Files
blowfish/assets/css/main.css
T
Nuno CoraçãoandClaude Fable 5 ca56ac78a3 🐛 Let the fullscreen mobile menu escape the floating header
The floating header's backdrop blur makes the pill a containing block
for fixed-position descendants, so the fullscreen mobile menu rendered
at the pill's height instead of filling the viewport. Lift the filter
while the menu is open. Fixes #3057.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 23:51:04 +01:00

514 lines
9.7 KiB
CSS

/*! Blowfish | MIT License | https://github.com/nunocoracao/blowfish */
@config "../../tailwind.config.js";
@import "tailwindcss";
@import "./components/chroma.css" layer(utilities);
@import "./components/tabs.css" layer(utilities);
@import "./components/zen-mode.css";
@import "./components/gist.css";
@import "./components/a11y.css";
@import "./components/admonition.css" layer(components);
html:not(.dark) {
color-scheme: light;
}
html.dark {
color-scheme: dark;
}
body a,
body button {
@apply transition-colors;
}
/* Staggered entrance for the landing homepage hero. Removed entirely when a
visitor requests reduced motion. */
@keyframes landing-rise {
from {
opacity: 0;
transform: translateY(0.9rem);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.landing-rise {
animation: landing-rise 0.65s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.landing-rise-1 {
animation-delay: 90ms;
}
.landing-rise-2 {
animation-delay: 180ms;
}
.landing-rise-3 {
animation-delay: 270ms;
}
.landing-rise-4 {
animation-delay: 360ms;
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto !important;
}
.landing-rise,
.landing-rise-1,
.landing-rise-2,
.landing-rise-3,
.landing-rise-4 {
animation: none;
}
}
button,
[role="button"] {
cursor: pointer;
}
/* Scale SVG icons to text size */
.icon svg {
@apply h-[1em] w-[1em];
}
/* Scale SVG logos to appropriate size */
.logo svg {
@apply h-[5rem] w-[5rem];
}
/* Search */
#search-query::-webkit-search-cancel-button,
#search-query::-webkit-search-decoration,
#search-query::-webkit-search-results-button,
#search-query::-webkit-search-results-decoration {
@apply hidden;
}
/* RTL support */
.prose blockquote {
@apply rtl:pr-4 rtl:border-l-0 rtl:border-r-4;
}
.prose ul > li,
.prose ol > li {
@apply rtl:pl-0 rtl:pr-2 rtl:mr-7;
}
.prose ol > li:before,
.prose ul > li:before {
@apply rtl:left-auto rtl:right-1;
}
.prose thead td:first-child,
.prose thead th:first-child {
@apply rtl:pr-0;
}
.prose thead td:last-child,
.prose thead th:last-child {
@apply rtl:pl-0;
}
/* Adjust first child within prose */
.prose div.min-w-0.max-w-prose > *:first-child {
@apply mt-3;
}
/* Table of Contents */
#TOCView {
max-height: calc(100vh - 150px);
min-height: 0;
overflow-x: hidden;
}
.toc ul,
.toc li {
@apply px-0 leading-snug list-none;
}
.toc ul ul {
@apply ltr:pl-4 rtl:pr-4;
}
.toc a {
@apply font-normal text-neutral-700 dark:text-neutral-300;
}
.toc ul > li {
@apply rtl:mr-0;
}
/* Code Copy */
.highlight {
@apply relative z-0;
}
.highlight-wrapper:hover > .copy-button {
@apply visible;
}
.copy-button {
@apply absolute top-0 right-0 z-10 invisible w-20 py-1 font-mono text-sm cursor-pointer
opacity-90 bg-neutral-200 whitespace-nowrap rounded-bl-md rounded-tr-md text-neutral-700
dark:bg-neutral-600 dark:text-neutral-200 overflow-hidden truncate;
}
.copy-button:hover,
.copy-button:focus,
.copy-button:active,
.copy-button:active:hover {
@apply bg-primary-100 dark:bg-primary-600;
}
.copy-textarea {
@apply absolute opacity-5 -z-10;
}
/* Fix long KaTeX equations on mobile (see https://katex.org/docs/issues.html#css-customization) */
.katex-display {
overflow: auto hidden;
}
/* Fix katex overflow https://github.com/nunocoracao/blowfish/issues/2138 */
.katex-display {
padding: 1em;
width: calc(100% - 1em);
}
/* Fix long tables breaking out of article on mobile */
table {
display: block;
overflow: auto;
}
/* Fix long inline code sections breaking out of article on mobile */
code {
word-wrap: break-word; /* All browsers since IE 5.5+ */
overflow-wrap: break-word; /* Renamed property in CSS3 draft spec */
}
/* Fix long URLs breaking out of article bounds on mobile */
a {
word-break: break-word;
word-wrap: break-word;
overflow-wrap: break-word;
}
.prose-invert .highlight pre > code {
background-color: unset;
}
/* Custom */
pre {
text-align: left;
}
.single_hero_round {
max-height: 50vh;
object-fit: cover;
}
.single_hero_background {
width: calc(100% + 1px); /* patch for very small gap at right edge on mobile devices */
z-index: -10;
}
.hero_gradient {
width: 100%;
height: 100%;
}
/* ---- Print ---- */
@page {
margin: 2cm;
}
@media print {
html {
color-scheme: light only;
}
body {
background: #fff !important;
color: #111 !important;
max-width: none !important;
padding: 0 !important;
}
/* Site chrome that makes no sense on paper */
body > header,
#background-canvas,
.single_hero_background,
#scroll-to-top,
#bmc-wbtn {
display: none !important;
}
/* Flatten decoration; dark mode prints light */
* {
box-shadow: none !important;
text-shadow: none !important;
}
main,
article,
.prose,
.prose *:not(pre):not(pre *) {
color: #111 !important;
background: transparent !important;
}
pre,
pre * {
background: #f4f4f5 !important;
color: #111 !important;
white-space: pre-wrap !important;
}
/* Links stay useful on paper */
a {
text-decoration: underline;
}
.prose a[href^="http"]::after {
content: " (" attr(href) ")";
font-size: 0.85em;
color: #555;
word-break: break-all;
}
/* Sensible page flow */
pre,
blockquote,
table,
figure,
img {
break-inside: avoid;
}
h1,
h2,
h3,
h4 {
break-after: avoid;
}
img {
max-width: 100% !important;
}
}
/* Background hero: feature image dissolves into the global background */
.hero-canvas-fade {
-webkit-mask-image: linear-gradient(to bottom, black 20%, transparent 92%);
mask-image: linear-gradient(to bottom, black 20%, transparent 92%);
}
/* Shortcode grids: a lone trailing card stretches across the full row */
@media (min-width: 640px) and (max-width: 1023.98px) {
.grid-balance > :last-child:nth-child(odd) {
grid-column: 1 / -1;
}
}
@media (min-width: 1024px) {
.grid-balance-3 > :last-child:nth-child(3n + 1) {
grid-column: 1 / -1;
}
.grid-balance-4 > :last-child:nth-child(4n + 1) {
grid-column: 1 / -1;
}
}
.thumbnail_card {
aspect-ratio: var(--thumbnail-aspect-ratio, 1.5);
height: auto;
}
.thumbnail_card_related {
aspect-ratio: var(--thumbnail-aspect-ratio, 1.5);
height: auto;
}
.thumbnail {
width: 300px;
min-height: 180px;
}
@variant max-md {
.thumbnail {
width: 100%;
}
}
.thumbnail-shadow {
box-shadow: 5px 5px 20px 1px rgba(0, 0, 0, 0.3);
}
/* placeholder for gallery/carousel */
@variant max-md {
.width-patch {
width: 80vw;
}
}
@variant min-md {
.width-patch {
width: 65ch;
}
}
.anchor {
display: block;
position: relative;
top: -150px;
height: 0px;
visibility: hidden;
}
/* Offset scroll position to avoid header overlap */
[id^="fn"],
[id^="fnref"] {
scroll-margin-top: 145px;
}
/* patch for skip to main content */
#main-content {
scroll-margin-top: -125px;
}
@variant sm {
.article {
flex-wrap: wrap;
}
}
@variant md {
.article {
flex-wrap: nowrap;
}
}
.medium-zoom-image--opened {
z-index: 100;
}
@layer utilities {
.bf-border-color {
@apply border-neutral-300 dark:border-neutral-700;
}
.bf-border-color-hover {
@apply hover:border-primary-600 dark:hover:border-primary-400;
}
.bf-icon-color-hover {
@apply hover:text-primary-600 dark:hover:text-primary-400;
}
.bf-scrollbar {
&::-webkit-scrollbar-track {
background-color: var(--scrollbar-track);
border-radius: var(--scrollbar-track-radius);
}
&::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb);
border-radius: var(--scrollbar-thumb-radius);
}
&::-webkit-scrollbar-corner {
background-color: var(--scrollbar-corner);
border-radius: var(--scrollbar-corner-radius);
}
@supports (-moz-appearance:none) {
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-thumb, initial) var(--scrollbar-track, initial);
}
&::-webkit-scrollbar {
display: block;
width: 8px;
height: 8px;
}
--scrollbar-thumb: oklch(70.8% 0 0);
--scrollbar-track: oklch(92.2% 0 0);
&:is(.dark *) {
--scrollbar-thumb: oklch(43.9% 0 0);
}
&:is(.dark *) {
--scrollbar-track: oklch(26.9% 0 0);
}
}
}
@layer base {
* {
@supports (-moz-appearance:none) {
scrollbar-color: initial;
scrollbar-width: initial;
}
}
}
/* Prevent body scroll when mobile menu is open */
body:has(#mobile-menu-toggle:checked) {
overflow: hidden;
}
/* Reset body position for desktop after it was modified on mobile */
@media (min-width: 853px) {
body:has(#mobile-menu-toggle:checked) {
overflow: visible;
}
}
/* Hide buy me a coffee in mobile menu */
#bmc-wbtn {
z-index: 50 !important;
}
.nested-menu {
position: relative;
}
.menuhide {
position: absolute;
z-index: 1000;
width: max-content;
max-width: min(20rem, calc(100vw - 2rem));
opacity: 0;
visibility: hidden;
transition:
visibility 0.3s,
opacity 0.3s ease-in-out;
}
/* A backdrop-filter turns the header pill into a containing block for
position:fixed descendants, which would trap the fullscreen mobile menu
inside it. Lift the filter while that menu is open — the fullscreen
overlay covers the header anyway, so the change is invisible. */
header > div:has(.mobile-menu-fullscreen #mobile-menu-toggle:checked) {
-webkit-backdrop-filter: none;
backdrop-filter: none;
}
/* Dropdowns near the end of the bar open leftward so they stay on screen */
.nested-menu:nth-last-child(-n + 3) .menuhide,
.mobile-header-row .menuhide {
inset-inline-end: 0;
}
.nested-menu:hover .menuhide,
.nested-menu:focus-within .menuhide {
opacity: 1;
visibility: visible;
}
.active {
text-decoration-line: underline;
text-decoration-thickness: 3px;
text-underline-offset: 4px;
}