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
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
- name: Linter
if: ${{ github.event_name == 'pull_request' }}
env:
PRE_COMMIT_SKIP: mkdocs-build,linkcheckmd
PRE_COMMIT_SKIP: mkdocs-build
run: |
pre-commit install
pre-commit run --all-files --verbose
Expand Down
168 changes: 167 additions & 1 deletion theme/css/content.css
Original file line number Diff line number Diff line change
Expand Up @@ -1020,10 +1020,15 @@ html[data-mode="dim"] .osl-page-hero{
border-radius: 0;
}

.osl-side-nav__group a{
margin-left: .35rem;
padding-left: 1rem;
}

.osl-side-nav a:hover,
.osl-side-nav a.active{
background: transparent;
box-shadow: inset 3px 0 0 var(--osl-accent);
box-shadow: inset 0 -2px 0 var(--osl-accent);
}

.project-card,
Expand Down Expand Up @@ -1072,3 +1077,164 @@ html[data-mode="dim"] .osl-page-hero{
padding: 1.25rem 0;
}
}

/* Responsive section navigation
Desktop keeps the sticky left sidebar; mobile uses an inline disclosure menu
so long section menus do not consume half of the viewport. */
.osl-mobile-section-nav{
display: none;
}

.osl-mobile-section-nav summary{
list-style: none;
}

.osl-mobile-section-nav summary::-webkit-details-marker{
display: none;
}

@media (max-width: 900px){
.osl-page-layout{
grid-template-columns: 1fr;
gap: clamp(1rem, 4vw, 1.6rem);
}

.osl-hero-system,
.osl-side-nav{
display: none;
}

.osl-mobile-section-nav{
display: block;
overflow: hidden;
border: 1px solid var(--border-strong);
border-left: .35rem solid var(--osl-accent);
background: var(--surface-solid);
}

.osl-mobile-section-nav__summary{
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: .95rem 1rem;
color: var(--heading);
}

.osl-mobile-section-nav__summary:focus-visible,
.osl-mobile-section-nav__group-summary:focus-visible{
outline: 3px solid color-mix(in oklab, var(--osl-accent) 45%, transparent);
outline-offset: -3px;
}

.osl-mobile-section-nav__summary::after{
content: "";
flex: 0 0 auto;
width: .7rem;
height: .7rem;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
transform: translateY(-.15rem) rotate(45deg);
transition: transform .18s ease;
}

.osl-mobile-section-nav[open] > .osl-mobile-section-nav__summary::after{
transform: translateY(.15rem) rotate(225deg);
}

.osl-mobile-section-nav__summary-text{
display: grid;
gap: .18rem;
min-width: 0;
}

.osl-mobile-section-nav__eyebrow{
color: var(--osl-accent);
font-size: .76rem;
font-weight: 850;
letter-spacing: .1em;
line-height: 1.2;
text-transform: uppercase;
}

.osl-mobile-section-nav__current{
overflow: hidden;
color: color-mix(in oklab, var(--fg) 78%, var(--muted));
font-size: .94rem;
font-weight: 750;
line-height: 1.3;
text-overflow: ellipsis;
white-space: nowrap;
}

.osl-mobile-section-nav__panel{
display: grid;
gap: .15rem;
padding: .35rem .75rem .85rem;
border-top: 1px solid var(--border);
}

.osl-mobile-section-nav__group{
border-top: 1px solid var(--border);
}

.osl-mobile-section-nav__group:first-child{
border-top: 0;
}

.osl-mobile-section-nav__group-summary{
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
gap: .85rem;
padding: .82rem .25rem;
color: var(--heading);
font-size: .95rem;
font-weight: 850;
}

.osl-mobile-section-nav__group-summary::after{
content: "";
flex: 0 0 auto;
width: .55rem;
height: .55rem;
border-right: 2px solid currentColor;
border-bottom: 2px solid currentColor;
opacity: .7;
transform: translateY(-.12rem) rotate(45deg);
transition: transform .18s ease;
}

.osl-mobile-section-nav__group[open] > .osl-mobile-section-nav__group-summary{
color: var(--osl-accent);
}

.osl-mobile-section-nav__group[open] > .osl-mobile-section-nav__group-summary::after{
transform: translateY(.12rem) rotate(225deg);
}

.osl-mobile-section-nav__group-links{
display: grid;
gap: .12rem;
padding: 0 0 .7rem .8rem;
}

.osl-mobile-section-nav a{
display: block;
padding: .62rem .75rem;
color: color-mix(in oklab, var(--fg) 82%, var(--muted));
font-size: .93rem;
font-weight: 720;
line-height: 1.3;
text-decoration: none;
}

.osl-mobile-section-nav a:hover,
.osl-mobile-section-nav a.active{
background: color-mix(in oklab, var(--osl-accent) 10%, transparent);
box-shadow: inset 0 -2px 0 var(--osl-accent);
color: var(--osl-accent);
}
}
114 changes: 85 additions & 29 deletions theme/single-sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,80 @@
{% endif %}
{% endfor %}

