blob: 06292eab82a34eb738060c1e52ff4f6189a5ac5a [file]
/*
* Copyright 2026 The Pigweed Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/* ========== THEME & FONT VARIABLES ========== */
:root {
/* Pigweed typography variables */
--pw-font-body: 'Noto Sans', sans-serif;
--pw-font-code: 'Roboto Mono', monospace;
--pw-font-headings: 'Lato', sans-serif;
/* Header and breadcrumbs layout variables */
--pw-header-height: 56px;
--pw-breadcrumbs-height: 30px;
--pw-header-padding-x: 24px;
}
@media (max-width: 839px) {
:root {
--pw-header-height: 52px;
--pw-breadcrumbs-height: 28px;
--pw-header-padding-x: 1rem;
}
}
body {
margin: 0;
padding-top: var(--pw-header-height) !important;
box-sizing: border-box;
min-height: 100vh;
}
/* Universal Skip Link for keyboard and screen reader accessibility */
.pw-skip-link {
position: fixed;
top: -100px;
left: var(--pw-header-padding-x);
z-index: 10001;
display: inline-flex;
align-items: center;
justify-content: center;
height: 36px;
padding: 0 16px;
box-sizing: border-box;
background-color: var(--pw-color-background-primary);
color: var(--pw-color-foreground-primary) !important;
border: 1px solid var(--pf-border);
border-radius: 6px;
font-family: var(--pw-font-body);
font-size: 14px;
font-weight: 500;
text-decoration: none !important;
box-shadow: var(--pf-shadow-md);
transition:
top 0.15s ease-in-out,
background-color 0.15s ease,
border-color 0.15s ease,
color 0.15s ease;
}
.pw-skip-link:hover {
background-color: var(--pf-hover);
color: var(--pw-color-link) !important;
border-color: var(--pf-border-focus);
}
.pw-skip-link:focus,
.pw-skip-link:focus-visible {
top: calc((var(--pw-header-height) - 36px) / 2);
outline: 2px solid var(--pf-outline-focus);
outline-offset: 2px;
border-color: var(--pf-border-focus);
}
/* ========== TOP HEADER BAR LAYOUT ========== */
#pw-header {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: var(--pw-header-height);
box-sizing: border-box;
z-index: 1000;
display: flex;
align-items: center;
/* Use flex-start instead of space-between so that on mobile #pw-header-menu
* and #pw-header-brand remain grouped on the left, while #pw-header-tools is
* pushed to the far right via margin-left: auto. */
justify-content: flex-start;
background-color: var(--pw-color-background-secondary);
color: var(--pw-color-foreground-primary);
padding: 0 var(--pw-header-padding-x);
border-bottom: 1px solid var(--pf-border);
font-family: var(--pw-font-body);
}
/* Brand container: menu toggle button, logo, and site title. */
#pw-header-menu {
display: flex !important;
align-items: center;
justify-content: center;
background: transparent;
border: none;
color: var(--pw-color-foreground-primary);
cursor: pointer;
padding: 4px;
margin: 0 12px 0 0;
border-radius: 4px;
line-height: 1;
&:hover {
background-color: var(--pf-hover);
}
&:focus-visible {
outline: 2px solid var(--pf-outline-focus);
}
.material-symbols-outlined {
font-size: 24px;
line-height: 1;
display: block;
user-select: none;
}
}
@media (min-width: 840px) {
#pw-header-menu {
display: none !important;
}
}
#pw-header-brand {
height: 100%;
display: flex;
align-items: center;
gap: 8px;
flex-shrink: 0;
margin-right: 0;
@media (min-width: 840px) {
margin-right: 0;
}
a,
a:visited,
a:hover,
a:active {
color: var(--pw-color-foreground-primary);
font-family: var(--pw-font-headings);
font-weight: bold;
font-style: italic;
font-size: 22px;
margin: 0 !important;
padding: 0;
white-space: nowrap;
text-decoration: none;
}
img {
height: 30px;
width: auto;
}
@media (max-width: 839px) {
img {
height: 26px;
}
a,
a:visited,
a:hover,
a:active {
font-size: 20px;
}
}
}
/* Site navigation links and dropdown popovers. */
#pw-header-nav {
display: none !important;
}
@media (min-width: 840px) {
#pw-header-nav {
display: flex !important;
align-items: center;
height: 100%;
gap: 2px;
margin-left: auto !important;
margin-right: 12px;
overflow: visible;
}
}
.pw-nav-item {
position: relative;
height: 100%;
display: flex;
align-items: center;
flex-shrink: 0;
}
.pw-nav-link,
.pw-nav-link:visited {
display: inline-flex;
align-items: center;
gap: 2px;
height: 36px;
padding: 0 8px;
color: var(--pw-color-foreground-primary) !important;
text-decoration: none !important;
font-size: 13px;
font-weight: 500;
border-radius: 6px;
white-space: nowrap;
transition:
background-color 0.15s ease,
color 0.15s ease;
&:hover,
&:active {
background-color: var(--pf-hover);
color: var(--pw-color-link) !important;
text-decoration: none !important;
}
}
.pw-nav-item:hover > .pw-nav-link,
.pw-nav-item:focus-within > .pw-nav-link {
background-color: var(--pf-hover);
color: var(--pw-color-link) !important;
text-decoration: none !important;
}
.pw-dropdown-arrow {
display: inline-block;
font-size: 18px;
line-height: 1;
text-decoration: none !important;
user-select: none;
}
.pw-nav-item:hover .pw-dropdown-arrow,
.pw-nav-item:focus-within .pw-dropdown-arrow {
transform: rotate(180deg);
}
/* Dropdown popover container */
.pw-nav-popover {
display: none;
position: absolute;
top: 100%;
left: 0;
min-width: 200px;
max-width: 320px;
max-height: calc(100vh - 80px);
overflow-y: auto;
background-color: var(--pw-color-background-primary);
border: 1px solid var(--pf-border);
border-radius: 8px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
padding: 6px 0;
margin: 0;
z-index: 1001;
}
.pw-nav-item:hover > .pw-nav-popover,
.pw-nav-item:focus-within > .pw-nav-popover {
display: block !important;
}
.pw-nav-item.is-closed > .pw-nav-popover {
display: none !important;
}
.pw-nav-item.is-closed .pw-dropdown-arrow {
transform: none !important;
}
.pw-nav-item:nth-last-child(-n + 4) > .pw-nav-popover {
left: auto;
right: 0;
}
.pw-nav-dropdown-list {
list-style: none;
margin: 0;
padding: 0;
}
.pw-nav-dropdown-link,
.pw-nav-dropdown-link:visited {
display: block;
padding: 8px 16px;
color: var(--pw-color-foreground-primary) !important;
text-decoration: none;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transition:
background-color 0.15s ease,
color 0.15s ease;
&:hover,
&:focus,
&:active {
background-color: var(--pf-hover);
color: var(--pw-color-link) !important;
}
}
/* Search UI elements within the header bar (desktop trigger and mobile button).
* Styles for the Pagefind search modal and search results outside the header
* live in search.css. */
#pw-header-search {
display: none !important;
height: 100%;
}
#pw-search-mobile {
background-color: var(--pw-color-background-primary);
border: 1px solid var(--pf-border);
color: var(--pw-color-foreground-primary);
cursor: pointer;
padding: 0;
margin: 0;
display: flex !important;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
border-radius: 50%;
box-sizing: border-box;
transition:
background-color 0.15s ease,
border-color 0.15s ease;
&:hover {
background-color: var(--pf-hover);
}
&:focus-visible {
outline: 2px solid var(--pf-outline-focus);
}
.material-symbols-outlined {
font-size: 20px;
line-height: 1;
display: block;
user-select: none;
}
}
pagefind-modal-trigger {
all: unset !important;
display: inline-flex !important;
align-items: center !important;
contain: none !important;
flex-shrink: 0 !important;
}
pagefind-modal-trigger .pf-trigger-btn {
display: inline-flex !important;
align-items: center !important;
height: 36px !important;
background: var(--pf-background) !important;
border: 1px solid var(--pf-border) !important;
border-radius: var(--pf-border-radius) !important;
color: var(--pw-color-foreground-primary) !important;
cursor: pointer !important;
box-sizing: border-box !important;
transition:
background-color 0.15s ease,
border-color 0.15s ease;
&:hover {
background-color: var(--pf-hover) !important;
border-color: var(--pf-border-focus) !important;
}
&:focus-visible {
outline: 2px solid var(--pf-outline-focus) !important;
}
}
pagefind-modal-trigger .pf-trigger-icon {
width: 16px !important;
height: 16px !important;
display: inline-block !important;
background-color: var(--pw-color-foreground-primary) !important;
-webkit-mask-image: var(--pf-icon-search) !important;
mask-image: var(--pf-icon-search) !important;
-webkit-mask-size: 100% 100% !important;
mask-size: 100% 100% !important;
-webkit-mask-repeat: no-repeat !important;
mask-repeat: no-repeat !important;
-webkit-mask-position: center !important;
mask-position: center !important;
flex-shrink: 0 !important;
}
/* Wide viewports (1120px and higher):
* Display full desktop search bar in header flow and hide condensed button.
* Between 840px and 1120px, the navigation links stay visible while search
* switches to the condensed button in #pw-header-tools to prevent overflow. */
@media (min-width: 1120px) {
#pw-header-search {
display: flex !important;
align-items: center;
flex-shrink: 0;
margin-left: 0;
margin-right: 8px;
}
pagefind-modal-trigger {
width: 260px !important;
}
pagefind-modal-trigger .pf-trigger-btn {
width: 100% !important;
padding: 0 14px !important;
gap: 8px !important;
}
#pw-search-mobile {
display: none !important;
}
}
/* Tools container: action buttons such as search and the theme selector.
* On mobile (<840px), margin-left: auto pushes tools to the far right edge,
* ensuring the largest gap is in the middle between the brand and tools.
* On desktop (>=840px), nav already has margin-left: auto, so tools margin-left is 0. */
#pw-header-tools {
height: 100%;
display: flex;
align-items: center;
gap: 8px;
flex-shrink: 0;
margin-left: auto;
@media (min-width: 840px) {
margin-left: 0;
}
}
/* Theme switcher component within the header bar. Root-level theme CSS
* variables that transcend the header live in theme.css. */
pw-theme {
display: inline-flex !important;
align-items: center !important;
flex-shrink: 0 !important;
background-color: var(--pw-color-background-primary);
border: 1px solid var(--pf-border);
border-radius: 20px;
padding: 2px;
gap: 2px;
box-sizing: border-box;
}
.pw-theme-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
border: none;
background: transparent;
color: var(--pf-text-muted);
border-radius: 50%;
cursor: pointer;
transition:
background-color 0.15s ease,
color 0.15s ease;
line-height: 1;
.material-symbols-outlined {
font-size: 20px;
display: block;
line-height: 1;
user-select: none;
}
&:hover {
color: var(--pw-color-foreground-primary);
background-color: var(--pf-hover);
}
&:focus-visible {
outline: 2px solid var(--pf-outline-focus);
}
&.active {
background-color: var(--pw-color-background-code);
color: var(--pw-color-link);
}
}
/* ========== NATIVE HEADER REPLACEMENTS ========== */
/* Hide native headers from Sphinx and Doxygen that are superseded by the
* universal header bar. */
#pst-header,
#navrow1 {
display: none !important;
}
/* Suppress native Sphinx and Rustdoc skip links in favor of the universal
* pw-skip-link component. */
#pst-skip-link,
.skip-main-content {
display: none !important;
}
/* Hide the 'ayu' theme option in Rustdoc settings. */
label[for='theme-ayu'] {
display: none !important;
}
/* Prevent #main-content from inheriting Rustdoc's yellow :target highlight
* when targeted by the skip link. */
#main-content:target {
background-color: transparent !important;
border-right: none !important;
}