diff --git a/CLAUDE.md b/CLAUDE.md index 0f0309d..3defbaa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -134,7 +134,7 @@ ISR endpoint at `GET /api/revalidate?secret=&slug=/blog/`. Secret - `‡` (principal investigator) — `principalInvestigator: true` on the author. Shows when **2+ authors** AND at least one is PI. - `¹ ² ³` (affiliation indices) — derived from `affiliations: [...]` on each author. Shows when **2+ affiliations** exist on the entry. - Marker order on each author follows academic convention: `*†‡` then numeric indices. The affiliation legend below the author line drops its leading `` under the same `showAffSup` rule. Single-author / single-affiliation entries collapse to clean text — no orphan markers. Each `` has `cursor-help` + a native `title` tooltip (affiliation index sups resolve to the full affiliation name; symbol sups resolve to their caption text). A combined caption line appears below the affiliation row when any symbol marker is shown — e.g. `*Corresponding author · †Equal contribution · ‡Principal investigator` — joined by ` · `. + Marker order on each author follows academic convention: `*†‡` then numeric indices. The affiliation legend below the author line drops its leading `` under the same `showAffSup` rule. Single-author / single-affiliation entries collapse to clean text — no orphan markers. Each `` has `cursor-help` + a native `title` tooltip (affiliation index sups resolve to the full affiliation name; symbol sups resolve to their caption text). A combined caption line appears below the affiliation row when any symbol marker is shown — e.g. `*Corresponding author · †Equal contribution · ‡Principal investigator` — joined by `·`. ## Indexing Helper diff --git a/src/components/content/blog/HeadingContent.tsx b/src/components/content/blog/HeadingContent.tsx index 95eb3bc..f052864 100644 --- a/src/components/content/blog/HeadingContent.tsx +++ b/src/components/content/blog/HeadingContent.tsx @@ -41,29 +41,14 @@ export const HeadingContent: React.FunctionComponent = (pro return (
- {/* Hero thumbnail. Rendering the same image that BlogItem uses on /blog - gives the post detail page a strong claim as the canonical landing - for that image — Google Images links should resolve to the post - rather than the list page. */} - {props.thumbnail && ( -
- -
- )} - - {/* Title */} + {/* Title — the thumbnail in frontmatter feeds Open Graph + Twitter cards + (social previews) and BlogItem listing thumbnails. Intentionally NOT + rendered as an in-page hero: on narrow viewports it dominated the + fold and pushed the headline below the scroll, and the post detail + page already has a strong canonical claim via JSON-LD primaryImage. */}

{props.title} diff --git a/src/components/content/research/ResearchItem.tsx b/src/components/content/research/ResearchItem.tsx index 3ea3fbd..09cc0a7 100644 --- a/src/components/content/research/ResearchItem.tsx +++ b/src/components/content/research/ResearchItem.tsx @@ -7,7 +7,6 @@ import { twclsx } from '@/libs/twclsx' import { ComingSoonImage } from './ComingSoonImage' import type { Research } from 'me' -import NextImage from 'next/image' import { Fragment } from 'react' type ResearchItemProps = Research & { priority?: boolean } @@ -59,22 +58,32 @@ export const ResearchItem: React.FunctionComponent = (props) return (
-
+
{props.comingSoon ? ( ) : ( - instead of next/image: next/image with `fill` + // requires a fixed-aspect parent and would either crop + // (object-cover) or letterbox (object-contain) — neither matches + // "card adopts the image's natural aspect ratio". ImageKit URLs + // already include the right width transform via resolveListingImage. + // eslint-disable-next-line @next/next/no-img-element + {props.title} )} @@ -107,7 +116,7 @@ export const ResearchItem: React.FunctionComponent = (props) )} {venueLine && ( -
[{venueLine}]
+
{venueLine}
)} {actions.length > 0 && ( diff --git a/src/components/content/research/ResearchTeaser.tsx b/src/components/content/research/ResearchTeaser.tsx index 71c2e94..f2671c6 100644 --- a/src/components/content/research/ResearchTeaser.tsx +++ b/src/components/content/research/ResearchTeaser.tsx @@ -1,7 +1,7 @@ -import { WrappedImage } from '@/components/site/images' - import { twclsx } from '@/libs/twclsx' +import NextImage from 'next/image' + type ResearchTeaserProps = { src: string alt: string @@ -9,17 +9,28 @@ type ResearchTeaserProps = { priority?: boolean } +/** + * Hero figure on the research detail page. Uses a 16:9 aspect-ratio box with + * `object-contain` so the entire scientific figure is visible at every viewport + * width — research teasers usually have important content (axes, labels, + * sub-panels) edge-to-edge that can't be cropped by `object-cover`. The bg + * tile shows behind the image only when the source aspect ratio mismatches. + */ export const ResearchTeaser: React.FunctionComponent = ({ src, alt, caption, priority }) => { return (
- +
+ +
{caption && (
(({ ) } + // Default Next.js scroll behavior: scroll-to-top on a new path, hash-aware + // for in-page anchors. The previous `scroll={false}` blocked both, leaving + // readers stranded mid-page when navigating between posts. return ( - + {children} )