/*
 * Constrain raw media in feed item content. The fetcher emits
 * <figure class="wp-block-image|video"> wrappers around <img>/<video>
 * tags, but those core block stylesheets are only enqueued when a real
 * core/image|video block is parsed on the page — which never happens for
 * our injected HTML. Scope on .heckl_feed_item (added by post_class) so the
 * rule applies on every surface a feed item renders on: post-type
 * archive, home-with-?heckl_feed_type=X filter, and single views.
 */
.heckl_feed_item figure,
.heckl_feed_item img,
.heckl_feed_item video {
	max-width: 100%;
}

.heckl_feed_item img,
.heckl_feed_item video {
	height: auto;
}

/*
 * Code blocks. WPcom Reader items frequently embed long-line code snippets
 * (raw HTML, PHP, etc.); <pre> defaults to white-space: pre which never
 * wraps, so a single long line widens the column. core/code's stylesheet
 * normally fixes this with overflow-wrap, but it isn't enqueued here for
 * the same reason image/video styles aren't (no real block is parsed).
 */
.heckl_feed_item pre {
	max-width: 100%;
	overflow-x: auto;
}

/* ─── ActivityPub posts: self-contained card layout ──────────
 *
 * Every visual element of an AP card lives inside `post_content`
 * as a single `<div class="heckl-ap-card">` baked in at fetch time
 * by Radical_Socials_ActivityPub_Fetcher::render_card_wrapper().
 * That means a theme template that reorders or removes the
 * surrounding blocks (post title, post date, our author blocks,
 * read-more, etc.) doesn't affect how the card looks — the layout
 * is fully owned by this CSS plus the markup baked into content.
 *
 * Sizes are all ems so the card scales with the visitor's base
 * font size; colors come from existing theme palette tokens
 * (`--wp--preset--color--contrast-1` for muted text) with a
 * sensible `currentColor` fallback when a theme doesn't define
 * them.
 *
 * Only AP items get this treatment; RSS and WP.com cards keep the
 * standard block layout (post-title + date + read-more + author
 * blocks) since those have meaningful titles and are closer to
 * traditional blog content.
 */

/* Hide the surrounding blocks for AP items only. They're either
 * not part of the social-card layout (title, date, featured
 * image, read-more, comments link) or their data is already
 * present inside the card content (avatar + name baked into
 * .heckl-ap-card during normalize). */
.heckl-feed-type-activitypub .wp-block-post-title,
.heckl-feed-type-activitypub .wp-block-post-date,
.heckl-feed-type-activitypub .wp-block-post-featured-image,
.heckl-feed-type-activitypub .wp-block-post-comments-link {
	display: none;
}

/* The card itself — a small grid laid out inside the post body.
 * Areas: optional "Reposted by …" line at the top spanning both
 * columns, avatar in column 1 spanning rows 2–3, display name in
 * column 2 row 2, post body (paragraphs, attachments, etc.) in
 * column 2 row 3. */
.heckl-feed-type-activitypub .entry-content .heckl-ap-card {
	display: grid;
	grid-template-columns: 3em 1fr;
	grid-template-areas:
		"boost  boost"
		"avatar name"
		"avatar body";
	column-gap: 0.875em;
	row-gap: 0.375em;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-boost-context {
	grid-area: boost;
	margin: 0;
	font-size: 0.825em;
	color: var( --wp--preset--color--contrast-1, currentColor );
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-boost-context a {
	color: inherit;
	text-decoration: none;
}

/* The avatar is wrapped in a <div> so wpautop doesn't wrap the bare
 * <img> in a <p> (see render_card_wrapper for the why). Layout lives on
 * the wrapper; the inner <img> just fills it. */
.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-avatar {
	grid-area: avatar;
	align-self: start;
	width: 3em;
	height: 3em;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-avatar img {
	display: block;
	width: 100%;
	height: 100%;
	border-radius: 50%;
	object-fit: cover;
}

/* Name row: bold display name, muted "@user@host" handle, and a muted
 * relative time. They live in a single flex row that wraps onto a
 * second line on narrow viewports — the time stays close to the handle
 * so the visual association doesn't break. */
.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-name {
	grid-area: name;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	column-gap: 0.4em;
	font-size: 1em;
	line-height: 1.3;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-displayname {
	font-weight: 600;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-handle,
.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-time {
	font-size: 0.825em;
	color: var( --wp--preset--color--contrast-1, currentColor );
	font-weight: 400;
}

/* Render a middle-dot separator before the time only when it follows
 * another part of the name row, so we never end up with a stray "·" at
 * the start (which happens for items missing both display name and
 * handle). */
.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-handle + .heckl-ap-time::before,
.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-displayname + .heckl-ap-time::before {
	content: "·";
	margin-right: 0.4em;
	opacity: 0.7;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-name a {
	color: inherit;
	text-decoration: none;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-body {
	grid-area: body;
	font-size: 1em;
	line-height: 1.5;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-body > p {
	margin: 0.375em 0;
}

/* Reply context ("↪️ In reply to …") gets a muted treatment and
 * sits at the top of the body column (in flow with the rest of
 * the post text). */
.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-reply-context {
	font-size: 0.825em;
	color: var( --wp--preset--color--contrast-1, currentColor );
	margin: 0 0 0.375em;
}

/* Multiple image attachments: lay them in a 2-column grid inside
 * the body column. Single-image and mixed-media posts keep the
 * default block flow. */
.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-body:has(.wp-block-image + .wp-block-image) {
	display: grid;
	grid-template-columns: 1fr 1fr;
	column-gap: 0.5em;
	row-gap: 0.5em;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-body:has(.wp-block-image + .wp-block-image) > p,
.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-body:has(.wp-block-image + .wp-block-image) > .heckl-reply-context {
	grid-column: 1 / -1;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-body > .wp-block-image {
	margin: 0.5em 0 0;
}

.heckl-feed-type-activitypub .entry-content .heckl-ap-card .heckl-ap-body > .wp-block-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 0.5em;
}

.heckl-refresh-bar {
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
	justify-content: center;
	padding: 8px 0 4px;
}

.heckl-refresh-btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 14px;
	border: 1px solid currentColor;
	border-radius: 999px;
	background: transparent;
	color: currentColor;
	font: inherit;
	font-size: 0.85em;
	opacity: 0.6;
	cursor: pointer;
	transition: opacity 0.15s;
}

.heckl-refresh-btn:hover {
	opacity: 1;
}

.heckl-refresh-btn:disabled {
	cursor: default;
	opacity: 0.4;
}

.heckl-refresh-btn .heckl-pull-spinner {
	display: none;
	width: 14px;
	height: 14px;
	border: 2px solid currentColor;
	border-top-color: transparent;
	border-radius: 50%;
	animation: heckl-spin 0.7s linear infinite;
}

.heckl-refresh-bar.heckl-pull-refreshing .heckl-pull-arrow {
	display: none;
}

.heckl-refresh-bar.heckl-pull-refreshing .heckl-pull-spinner {
	display: block;
}

.heckl-last-refreshed {
	font-size: 0.8em;
	opacity: 0.55;
}

@keyframes heckl-spin {
	to { transform: rotate(360deg); }
}
