You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1277 lines
31 KiB
1277 lines
31 KiB
/** |
|
* Layout styles |
|
* This file contains the layout styles for the application |
|
* Layout has 5 main parts: |
|
* - Header (header) |
|
* - Left menu (nav) |
|
* - Main content (main) |
|
* - Right sidebar (aside) |
|
* - Footer (footer) |
|
**/ |
|
|
|
|
|
|
|
|
|
/* Layout Container */ |
|
.layout { |
|
max-width: 100%; |
|
width: 1200px; |
|
min-width: 0; /* flex child of body: allow shrink so children don’t force page width */ |
|
margin: 0 auto; |
|
display: flex; |
|
flex-grow: 1; |
|
} |
|
|
|
/* Only the app chrome sidebar — not <nav> in main (pagination) or footer. */ |
|
.layout > nav { |
|
width: 21vw; |
|
min-width: 150px; |
|
max-width: 280px; |
|
flex-shrink: 0; |
|
padding: 1em; |
|
overflow-y: auto; /* Ensure the menu is scrollable if content is too long */ |
|
} |
|
|
|
.layout > nav ul { |
|
list-style-type: none; |
|
padding: 0; |
|
} |
|
|
|
.layout > nav li { |
|
margin: 0.5em 0; |
|
} |
|
|
|
.layout > nav a { |
|
color: var(--color-primary); |
|
text-decoration: none; |
|
} |
|
|
|
.layout > nav a:hover { |
|
color: var(--color-text-mid); |
|
text-decoration: none; |
|
} |
|
|
|
/* Left nav: featured authors (desktop only; same site logo as header when no Nostr picture) */ |
|
.sidebar-featured-authors { |
|
display: none; |
|
} |
|
|
|
/* Top topics list (same visibility pattern as featured authors) */ |
|
.sidebar-top-topics { |
|
display: none; |
|
} |
|
|
|
@media (min-width: 1025px) { |
|
.sidebar-featured-authors { |
|
display: block; |
|
margin-top: 1.1rem; |
|
padding-top: 0.9rem; |
|
border-top: 1px solid var(--color-border); |
|
} |
|
|
|
.layout > nav .sidebar-featured-authors a, |
|
.layout > nav .sidebar-featured-authors a:hover { |
|
color: inherit; |
|
text-decoration: none; |
|
} |
|
|
|
.sidebar-featured-authors__title { |
|
margin: 0 0 0.55rem; |
|
font-family: var(--font-family), sans-serif; |
|
font-size: 0.68rem; |
|
font-weight: 600; |
|
letter-spacing: 0.07em; |
|
text-transform: uppercase; |
|
color: color-mix(in srgb, var(--color-text-mid) 72%, var(--color-bg) 28%); |
|
line-height: 1.3; |
|
} |
|
|
|
.sidebar-featured-authors__grid { |
|
display: flex; |
|
flex-wrap: wrap; |
|
gap: 0.5rem 0.45rem; |
|
align-content: flex-start; |
|
list-style: none; |
|
margin: 0; |
|
padding: 0; |
|
} |
|
|
|
.layout > nav .sidebar-featured-authors__item, |
|
.sidebar-featured-authors__item { |
|
margin: 0; |
|
padding: 0; |
|
list-style: none; |
|
} |
|
|
|
.sidebar-featured-authors__link { |
|
display: block; |
|
border-radius: 50%; |
|
line-height: 0; |
|
} |
|
|
|
.sidebar-featured-authors__link:hover { |
|
text-decoration: none; |
|
} |
|
|
|
.sidebar-featured-authors__link:hover .sidebar-featured-authors__avatar { |
|
box-shadow: 0 0 0 2px var(--color-secondary); |
|
} |
|
|
|
.sidebar-featured-authors__link:focus-visible .sidebar-featured-authors__avatar, |
|
.sidebar-featured-authors__link:focus-visible { |
|
outline: 2px solid var(--color-focus-ring); |
|
outline-offset: 2px; |
|
} |
|
|
|
.sidebar-featured-authors__avatar { |
|
display: block; |
|
width: 40px; |
|
height: 40px; |
|
border-radius: 50%; |
|
overflow: hidden; |
|
background: var(--color-bg-light); |
|
box-shadow: 0 0 0 1px var(--color-border); |
|
} |
|
|
|
.sidebar-featured-authors__avatar img { |
|
display: block; |
|
width: 100%; |
|
height: 100%; |
|
object-fit: cover; |
|
} |
|
|
|
.sidebar-featured-authors__avatar img[src*="favicon-96x96"] { |
|
object-fit: contain; |
|
object-position: center; |
|
padding: 0.2rem; |
|
box-sizing: border-box; |
|
} |
|
|
|
.sidebar-top-topics { |
|
display: block; |
|
margin-top: 1.1rem; |
|
padding-top: 0.9rem; |
|
border-top: 1px solid var(--color-border); |
|
} |
|
|
|
.sidebar-top-topics__title { |
|
margin: 0 0 0.5rem; |
|
font-family: var(--font-family), sans-serif; |
|
font-size: 0.68rem; |
|
font-weight: 600; |
|
letter-spacing: 0.07em; |
|
text-transform: uppercase; |
|
color: color-mix(in srgb, var(--color-text-mid) 72%, var(--color-bg) 28%); |
|
line-height: 1.3; |
|
} |
|
|
|
.sidebar-top-topics__list { |
|
list-style: none; |
|
margin: 0; |
|
padding: 0; |
|
display: flex; |
|
flex-wrap: wrap; |
|
gap: 0.4rem 0.35rem; |
|
align-items: center; |
|
} |
|
|
|
.layout > nav .sidebar-top-topics__list li { |
|
margin: 0; |
|
} |
|
|
|
/* Pill badges: borderless, low-contrast chips (softer than article `a.tag`) */ |
|
.layout > nav a.topic-badge.sidebar-top-topics__link, |
|
.layout > nav a.topic-badge { |
|
display: inline-block; |
|
max-width: 100%; |
|
background-color: color-mix(in srgb, var(--color-text-mid) 7%, var(--color-bg)); |
|
color: color-mix(in srgb, var(--color-text-mid) 78%, var(--color-bg) 22%); |
|
padding: 0.2rem 0.5rem; |
|
border-radius: 999px; |
|
font-size: 0.7rem; |
|
line-height: 1.35; |
|
font-weight: 400; |
|
text-decoration: none; |
|
border: none; |
|
box-sizing: border-box; |
|
word-break: break-word; |
|
transition: background-color 0.2s ease, color 0.2s ease; |
|
} |
|
|
|
.layout > nav a.topic-badge:hover, |
|
.layout > nav a.topic-badge:focus-visible { |
|
background-color: color-mix(in srgb, var(--color-text-mid) 12%, var(--color-bg)); |
|
color: color-mix(in srgb, var(--color-primary) 42%, var(--color-text-mid)); |
|
text-decoration: none; |
|
} |
|
} |
|
|
|
/* Only the app chrome in Header.html.twig (#site-header). A bare `header` rule also |
|
matched <header class="featured-authors__intro"> and fixed it under the real bar, hiding it. */ |
|
#site-header { |
|
position: fixed; |
|
/* Use inset instead of 100vw: 100vw includes the vertical scrollbar and causes horizontal overflow on many viewports. */ |
|
left: 0; |
|
right: 0; |
|
top: 0; |
|
width: auto; |
|
box-sizing: border-box; |
|
} |
|
|
|
/* Desktop: breathing room under the browser chrome. Mobile gets inset via |
|
.header__logo padding in the max-width block below. */ |
|
@media (min-width: 1025px) { |
|
#site-header { |
|
padding-top: max(0.65rem, env(safe-area-inset-top, 0px)); |
|
} |
|
} |
|
|
|
/* Hamburger button */ |
|
.hamburger { |
|
cursor: pointer; |
|
display: none; /* Hidden on desktop */ |
|
font-size: 26px; |
|
} |
|
|
|
/* Trailing tools: Nostr ⋯ menu + hamburger (mobile) */ |
|
.header__end { |
|
display: flex; |
|
flex-shrink: 0; |
|
align-items: center; |
|
gap: 0.4rem; |
|
} |
|
|
|
/* NIP-19 share menu (header) */ |
|
.nostr-share-menu { |
|
position: relative; |
|
list-style: none; |
|
} |
|
|
|
.nostr-share-menu__trigger { |
|
display: inline-flex; |
|
align-items: center; |
|
gap: 0.2rem; |
|
min-width: 2.25rem; |
|
font-size: 0.9rem; |
|
line-height: 1.2; |
|
padding: 0.2rem 0.45rem; |
|
list-style: none; |
|
} |
|
|
|
.nostr-share-menu__label { |
|
font-size: 0.85rem; |
|
font-weight: 600; |
|
white-space: nowrap; |
|
} |
|
|
|
.nostr-share-menu__glyph { |
|
font-size: 1.1rem; |
|
line-height: 1; |
|
opacity: 0.9; |
|
} |
|
|
|
.nostr-share-menu__trigger::-webkit-details-marker { |
|
display: none; |
|
} |
|
|
|
.nostr-share-menu__list { |
|
position: absolute; |
|
z-index: 1002; |
|
right: 0; |
|
top: calc(100% + 4px); |
|
margin: 0; |
|
padding: 0.35rem 0; |
|
min-width: 12rem; |
|
list-style: none; |
|
background: var(--color-bg); |
|
border: 1px solid var(--color-border); |
|
border-radius: 4px; |
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); |
|
} |
|
|
|
.nostr-share-menu__item { |
|
margin: 0; |
|
padding: 0; |
|
} |
|
|
|
.nostr-share-menu__action { |
|
display: block; |
|
width: 100%; |
|
text-align: left; |
|
padding: 0.45rem 0.75rem; |
|
font-family: var(--font-family), sans-serif; |
|
font-size: 0.9rem; |
|
font-weight: 400; |
|
line-height: 1.3; |
|
text-transform: none; |
|
color: var(--color-text, inherit); |
|
text-decoration: none; |
|
background: none; |
|
border: none; |
|
cursor: pointer; |
|
border-radius: 0; |
|
} |
|
|
|
.nostr-share-menu__action:hover, |
|
.nostr-share-menu__action:focus-visible { |
|
background: color-mix(in srgb, var(--color-primary) 12%, transparent); |
|
} |
|
|
|
a.nostr-share-menu__action { |
|
color: var(--color-primary, inherit); |
|
} |
|
|
|
.nostr-share-menu--event .nostr-share-menu__trigger { |
|
min-width: auto; |
|
padding: 0.15rem 0.4rem; |
|
font-size: 1rem; |
|
} |
|
|
|
.header__logo { |
|
display: flex; |
|
width: 100%; |
|
justify-content: center; |
|
} |
|
|
|
#progress-bar { |
|
position: absolute; |
|
left: 0; |
|
bottom: 0; |
|
height: 4px; |
|
width: 0; |
|
transform-origin: left center; |
|
background: var(--color-primary); |
|
transition: width 0.4s ease; |
|
z-index: 1000; |
|
overflow: hidden; |
|
pointer-events: none; |
|
} |
|
|
|
/* |
|
* In-flight navigation: a full-width track with a short segment that sweeps left → right |
|
* (do not keyframe the track width: 20% / 55% / 28% read as a half-screen rubber band). |
|
*/ |
|
#progress-bar.pb-indeterminate { |
|
transition: none; |
|
/* Tinted track: solid fill comes from ::before while loading */ |
|
background: color-mix(in srgb, var(--color-primary) 20%, transparent); |
|
animation: none; |
|
} |
|
|
|
#progress-bar.pb-indeterminate::before { |
|
content: ""; |
|
position: absolute; |
|
top: 0; |
|
left: 0; |
|
width: 35%; |
|
height: 100%; |
|
background: var(--color-primary); |
|
border-radius: 0 2px 2px 0; |
|
animation: pb-sweep 1.15s cubic-bezier(0.4, 0, 0.2, 1) infinite; |
|
} |
|
|
|
@keyframes pb-sweep { |
|
0% { |
|
transform: translateX(-100%); |
|
} |
|
|
|
100% { |
|
/* Move one segment width past the right edge of the 100% track */ |
|
transform: translateX(calc(100% / 0.35 + 100%)); |
|
} |
|
} |
|
|
|
/* Mobile Styles */ |
|
@media (max-width: 1024px) { |
|
.header__logo { |
|
box-sizing: border-box; |
|
justify-content: space-between; |
|
align-items: center; |
|
gap: 0.5rem; |
|
/* Top: safe area (notch) + room so the site title isn’t flush under the browser chrome */ |
|
padding: max(0.5rem, env(safe-area-inset-top, 0px)) max(0.65rem, env(safe-area-inset-left)) 0.45rem max(0.65rem, env(safe-area-inset-right)); |
|
} |
|
|
|
.header__brand { |
|
flex: 1; |
|
min-width: 0; |
|
display: block; |
|
text-align: left; |
|
} |
|
|
|
.header__categories { |
|
display: none; |
|
flex-direction: column; |
|
padding-top: 10px; |
|
padding-bottom: max(1rem, env(safe-area-inset-bottom, 0px)); |
|
} |
|
|
|
.header__categories.active { |
|
display: flex; |
|
} |
|
|
|
.hamburger { |
|
display: block; |
|
align-self: center; |
|
} |
|
|
|
.header__categories ul { |
|
flex-direction: column; |
|
gap: 0.35rem; |
|
align-items: stretch; |
|
} |
|
|
|
.header__cat-link { |
|
width: 100%; |
|
min-height: 2.6rem; |
|
} |
|
|
|
/* Log in / account block below category links in the hamburger */ |
|
.header__mobile-account { |
|
align-self: stretch; |
|
text-align: left; |
|
width: 100%; |
|
max-width: 32rem; |
|
margin: 0 auto; |
|
padding: 0.75rem 0.25rem 0; |
|
border-top: 1px solid var(--color-border); |
|
} |
|
} |
|
|
|
/* Hide the duplicate hamburger user menu on wide screens (sidebar <nav> has the real menu). */ |
|
@media (min-width: 1025px) { |
|
.header__mobile-account { |
|
display: none; |
|
} |
|
|
|
/* Center the title; keep Nostr menu + hamburger on the right without shifting the brand. */ |
|
.header__logo { |
|
display: grid; |
|
grid-template-columns: 1fr auto 1fr; |
|
align-items: center; |
|
} |
|
|
|
.header__brand { |
|
grid-column: 2; |
|
justify-self: center; |
|
} |
|
|
|
.header__end { |
|
grid-column: 3; |
|
justify-self: end; |
|
} |
|
} |
|
|
|
/* Main content */ |
|
:root { |
|
/* Clears fixed #site-header; keep in sync with main margin-top per breakpoint below. */ |
|
--site-fixed-header-offset: 140px; |
|
} |
|
|
|
/* #:target / in-page links: scroll position leaves room under the fixed bar (scroll-margin on inline <mark> is unreliable alone). */ |
|
html { |
|
scroll-padding-top: calc(var(--site-fixed-header-offset) + 0.75rem); |
|
} |
|
|
|
main { |
|
margin-top: var(--site-fixed-header-offset); |
|
flex-grow: 1; |
|
min-width: 0; /* flex item: allow shrinking below wide images / intrinsic min-content */ |
|
padding: 1em; |
|
word-break: break-word; |
|
} |
|
|
|
.user-menu { |
|
position: fixed; |
|
top: 150px; |
|
width: calc(21vw - 10px); |
|
min-width: 150px; |
|
max-width: 270px; |
|
} |
|
|
|
@media (min-width: 1025px) { |
|
:root { |
|
--site-fixed-header-offset: 152px; |
|
} |
|
|
|
/* Match extra header padding-top so content and menu clear the fixed bar */ |
|
/* In-flow left column: <nav> clears the fixed #site-header. */ |
|
.layout > nav { |
|
margin-top: var(--site-fixed-header-offset); |
|
} |
|
|
|
/* Right column: same clearance as <main> so the highlights pane is not under #site-header. */ |
|
.layout > aside { |
|
margin-top: var(--site-fixed-header-offset); |
|
/* Default: do not stretch — avoids a full-height empty column on pages with blank <aside> (e.g. article). */ |
|
align-self: flex-start; |
|
} |
|
|
|
/* Home: stretch the aside to the same row height as <main> so the highlights column isn’t a short box; list flows with the page. */ |
|
.layout:has(.home-body--wall) > aside { |
|
align-self: stretch; |
|
} |
|
|
|
/* |
|
* Left column account block: keep it in document flow (not position:fixed) so order is |
|
* badge → logout / search → featured authors. Fixed positioning removed the menu from the flow |
|
* so the featured block sat under the header or overlapped. |
|
*/ |
|
.layout > nav .user-menu:not(.user-menu--inline) { |
|
position: static; |
|
width: 100%; |
|
min-width: 0; |
|
max-width: 100%; |
|
top: auto; |
|
left: auto; |
|
} |
|
|
|
.layout > nav .user-menu .notice { |
|
margin-top: 0; |
|
margin-bottom: 0.3rem; |
|
} |
|
|
|
/* Tight stack: badge, then logout, then search */ |
|
.layout > nav .user-menu .user-menu__account-nav { |
|
margin: 0.4rem 0 0.35rem; |
|
padding: 0; |
|
} |
|
|
|
.layout > nav .user-menu .user-menu__account-nav li { |
|
margin: 0.2rem 0 0; |
|
} |
|
|
|
.layout > nav .user-menu .user-menu__account-nav li:first-child { |
|
margin-top: 0; |
|
} |
|
|
|
/* More separation before the featured block (sibling in <nav>, after this menu). */ |
|
.layout > nav .sidebar-featured-authors { |
|
margin-top: 1.35rem; |
|
padding-top: 1.15rem; |
|
} |
|
} |
|
|
|
/* After .user-menu so this wins: hamburger copy stays in flow, not position:fixed. */ |
|
.user-menu.user-menu--inline { |
|
position: static; |
|
width: 100%; |
|
min-width: 0; |
|
max-width: none; |
|
top: auto; |
|
left: auto; |
|
} |
|
|
|
.user-nav { |
|
padding: 10px; |
|
margin: 10px 0; |
|
} |
|
|
|
/* Right sidebar */ |
|
aside { |
|
width: min(22vw, 260px); |
|
min-width: 170px; |
|
flex-shrink: 0; |
|
flex-grow: 0; |
|
padding: 1em; |
|
} |
|
|
|
/* Home: full list height — no max-height; window scroll. */ |
|
.home-aside-highlights { |
|
display: flex; |
|
flex-direction: column; |
|
gap: 0.5rem; |
|
min-width: 0; |
|
width: 100%; |
|
} |
|
|
|
/* Wrapper around the list (keeps end padding; no max-height so highlights aren’t trapped in a short box). */ |
|
.home-aside-highlights__scroller { |
|
overflow: visible; |
|
padding-right: max(0.6rem, calc(0.35rem + env(safe-area-inset-right, 0px))); |
|
box-sizing: border-box; |
|
} |
|
|
|
.home-aside-highlights__title { |
|
margin: 0 0 0.55rem; |
|
font-family: var(--font-family), sans-serif; |
|
font-size: 0.68rem; |
|
font-weight: 600; |
|
letter-spacing: 0.07em; |
|
text-transform: uppercase; |
|
color: color-mix(in srgb, var(--color-text-mid) 72%, var(--color-bg) 28%); |
|
line-height: 1.3; |
|
} |
|
|
|
.home-aside-highlights__list { |
|
list-style: none; |
|
margin: 0; |
|
padding: 0 0.2rem 0 0; /* keep inset from scrollbar */ |
|
display: flex; |
|
flex-direction: column; |
|
gap: 0.9rem; |
|
} |
|
|
|
/* Block body HTML (full quote + <mark> like the article) must not sit inside <a> — use overlay “hit” link. */ |
|
.home-aside-highlights__item-inner { |
|
position: relative; |
|
color: color-mix(in srgb, var(--color-text-mid) 90%, var(--color-primary) 10%); |
|
padding: 0.1rem 0 0.15rem 0.55rem; |
|
border: none; |
|
border-left: 1px solid color-mix(in srgb, var(--color-text-mid) 7%, var(--color-border) 93%); |
|
border-radius: 0; |
|
background: transparent; |
|
line-height: 1.45; |
|
font-size: 0.78rem; |
|
transition: color 0.18s ease, border-left-color 0.18s ease, background 0.18s ease; |
|
} |
|
|
|
.home-aside-highlights__item-inner:hover { |
|
color: var(--color-primary); |
|
border-left-color: color-mix(in srgb, var(--color-primary) 32%, var(--color-border) 68%); |
|
background: color-mix(in srgb, var(--color-primary) 4%, var(--color-bg) 96%); |
|
} |
|
|
|
.home-aside-highlights__item-inner:has(.home-aside-highlights__hit:focus-visible) { |
|
color: var(--color-primary); |
|
border-left-color: color-mix(in srgb, var(--color-primary) 38%, var(--color-border) 62%); |
|
background: color-mix(in srgb, var(--color-primary) 4%, var(--color-bg) 96%); |
|
outline: 2px solid var(--color-focus-ring, var(--color-primary)); |
|
outline-offset: 3px; |
|
} |
|
|
|
.home-aside-highlights__hit { |
|
position: absolute; |
|
inset: 0; |
|
z-index: 2; |
|
text-decoration: none; |
|
} |
|
|
|
/* Highlight author (small badge link) + date above quote; badge is clickable, rest of row opens article. */ |
|
.home-aside-highlights__byline { |
|
display: flex; |
|
flex-wrap: wrap; |
|
align-items: center; |
|
gap: 0.3rem 0.5rem; |
|
margin: 0 0 0.35rem; |
|
position: relative; |
|
z-index: 3; |
|
font-family: var(--font-family), system-ui, sans-serif; |
|
font-size: 0.68rem; |
|
line-height: 1.2; |
|
pointer-events: none; |
|
} |
|
|
|
.home-aside-highlights__who { |
|
display: inline-flex; |
|
max-width: 100%; |
|
pointer-events: auto; |
|
} |
|
|
|
.home-aside-highlights__byline .user-badge { |
|
gap: 0.28rem; |
|
} |
|
|
|
.home-aside-highlights__byline .user-badge__avatar { |
|
width: 1.125rem; |
|
height: 1.125rem; |
|
} |
|
|
|
.home-aside-highlights__byline .user-badge__name { |
|
font-size: 0.68rem; |
|
max-width: 7.5rem; |
|
overflow: hidden; |
|
text-overflow: ellipsis; |
|
white-space: nowrap; |
|
} |
|
|
|
.home-aside-highlights__time { |
|
font-size: 0.65rem; |
|
color: color-mix(in srgb, var(--color-text-mid) 88%, var(--color-bg) 12%); |
|
font-variant-numeric: tabular-nums; |
|
white-space: nowrap; |
|
} |
|
|
|
/* Let clicks go to the overlay; quote/meta stay visible above background only visually (no pointer on text). */ |
|
.home-aside-highlights__item-inner .home-aside-highlights__quote, |
|
.home-aside-highlights__item-inner .home-aside-highlights__meta { |
|
position: relative; |
|
z-index: 0; |
|
pointer-events: none; |
|
} |
|
|
|
.home-aside-highlights__quote { |
|
display: -webkit-box; |
|
-webkit-box-orient: vertical; |
|
-webkit-line-clamp: 5; |
|
line-clamp: 5; |
|
overflow: hidden; |
|
font-style: italic; |
|
font-weight: 400; |
|
font-family: var(--main-body-font, Georgia), ui-serif, serif; |
|
margin-bottom: 0.3rem; |
|
word-break: break-word; |
|
color: inherit; |
|
} |
|
|
|
/* Match article `bodyHtml` semantics; keep aside scale (`.user-highlight__body` is larger in-article). */ |
|
.home-aside-highlights__quote--html.user-highlight__body { |
|
margin: 0 0 0.3rem; |
|
font-size: 0.78rem; |
|
line-height: 1.45; |
|
color: inherit; |
|
} |
|
|
|
/* Lead-in to the (truncated) highlight was removed so line-clamp shows the mark, not only context. */ |
|
.home-aside-highlights__quote--html .user-highlight__elide { |
|
font-style: normal; |
|
color: var(--color-text-mid, #6b6b6b); |
|
user-select: none; |
|
} |
|
|
|
.home-aside-highlights__meta { |
|
display: block; |
|
font-size: 0.7rem; |
|
font-style: normal; |
|
font-family: var(--font-family), system-ui, sans-serif; |
|
color: color-mix(in srgb, var(--color-text-mid) 80%, var(--color-bg) 20%); |
|
letter-spacing: 0.02em; |
|
transition: color 0.18s ease; |
|
} |
|
|
|
.home-aside-highlights__item-inner:hover .home-aside-highlights__meta, |
|
.home-aside-highlights__item-inner:has(.home-aside-highlights__hit:focus-visible) .home-aside-highlights__meta { |
|
color: color-mix(in srgb, var(--color-primary) 45%, var(--color-text-mid) 55%); |
|
} |
|
|
|
.home-aside-highlights__item-inner:hover .home-aside-highlights__time, |
|
.home-aside-highlights__item-inner:has(.home-aside-highlights__hit:focus-visible) .home-aside-highlights__time { |
|
color: color-mix(in srgb, var(--color-primary) 32%, var(--color-text-mid) 68%); |
|
} |
|
|
|
table { |
|
width: 100%; |
|
margin: 20px 0; |
|
} |
|
|
|
pre, code { |
|
text-wrap: wrap; |
|
padding: 3px; |
|
background-color: var(--color-bg-light); |
|
font-size: 1rem; |
|
} |
|
|
|
hr { |
|
margin: 20px 0; |
|
} |
|
|
|
dt { |
|
margin-top: 10px; |
|
} |
|
|
|
/* Responsive adjustments */ |
|
@media (max-width: 1024px) { |
|
/* Only the main column nav, not <nav> in the footer (Sitemap and feeds, etc.) */ |
|
.layout > nav, |
|
aside { |
|
display: none; /* Hide the sidebars on small screens */ |
|
} |
|
/* Home: keep highlights — stack <aside> under the featured wall (same DOM order; row layout would squeeze it beside main). */ |
|
.layout:has(.home-body--wall) { |
|
flex-direction: column; |
|
align-items: stretch; |
|
} |
|
|
|
.layout:has(.home-body--wall) > aside { |
|
display: block; |
|
width: 100%; |
|
max-width: none; |
|
min-width: 0; |
|
flex-shrink: 0; |
|
margin-top: 0.5rem; |
|
padding: 0 1em 1.75rem; |
|
box-sizing: border-box; |
|
} |
|
/* Fixed header is taller than 90px (safe-area + logo row + title padding). Match it or the first |
|
main content (e.g. featured authors intro) sits under the bar and looks “cut off” at the top. */ |
|
:root { |
|
--site-fixed-header-offset: max(7.25rem, calc(4.8rem + env(safe-area-inset-top, 0px))); |
|
} |
|
|
|
main { |
|
margin-top: var(--site-fixed-header-offset); |
|
width: 100%; |
|
} |
|
} |
|
|
|
/* Footer */ |
|
footer { |
|
background-color: var(--color-footer-bg); |
|
color: var(--color-footer-text); |
|
padding: 1.25rem 1rem 1.5rem; |
|
position: relative; |
|
width: 100%; |
|
min-width: 0; /* flex child of body column: avoid min-content width wider than the viewport */ |
|
box-sizing: border-box; |
|
border-top: 1px solid var(--color-border); |
|
} |
|
|
|
.site-footer { |
|
max-width: 1200px; |
|
margin: 0 auto; |
|
display: flex; |
|
flex-direction: column; |
|
align-items: stretch; |
|
gap: 1.75rem; |
|
text-align: left; |
|
min-width: 0; |
|
width: 100%; |
|
box-sizing: border-box; |
|
} |
|
|
|
.site-footer__syndication-title { |
|
font-size: 1.1rem; |
|
font-weight: 600; |
|
margin: 0 0 0.35rem; |
|
} |
|
|
|
.site-footer__syndication-hint { |
|
margin: 0 0 0.75rem; |
|
font-size: 0.9rem; |
|
color: var(--color-text); |
|
opacity: 0.9; |
|
max-width: 40rem; |
|
} |
|
|
|
/* Footer <nav> must not use the main-column nav rule (width: 21vw), or the list stays ~1/5 of the screen. */ |
|
.site-footer__nav { |
|
width: 100%; |
|
max-width: 100%; |
|
min-width: 0; |
|
flex-shrink: 1; |
|
padding: 0; |
|
overflow-y: visible; |
|
} |
|
|
|
.site-footer__nav li { |
|
margin: 0; /* not nav li { margin: 0.5em 0 } */ |
|
} |
|
|
|
.site-footer__syndication { |
|
min-width: 0; |
|
max-width: 100%; |
|
} |
|
|
|
.site-footer__syndication-list { |
|
display: flex; |
|
flex-wrap: wrap; |
|
align-items: baseline; |
|
row-gap: 0.4rem; |
|
list-style: none; |
|
margin: 0; |
|
padding: 0; |
|
font-size: 0.95rem; |
|
line-height: 1.5; |
|
min-width: 0; |
|
max-width: 100%; |
|
} |
|
|
|
/* Do not set min-width:0 on <li> — with flex it lets items shrink to a hairline and |
|
forces one-word-per-line wrapping. Use natural (content) size per item instead. */ |
|
.site-footer__syndication-list > li { |
|
display: flex; |
|
flex-wrap: wrap; |
|
align-items: center; |
|
gap: 0.4rem 0.45rem; |
|
flex: 0 0 auto; |
|
max-width: 100%; |
|
} |
|
|
|
.site-footer__syndication-list > li + li::before { |
|
content: "·"; |
|
color: var(--color-text-mid, #666); |
|
font-weight: 300; |
|
align-self: center; |
|
padding: 0 0.1rem 0 0; |
|
} |
|
|
|
.site-footer__link { |
|
color: var(--color-footer-link); |
|
text-decoration: underline; |
|
text-underline-offset: 2px; |
|
font-weight: 400; |
|
} |
|
|
|
.site-footer__link:hover { |
|
color: var(--color-text); |
|
} |
|
|
|
.site-footer__link:focus-visible { |
|
outline: 2px solid var(--color-focus-ring); |
|
outline-offset: 2px; |
|
} |
|
|
|
/* RSS + category feed links in one cell */ |
|
.site-footer__syndication-list__feeds { |
|
display: flex; |
|
flex-wrap: wrap; |
|
align-items: center; |
|
gap: 0.4rem 0.45rem; |
|
min-width: 0; |
|
max-width: 100%; |
|
/* Break only unbroken long words; avoid overflow-wrap:anywhere (splits at every symbol). */ |
|
word-break: break-word; |
|
overflow-wrap: break-word; |
|
} |
|
|
|
/* Narrow / tablet: feeds row full width; tighter footer so it doesn’t dominate the viewport. */ |
|
@media (max-width: 1024px) { |
|
footer { |
|
padding: 0.65rem 0.75rem 0.75rem; |
|
} |
|
|
|
.site-footer { |
|
gap: 0.65rem; |
|
} |
|
|
|
.site-footer__syndication-title { |
|
font-size: 0.95rem; |
|
margin: 0 0 0.15rem; |
|
} |
|
|
|
.site-footer__syndication-hint { |
|
margin: 0 0 0.35rem; |
|
font-size: 0.8rem; |
|
line-height: 1.35; |
|
} |
|
|
|
.site-footer__syndication-list { |
|
row-gap: 0.15rem; |
|
font-size: 0.88rem; |
|
line-height: 1.35; |
|
} |
|
|
|
.site-footer__syndication-list > li { |
|
gap: 0.25rem 0.35rem; |
|
} |
|
|
|
.site-footer__syndication-list__feeds { |
|
flex: 1 1 100%; |
|
gap: 0.25rem 0.35rem; |
|
} |
|
|
|
.site-footer__main { |
|
margin-top: 0; |
|
} |
|
|
|
.site-footer__legal { |
|
margin: 0.35rem 0 0; |
|
font-size: 0.85rem; |
|
line-height: 1.35; |
|
} |
|
|
|
footer .footer-links { |
|
margin: 0 0 0.3rem; |
|
} |
|
|
|
.footer-links .footer-link { |
|
margin: 0.2rem 0; |
|
line-height: 1.35; |
|
font-size: 0.88rem; |
|
} |
|
} |
|
|
|
/* Single-column footer: center both syndication and main. (900px+ uses side-by-side layout.) */ |
|
@media (max-width: 899px) { |
|
.site-footer { |
|
text-align: center; |
|
} |
|
|
|
.site-footer__syndication-hint { |
|
margin-left: auto; |
|
margin-right: auto; |
|
} |
|
|
|
.site-footer__syndication-list, |
|
.site-footer__syndication-list__feeds { |
|
justify-content: center; |
|
} |
|
} |
|
|
|
/* Dots between feed links (skip first <a> = "All articles"). */ |
|
.site-footer__syndication-list__feeds a:not(:first-of-type)::before { |
|
content: "·"; |
|
color: var(--color-text-mid, #666); |
|
font-weight: 300; |
|
margin-right: 0.45rem; |
|
text-decoration: none; |
|
display: inline; |
|
} |
|
|
|
.site-footer__feeds-icon { |
|
display: flex; |
|
flex-shrink: 0; |
|
line-height: 0; |
|
color: var(--color-text-mid, #666); |
|
opacity: 0.72; |
|
} |
|
|
|
.site-footer__main { |
|
text-align: center; |
|
} |
|
|
|
.site-footer__jumble { |
|
margin: 0 0 0.65rem; |
|
font-size: 0.95rem; |
|
} |
|
|
|
.site-footer__legal { |
|
margin: 1rem 0 0; |
|
font-size: 0.95rem; |
|
} |
|
|
|
@media (min-width: 900px) { |
|
.site-footer { |
|
flex-direction: row; |
|
align-items: flex-start; |
|
justify-content: space-between; |
|
gap: 2rem 3rem; |
|
} |
|
|
|
.site-footer__syndication { |
|
flex: 0 1 50%; |
|
} |
|
|
|
.site-footer__main { |
|
flex: 0 1 auto; |
|
min-width: min(20rem, 100%); |
|
text-align: right; |
|
} |
|
|
|
.site-footer__legal { |
|
text-align: right; |
|
} |
|
} |
|
|
|
footer .footer-links { |
|
margin: 0 0 0.5rem; |
|
} |
|
|
|
.featured-authors { |
|
max-width: 48rem; |
|
margin: 0 auto; |
|
padding: 0 0.5rem 2rem; |
|
display: flex; |
|
flex-direction: column; |
|
gap: 2.5rem; |
|
} |
|
|
|
.featured-authors-grid { |
|
display: grid; |
|
grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); |
|
gap: 0.85rem; |
|
} |
|
|
|
.featured-authors-grid__card { |
|
display: flex; |
|
flex-direction: column; |
|
align-items: center; |
|
gap: 0.35rem; |
|
padding: 0.75rem 0.55rem; |
|
border: 1px solid var(--color-border); |
|
background: var(--color-bg); |
|
text-decoration: none; |
|
color: inherit; |
|
} |
|
|
|
.featured-authors-grid__card:hover { |
|
text-decoration: none; |
|
background: var(--color-bg-light); |
|
} |
|
|
|
.featured-authors-grid__avatar { |
|
width: 64px; |
|
height: 64px; |
|
border-radius: 50%; |
|
overflow: hidden; |
|
box-shadow: 0 0 0 1px var(--color-border); |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
background: var(--color-bg-light); |
|
} |
|
|
|
.featured-authors-grid__avatar > img { |
|
width: 100%; |
|
height: 100%; |
|
object-fit: cover; |
|
display: block; |
|
} |
|
|
|
.featured-authors-grid__avatar-fallback { |
|
font-size: 1.25rem; |
|
color: var(--color-text-mid); |
|
} |
|
|
|
.featured-authors-grid__name { |
|
width: 100%; |
|
text-align: center; |
|
font-weight: 600; |
|
overflow: hidden; |
|
text-overflow: ellipsis; |
|
white-space: nowrap; |
|
} |
|
|
|
.featured-authors-grid__handle { |
|
width: 100%; |
|
text-align: center; |
|
font-size: 0.82rem; |
|
overflow: hidden; |
|
text-overflow: ellipsis; |
|
white-space: nowrap; |
|
} |
|
|
|
.featured-authors__intro { |
|
margin-bottom: 0; |
|
overflow: visible; /* do not clip heading ascenders */ |
|
} |
|
|
|
/* Override global h1 (3.2rem + tight line box); keep full glyphs visible */ |
|
.featured-authors__intro h1 { |
|
margin: 0 0 0.5rem; |
|
font-size: clamp(1.35rem, 2.6vw, 2.05rem); |
|
line-height: 1.28; |
|
font-weight: 700; |
|
font-family: var(--heading-font), serif; |
|
color: var(--color-primary); |
|
padding: 0.2em 0 0.05em; |
|
overflow: visible; |
|
} |
|
|
|
.featured-authors__card { |
|
margin-bottom: 2.5rem; |
|
padding-bottom: 1.5rem; |
|
border-bottom: 1px solid var(--color-border); |
|
box-sizing: border-box; |
|
width: 100%; |
|
} |
|
|
|
.featured-authors__card:last-of-type { |
|
border-bottom: none; |
|
} |
|
|
|
/* One shared content width: drop the 40rem cap so label/value grid lines line up with the card edges */ |
|
.featured-authors__card .author-profile.author-profile--featured { |
|
max-width: none; |
|
width: 100%; |
|
margin-left: 0; |
|
margin-right: 0; |
|
box-sizing: border-box; |
|
} |
|
|
|
.author-profile--featured .author-profile__header-meta { |
|
max-width: none; |
|
width: 100%; |
|
} |
|
|
|
/* Same first-column width for section blocks and per-row fields so dividers don’t “jump” between cards */ |
|
.author-profile--featured .author-profile__section--label-value, |
|
.author-profile--featured .author-profile__meta-line, |
|
.author-profile--featured .author-profile__identity-row, |
|
.author-profile--featured .author-profile__payment { |
|
grid-template-columns: minmax(5.25rem, 8.5rem) minmax(0, 1fr); |
|
align-items: start; |
|
column-gap: 0.65rem; |
|
} |
|
|
|
.author-profile--featured .author-profile__title { |
|
font-size: 1.5rem; |
|
} |
|
|
|
/* Very narrow: single column so tiny two-column cells don’t look skewed */ |
|
@media (max-width: 30rem) { |
|
.author-profile--featured .author-profile__section--label-value, |
|
.author-profile--featured .author-profile__meta-line, |
|
.author-profile--featured .author-profile__identity-row, |
|
.author-profile--featured .author-profile__payment { |
|
grid-template-columns: 1fr; |
|
row-gap: 0.2rem; |
|
} |
|
|
|
.author-profile--featured .author-profile__meta-line, |
|
.author-profile--featured .author-profile__identity-row, |
|
.author-profile--featured .author-profile__payment { |
|
margin: 0.5rem 0; |
|
} |
|
|
|
.author-profile--featured .author-profile__meta-value, |
|
.author-profile--featured .author-profile__identity-link, |
|
.author-profile--featured .author-profile__payment-addr { |
|
white-space: normal; |
|
word-break: break-word; |
|
} |
|
} |
|
|
|
.featured-authors__actions { |
|
display: flex; |
|
flex-direction: row; |
|
flex-wrap: nowrap; |
|
flex-shrink: 0; |
|
align-items: center; |
|
justify-content: center; |
|
column-gap: 0.75rem; |
|
margin: 1rem 0 0; |
|
width: 100%; |
|
box-sizing: border-box; |
|
} |
|
|
|
.featured-authors__actions .btn { |
|
flex: 0 1 auto; |
|
text-align: center; |
|
} |
|
|
|
/* Narrow: smaller page title + intro; flex gap avoids margin collapse with first author block. */ |
|
@media (max-width: 1024px) { |
|
.featured-authors { |
|
align-items: stretch; |
|
gap: 1.75rem; |
|
} |
|
|
|
.featured-authors__intro { |
|
/* Contain the intro <p> margin so it doesn’t collapse with the first author block */ |
|
display: flow-root; |
|
} |
|
|
|
.featured-authors__card { |
|
margin-bottom: 0; |
|
} |
|
|
|
.featured-authors__intro h1 { |
|
/* Slightly smaller in the max-1024 layout; same visible box as the base h1 */ |
|
font-size: clamp(1.3rem, 4.2vw, 1.95rem); |
|
} |
|
|
|
.featured-authors__intro p { |
|
font-size: 0.9rem; |
|
line-height: 1.45; |
|
} |
|
} |
|
|
|
.footer-links a { |
|
color: var(--color-footer-link); |
|
text-decoration: underline; |
|
text-underline-offset: 2px; |
|
} |
|
|
|
.footer-links a:hover { |
|
color: var(--color-text); |
|
} |
|
|
|
.footer-links a:focus-visible { |
|
outline: 2px solid var(--color-focus-ring); |
|
outline-offset: 3px; |
|
} |
|
|
|
.search input { |
|
flex-grow: 1; |
|
}
|
|
|