{% macro render_desktop_side_nav(items, current_url) %}
<nav>
{% set rendered = namespace(urls=[]) %}
{% for item in items %}
{% if item.children %}
<div class="osl-side-nav__group">
<span class="osl-side-nav__group-title">{{ item.title }}</span>
{% for child in item.children %}
{% if child.url not in rendered.urls %}
{% set _ = rendered.urls.append(child.url) %}
<a href="{{ child.url|url }}"
class="{% if child.active or child.url == current_url %}active{% endif %}"
{% if child.active or child.url == current_url %}aria-current="page"{% endif %}>
{{ child.title }}
</a>
{% endif %}
{% endfor %}
</div>
{% else %}
{% if item.url not in rendered.urls %}
{% set _ = rendered.urls.append(item.url) %}
<a href="{{ item.url|url }}"
class="{% if item.active or item.url == current_url %}active{% endif %}"
{% if item.active or item.url == current_url %}aria-current="page"{% endif %}>
{{ item.title }}
</a>
{% endif %}
{% endif %}
{% endfor %}
</nav>
{% endmacro %}

{% macro render_mobile_side_nav(items, current_url, label) %}
<nav class="osl-mobile-section-nav__panel" aria-label="{{ label }} mobile navigation">
{% set rendered = namespace(urls=[]) %}
{% for item in items %}
{% if item.children %}
{% set group = namespace(active=item.active) %}
{% for child in item.children %}
{% if child.active or child.url == current_url %}
{% set group.active = true %}
{% endif %}
{% endfor %}
<details class="osl-mobile-section-nav__group" {% if group.active %}open{% endif %}>
<summary class="osl-mobile-section-nav__group-summary">
{{ item.title }}
</summary>
<div class="osl-mobile-section-nav__group-links">
{% for child in item.children %}
{% if child.url not in rendered.urls %}
{% set _ = rendered.urls.append(child.url) %}
<a href="{{ child.url|url }}"
class="{% if child.active or child.url == current_url %}active{% endif %}"
{% if child.active or child.url == current_url %}aria-current="page"{% endif %}>
{{ child.title }}
</a>
{% endif %}
{% endfor %}
</div>
</details>
{% else %}
{% if item.url not in rendered.urls %}
{% set _ = rendered.urls.append(item.url) %}
<a href="{{ item.url|url }}"
class="osl-mobile-section-nav__link{% if item.active or item.url == current_url %} active{% endif %}"
{% if item.active or item.url == current_url %}aria-current="page"{% endif %}>
{{ item.title }}
</a>
{% endif %}
{% endif %}
{% endfor %}
</nav>
{% endmacro %}

<section class="osl-page osl-page--sidebar osl-page--section-{{ section_slug }} osl-page--theme-{{ page_theme }}">
<div class="osl-page-shell">
<header class="osl-page-hero">
Expand All @@ -40,37 +114,19 @@ <h1>{{ page_title or config.site_name }}</h1>

<div class="osl-page-layout">
{% if sidebar.items %}
<details class="osl-mobile-section-nav">
<summary class="osl-mobile-section-nav__summary">
<span class="osl-mobile-section-nav__summary-text">
<span class="osl-mobile-section-nav__eyebrow">{{ sidebar.title }} menu</span>
<span class="osl-mobile-section-nav__current">Current: {{ page_title }}</span>
</span>
</summary>
{{ render_mobile_side_nav(sidebar.items, page.url, sidebar.title) }}
</details>

<aside class="osl-side-nav" aria-label="{{ sidebar.title }} navigation">
<p class="osl-side-nav__title">{{ sidebar.title }}</p>
<nav>
{% set rendered = namespace(urls=[]) %}
{% for item in sidebar.items %}
{% if item.children %}
<div class="osl-side-nav__group">
<span class="osl-side-nav__group-title">{{ item.title }}</span>
{% for child in item.children %}
{% if child.url not in rendered.urls %}
{% set _ = rendered.urls.append(child.url) %}
<a href="{{ child.url|url }}"
class="{% if child.active or child.url == page.url %}active{% endif %}"
{% if child.active or child.url == page.url %}aria-current="page"{% endif %}>
{{ child.title }}
</a>
{% endif %}
{% endfor %}
</div>
{% else %}
{% if item.url not in rendered.urls %}
{% set _ = rendered.urls.append(item.url) %}
<a href="{{ item.url|url }}"
class="{% if item.active or item.url == page.url %}active{% endif %}"
{% if item.active or item.url == page.url %}aria-current="page"{% endif %}>
{{ item.title }}
</a>
{% endif %}
{% endif %}
{% endfor %}
</nav>
{{ render_desktop_side_nav(sidebar.items, page.url) }}
</aside>
{% endif %}

Expand Down
Loading