/*
 * Sociaffy Analytics — client dashboard.
 *
 * Colour roles follow a validated data-viz palette, light surface only.
 *
 *   series-1 (primary)   #6366F1
 *   series-2 (projection) #eb6834
 *   good / critical       fixed status colours, always paired with an arrow
 *                         glyph and a label so colour never carries meaning alone
 */

/*
 * Some WooCommerce account themes cap .account_inner_content (or similar
 * wrappers) to a narrow reading width meant for text-based tabs like Orders
 * or Addresses. Our dashboard needs the full content column, so widen only
 * the ancestor that is actually holding our endpoint, leaving every other
 * account-area tab's width untouched.
 */
.account_inner_content:has(.soc-app) {
	max-width: 100%;
	background: none;
	border: none;
	padding-top: 0;
}

/*
 * The theme's breadcrumb bar, dropped on the analytics endpoint only.
 *
 * It reads "Sociaffy - Account / Account / Dashboard" — every part of which
 * the sidebar already shows, while costing 52px of a screen that has to fit a
 * chart. Profile and Subscription & Billing keep theirs, so the body class is
 * set on our endpoint alone (see Dashboard::body_class()).
 *
 * The bar is `position: fixed`, so hiding it leaves the content's margin-top
 * stranded; both offsets below are the theme's own values minus the bar's
 * height (desktop 135 - 52, mobile 125 - 50), which keeps the gap above the
 * content exactly as the theme intended it.
 */
body.soc-dashboard-page .inner_header {
	display: none;
}

body.soc-dashboard-page.woocommerce-account .woocommerce-MyAccount-content {
	margin-top: 83px;
}

@media (max-width: 767px) {

	body.soc-dashboard-page.woocommerce-account .woocommerce-MyAccount-content {
		margin-top: 75px;
	}
}

.soc-app {
	color-scheme: light;

	--soc-surface: #ffffff;
	--soc-plane: #f6f6f8;
	--soc-ink: #333333;
	--soc-ink-2: #52514e;
	--soc-muted: #767570;
	--soc-grid: #e6e6ea;
	--soc-axis: #c3c2b7;
	--soc-border: rgba(11, 11, 11, 0.1);

	--soc-series-1: #6366f1;
	--soc-series-2: #eb6834;

	--soc-good: #1a7f37;
	--soc-good-bg: #d4f5d8;
	--soc-bad: #c0341f;
	--soc-bad-bg: #fbdcdb;
	/*
	 * The middle state between the good/bad pair. These are the exact values
	 * the post-format "album" badge already uses, promoted to tokens rather
	 * than a second yellow being invented alongside it.
	 */
	--soc-warn: #9a6215;
	--soc-warn-bg: #fdedd8;

	--soc-accent: #d13684;

	--soc-radius: 6px;
	/*
	 * Text fields and hashtag chips deliberately do NOT follow --soc-pill.
	 * A brand set to a full pill radius (Hypeflare runs 999px) turns a text
	 * input into a lozenge and makes the hashtag chips read as buttons, so
	 * these hold a fixed modest radius on every brand. Pills that are meant
	 * to be pills — the range select, score bubble, tabs — still follow it.
	 */
	--soc-control-radius: 5px;
	--soc-gap: 16px;
	--soc-card-shadow: 0 4px 24px rgba(34, 41, 47, 0.1);

	font-family: var( --soc-font, "Euclid Circular A" ), -apple-system, "system-ui", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	color: var(--soc-ink);
	line-height: 1.45;
}

.soc-app *,
.soc-app *::before,
.soc-app *::after {
	box-sizing: border-box;
}

/* ------------------------------------------------------------------ Cards */

.soc-card {
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-radius: var(--soc-radius);
	padding: 20px;
	margin-bottom: var(--soc-gap);
}

/*
 * Hunter's call: 15px of breathing room above the first card specifically
 * (the profile card), not every .soc-card everywhere -- a blanket
 * margin-top would double up the gap between every stacked card on every
 * tab. Scoped to :first-child of .soc-app, which is always the profile
 * card. */
.soc-app > .soc-card:first-child {
	margin-top: 15px;
}

.soc-notice {
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-left: 3px solid var(--soc-accent);
	border-radius: 10px;
	padding: 16px 18px;
	margin: 0 0 var(--soc-gap);
	color: var(--soc-ink-2);
}

.soc-app__boot {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 32px;
	color: var(--soc-muted);
}

.soc-spinner {
	width: 16px;
	height: 16px;
	border: 2px solid var(--soc-grid);
	border-top-color: var(--soc-accent);
	border-radius: 50%;
	animation: soc-spin 0.8s linear infinite;
	flex: none;
}

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

@media (prefers-reduced-motion: reduce) {
	.soc-spinner {
		animation-duration: 2.4s;
	}
}

/* --------------------------------------------------------- Profile header */

.soc-profile {
	display: flex;
	flex-wrap: wrap;
	gap: 24px;
	align-items: flex-start;
}

.soc-profile__avatar-col {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
	flex: none;
}

.soc-profile__avatar {
	width: 112px;
	height: 112px;
	border-radius: 50%;
	object-fit: cover;
	background: var(--soc-plane);
	flex: none;
}

/*
 * The theme underlines every `a` inside `.page-content` (0,2,0), which outguns
 * a plain single-class selector — hence the `.soc-app a.` prefix here.
 */
.soc-app a.soc-profile__ig-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-size: 28px;
	color: var(--soc-accent);
	text-decoration: none;
}

.soc-app a.soc-profile__ig-link:hover {
	opacity: 0.8;
}

/*
 * The avatar and username double as links to the profile. Both inherit
 * everything so nothing about the card changes visually — the only job of
 * these rules is to undo the theme's link colour and underline.
 */
.soc-app a.soc-profile__avatar-link {
	display: block;
	line-height: 0;
	text-decoration: none;
	flex: none;
}

.soc-app a.soc-profile__username-link {
	color: inherit;
	font: inherit;
	text-decoration: none;
}

.soc-profile__identity {
	flex: 1 1 260px;
	min-width: 0;
}

.soc-profile__username {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 1.98rem;
	font-weight: 600;
	margin: 0 0 2px;
	word-break: break-word;
}

.soc-profile__name {
	color: var(--soc-ink-2);
	font-size: 1.18rem;
	font-weight: 300;
	margin: 0 0 10px;
}

.soc-profile__bio {
	color: var(--soc-ink-2);
	white-space: pre-line;
	margin: 0 0 8px;
	font-size: 0.94rem;
}

.soc-profile__link {
	color: var(--soc-accent);
	word-break: break-all;
	font-size: 0.94rem;
}

.soc-profile__meta {
	color: var(--soc-muted);
	font-size: 0.85rem;
	margin: 10px 0 0;
}

.soc-profile__actions {
	display: flex;
	gap: 8px;
	margin-top: 12px;
	flex-wrap: wrap;
}

.soc-verified {
	display: inline-flex;
	vertical-align: middle;
	flex: none;
	font-size: 0.72em;
	line-height: 1;
}

/*
 * Two stacked Font Awesome glyphs standing in for Instagram's scalloped
 * verified badge -- the free FA tier this site loads has no single icon
 * shaped like it (badge-check is Pro-only), so fa-certificate (the seal
 * outline) carries their blue and a small white fa-check sits centred on
 * top, composited with plain CSS rather than a hand-rolled SVG.
 */
.soc-verified__badge {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}
.soc-verified__badge .fa-certificate {
	/* Instagram's own badge blue, not our accent — it is their mark, and
	   recolouring it would read as a status of ours rather than theirs. */
	color: #3897f0;
}
.soc-verified__badge .fa-check {
	position: absolute;
	color: #fff;
	font-size: 0.42em;
}

.soc-profile__summary {
	flex: 1 1 320px;
	min-width: 0;
}

.soc-summary-grid {
	display: flex;
	justify-content: space-between;
	gap: 16px;
}

.soc-summary__label {
	color: var(--soc-muted);
	font-size: 0.96rem;
	margin-bottom: 2px;
}

.soc-summary__value {
	font-size: 1.48rem;
	font-weight: 600;
	line-height: 1.1;
}

.soc-summary__delta {
	font-size: 0.85rem;
	font-weight: 600;
	margin-top: 2px;
}

/* Score meter */

/*
 * The bubble is always centred on the marker — never nudged sideways — so it
 * reads as a pointer rather than a label that drifted. The horizontal padding
 * insets the track far enough that a bubble at 0% or 100% still has room to
 * sit centred without clipping the card, which is what the old --start/--end
 * clamping classes were working around (and why they looked lopsided).
 */
.soc-score {
	/* Measured from the track; the bubble floats ~34px above it, so the visual
	   gap to the stats row above is roughly this minus 34. */
	margin-top: 52px;
	padding: 0 34px;
}

.soc-score__track {
	position: relative;
	height: 6px;
	border-radius: 999px;
	background: var(--soc-accent);
}

.soc-score__bubble {
	position: absolute;
	bottom: calc(100% + 10px);
	transform: translateX(-50%);
	background: var(--soc-accent);
	color: #fff;
	font-size: 0.78rem;
	font-weight: 700;
	padding: 3px 8px;
	border-radius: var( --soc-pill, 5px );
	white-space: nowrap;
}

.soc-score__bubble::after {
	content: '';
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	border: 5px solid transparent;
	border-top-color: var(--soc-accent);
}

.soc-score__marker {
	position: absolute;
	top: 50%;
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: var(--soc-surface);
	border: 2px solid var(--soc-accent);
	transform: translate(-50%, -50%);
}

.soc-score__caption {
	display: flex;
	justify-content: center;
	align-items: baseline;
	gap: 8px;
	margin-top: 8px;
	color: var(--soc-muted);
	font-size: 0.85rem;
}

.soc-summary__range {
	display: flex;
	justify-content: flex-end;
	margin-top: 14px;
}

/* ------------------------------------------------------------------- Bars */

.soc-toolbar {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin-bottom: var(--soc-gap);
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-radius: var(--soc-radius);
	padding: 12px 16px;
}

/* Parked inside the theme's own breadcrumb row instead of stacked as its own
   card — no card chrome, no bottom margin, sized to sit inline. */
.soc-toolbar--inline {
	flex: 0 1 auto;
	flex-wrap: nowrap;
	background: none;
	border: none;
	padding: 0;
	margin: 0;
}

.soc-toolbar--inline .soc-toolbar__spacer {
	display: none;
}

.soc-toolbar--inline .soc-combobox {
	min-width: 180px;
}

/* Same idea as .soc-toolbar--inline above (built for the breadcrumb row
   this replaces) but the spacer stays live -- it is what pushes the
   account buttons over to sit beside the notification bell instead of
   right next to the status chips. */
.soc-toolbar--header {
	flex: 1 1 auto;
	flex-wrap: nowrap;
	background: none;
	border: none;
	padding: 0;
	margin: 0;
	min-width: 0;
}
.soc-toolbar--header .soc-combobox {
	min-width: 160px;
	max-width: 240px;
}

/*
 * Add Account/Account settings are <a class="soc-btn ...">, and the
 * rules that undo the theme's link underline/recolour on them
 * (.soc-app a.soc-btn* below) are scoped to require .soc-app as an
 * ancestor. The header toolbar sits outside .soc-app's DOM subtree, so
 * those rules silently stopped matching the moment it moved here --
 * same fix, re-scoped to where the toolbar actually lives now.
 */
.soc-hdr-toolbar-slot a.soc-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	border-radius: var( --soc-pill, 5px );
	color: var(--soc-ink);
	text-decoration: none;
}
.soc-hdr-toolbar-slot a.soc-btn:hover,
.soc-hdr-toolbar-slot a.soc-btn:focus-visible {
	text-decoration: none;
}
.soc-hdr-toolbar-slot a.soc-btn--primary,
.soc-hdr-toolbar-slot a.soc-btn--primary:hover {
	color: #fff;
	text-decoration: none;
}
.soc-hdr-toolbar-slot a.soc-btn--ghost:hover {
	color: var(--soc-accent);
	border-color: var(--soc-accent);
	text-decoration: none;
}

/*
 * Left edge lines up with where the page BODY content actually starts
 * (inside the .soc-app card, past its own left padding) -- not the
 * sidebar nav's own right edge, which left a visible gap. vw units
 * instead of % because margin-left percentages resolve against this
 * slot's own containing block (the header bar), not the viewport --
 * vw is what actually tracks the sidebar's viewport-relative
 * breakpoints (account.css: 15%/18%/22%) correctly. The -40px is the
 * header logo's width (70px) minus the card's own left padding (30px),
 * both fixed regardless of viewport.
 */
.soc-hdr-toolbar-slot {
	margin-left: calc( 15vw - 40px );
}

@media ( max-width: 1600px ) {
	.soc-hdr-toolbar-slot {
		margin-left: calc( 18vw - 40px );
	}
}

@media ( max-width: 1400px ) {
	.soc-hdr-toolbar-slot {
		margin-left: calc( 22vw - 40px );
	}
}

/*
 * Match the Notifications button's actual rendered height (36px, from
 * 7px 12px padding + its own font-size) instead of the page-body
 * toolbar's larger 40px/42px buttons -- measured live, the mismatch is
 * what read as "not vertically centred" even though align-items:center
 * was already correct; same centre point, just different heights.
 */
.soc-toolbar--header .soc-btn {
	min-height: 0;
	padding: 7px 12px;
	font-size: 14px;
}

/*
 * Safety net for narrower desktop widths (a 13" laptop window, a split
 * screen, anything under ~1400px) -- at full label width the toolbar can
 * overflow past the notification bell and push it off-screen. Wide
 * monitors never hit this breakpoint and keep full labels untouched.
 */
@media ( max-width: 1400px ) {
	.soc-toolbar--header .soc-btn__label {
		display: none;
	}
	.soc-toolbar--header .soc-combobox {
		min-width: 100px;
		max-width: 160px;
	}
	.soc-toolbar--header .soc-btn {
		padding: 7px 10px;
	}
}

.soc-toolbar__spacer {
	flex: 1 1 auto;
}

/* The toolbar's controls, kept as one unit so they wrap together. */
.soc-toolbar__actions {
	display: flex;
	align-items: center;
	gap: 8px;
}

/* What each Posts-card stat icon means. Lives in the same toolbar strip as
   the type/sort filters (pushed right by .soc-toolbar__spacer) rather than
   its own card, and wraps onto its own line under the filters on narrow
   widths same as the rest of the toolbar does. */
.soc-posts-legend {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 14px;
	font-size: 12px;
	color: var(--soc-muted);
}

.soc-posts-legend__item {
	display: flex;
	align-items: center;
	gap: 5px;
	white-space: nowrap;
	font-weight: 500;
}

.soc-posts-legend__item .soc-post__icon {
	font-size: 12px;
}

/*
 * The whole legend sits at the right end of the toolbar (pushed there by
 * .soc-toolbar__spacer), so a bubble that grows rightward from the
 * default .soc-tip anchor runs off the edge of the screen -- worst on
 * the last item, "Total watch time". Right-anchor the lot, same fix as
 * .soc-tile__info.soc-tip's own override, plus the same viewport clamp
 * so it still fits on a narrow window instead of just moving the overflow
 * to the left edge.
 */
.soc-posts-legend__item.soc-tip::after {
	left: auto;
	right: 0;
	max-width: min( 240px, calc( 100vw - 24px ) );
}
.soc-posts-legend__item.soc-tip::before {
	left: auto;
	right: 7px;
}

/*
 * Some themes ship a form reset (input/select/textarea { width: 100% }) that
 * outranks the shared .soc-select rule below, since that rule never sets its
 * own width. Pin actual <select> elements back to their content width; the
 * combobox's <input> is deliberately excluded so it still fills its wrapper.
 */
select.soc-select {
	width: auto;
	height: 40px;
	/* iOS Safari auto-zooms the page on focus for any field under 16px. */
	font-size: 16px;
}

/*
 * Desktop range picker.
 *
 * A native <select> hands its open list to the OS, which draws it in the
 * control's own font — so the brand face on the button dragged the brand face
 * into the menu. This is the same button with a list we own, which is the only
 * way to keep Euclid on the control and the system stack in the options.
 * Phones keep the real <select>; see rangeSelect() in dashboard.js.
 */
.soc-rangepick {
	position: relative;
	display: inline-block;
}

.soc-rangepick__button {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	font: inherit;
	font-size: 0.9rem;
	font-weight: 600;
	min-height: 40px;
	padding: 9px 14px;
	border: none;
	border-radius: var( --soc-pill, 5px );
	background: var(--soc-accent);
	color: #fff;
	cursor: pointer;
}

/*
 * The theme paints a flat #cc3366 onto every button:hover, which reads as red
 * next to our pink. Darken the accent itself instead, so each brand hovers to
 * its own colour rather than the theme's.
 */
.soc-rangepick__button:hover,
.soc-rangepick__button:focus,
.soc-rangepick__button:focus-visible {
	background: var(--soc-accent);
	background: color-mix( in srgb, var(--soc-accent) 82%, #000 );
	color: #fff;
}

/*
 * Secondary variant of the same control. The range picker is the page's primary
 * action and carries the accent fill; the Posts filters sit inside the content
 * and would shout over it in the same treatment — so they take the surface and
 * border of an ordinary control while opening the identical list.
 */
.soc-rangepick--plain .soc-rangepick__button {
	background: var(--soc-surface);
	color: var(--soc-ink);
	border: 1px solid var(--soc-border);
}

.soc-rangepick--plain .soc-rangepick__button:hover,
.soc-rangepick--plain .soc-rangepick__button:focus,
.soc-rangepick--plain .soc-rangepick__button:focus-visible {
	background: var(--soc-surface);
	color: var(--soc-accent);
	border-color: var(--soc-accent);
}

.soc-rangepick--plain .soc-rangepick__caret {
	color: var(--soc-muted);
}

.soc-rangepick--plain .soc-rangepick__button:hover .soc-rangepick__caret {
	color: var(--soc-accent);
}

.soc-rangepick__caret {
	display: inline-flex;
	font-size: 0.75em;
	line-height: 1;
}

.soc-rangepick__list {
	position: absolute;
	z-index: 30;
	top: calc(100% + 6px);
	right: 0;
	min-width: 100%;
	margin: 0;
	padding: 6px;
	list-style: none;
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-radius: var( --soc-control-radius, 5px );
	box-shadow: var(--soc-card-shadow);
}

.soc-rangepick__list[hidden] {
	display: none;
}

.soc-rangepick__option {
	padding: 8px 12px;
	border-radius: var( --soc-control-radius, 5px );
	font-size: 0.88rem;
	/* Brand face, but lighter than the button and the selected row, so the
	   current choice stands out from the ones you could switch to. */
	font-weight: 400;
	color: var(--soc-ink);
	white-space: nowrap;
	cursor: pointer;
}

.soc-rangepick__option:hover,
.soc-rangepick__option:focus {
	background: var(--soc-grid);
	outline: none;
}

.soc-rangepick__option[aria-selected="true"] {
	background: var(--soc-accent);
	color: #fff;
	font-weight: 600;
}

/*
 * Native selects, dressed to match the rest of the controls.
 *
 * Left alone they render the platform's own arrow in the platform's own style,
 * which is what made the Posts filters read as raw form fields beside the range
 * picker. The OS arrow is suppressed and the same Font Awesome caret used
 * elsewhere is laid over the top, so one chevron runs through the whole
 * dashboard. The radius follows the brand token rather than a fixed value, so
 * Hypeflare's pills stay pills.
 *
 * It remains a real <select>: the open list is still the native one, which is
 * the only version that behaves correctly on a phone.
 */
.soc-selectwrap {
	position: relative;
	display: inline-block;
}

.soc-selectwrap select.soc-select {
	appearance: none;
	-webkit-appearance: none;
	border-radius: var( --soc-pill, 5px );
	font-weight: 600;
	/* Room for the caret sitting over the control. */
	padding-right: 36px;
}

.soc-selectwrap__caret {
	position: absolute;
	top: 50%;
	right: 13px;
	transform: translateY(-50%);
	color: var(--soc-muted);
	font-size: 0.72em;
	/* Clicks belong to the select underneath. */
	pointer-events: none;
}

.soc-selectwrap:hover .soc-selectwrap__caret,
.soc-selectwrap select.soc-select:focus-visible + .soc-selectwrap__caret {
	color: var(--soc-accent);
}

/* Filled pill, matching the reference embed's date-range control. */
select.soc-select--pill {
	appearance: none;
	background: var(--soc-accent) url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6" viewBox="0 0 10 6" fill="none"><path d="M1 1l4 4 4-4" stroke="white" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>') no-repeat right 14px center;
	border: none;
	border-radius: var( --soc-pill, 5px );
	color: #fff;
	font-weight: 600;
	padding-right: 34px;
}

.soc-combobox {
	position: relative;
	min-width: 220px;
}

.soc-combobox__input {
	width: 100%;
	height: 40px;
}

/* Higher specificity than the shared ".soc-btn, .soc-select" border
   shorthand (which comes later in the cascade and would otherwise win). */
input.soc-combobox__input {
	border-color: #ebebeb;
	border-radius: var( --soc-control-radius, 5px );
	/* iOS Safari auto-zooms the page on focus for any input under 16px. */
	font-size: 16px;
}

.soc-combobox__list {
	position: absolute;
	z-index: 20;
	top: calc(100% + 4px);
	left: 0;
	right: 0;
	max-height: 280px;
	overflow-y: auto;
	margin: 0;
	padding: 6px;
	list-style: none;
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-radius: 10px;
	box-shadow: 0 8px 24px rgba(11, 11, 11, 0.12);
}

.soc-combobox__group-label {
	padding: 8px 10px 4px;
	font-size: 0.68rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--soc-muted);
}
.soc-combobox__group-label:not( :first-child ) {
	margin-top: 4px;
	border-top: 1px solid var(--soc-border);
	padding-top: 10px;
}

.soc-combobox__option {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 8px 10px;
	border-radius: 6px;
	font-size: 0.9rem;
	cursor: pointer;
}

.soc-combobox__option.is-active {
	background: var(--soc-plane);
}

.soc-combobox__option.is-selected {
	font-weight: 600;
}

/* The label alone truncates now -- the star beside it is a fixed-size
   control and must never be the thing that gets clipped. */
.soc-combobox__option-label {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/*
 * Starring an account, same idea as Gmail/Slack: an outline star that fills
 * gold once pinned. Sized and inset independently of .soc-combobox__option's
 * own padding so it lines up with the row rather than the row's text baseline.
 */
.soc-combobox__star {
	flex: none;
	display: grid;
	place-items: center;
	width: 22px;
	height: 22px;
	padding: 0;
	border: 0;
	border-radius: 5px;
	background: none;
	color: var(--soc-muted);
	font-size: 13px;
	cursor: pointer;
}

.soc-combobox__star:hover {
	background: var(--soc-surface);
	color: var(--soc-ink-2);
}

.soc-combobox__star.is-pinned,
.soc-combobox__star.is-pinned:hover {
	color: #f5a623;
}

.soc-combobox__empty {
	padding: 8px 10px;
	font-size: 0.9rem;
	color: var(--soc-muted);
}

.soc-btn,
.soc-select {
	font: inherit;
	font-size: 0.9rem;
	color: var(--soc-ink);
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-radius: 10px;
	padding: 9px 14px;
	cursor: pointer;
	min-height: 40px;
}

/* Buttons only — the shared rule above also covers .soc-select, which must
   stay a plain block so the native dropdown arrow renders. */
.soc-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
}

.soc-btn:hover,
.soc-select:hover {
	border-color: var(--soc-axis);
}

.soc-btn:focus-visible,
.soc-select:focus-visible,
.soc-tab:focus-visible {
	outline: 2px solid var(--soc-accent);
	outline-offset: 2px;
}

.soc-btn--primary {
	background: var(--soc-accent);
	border-color: var(--soc-accent);
	border-radius: var( --soc-pill, 5px );
	color: #fff;
	font-weight: 600;
}

.soc-btn--primary:hover {
	background: var(--soc-accent);
	border-color: var(--soc-accent);
	color: #fff;
}

.soc-btn[disabled] {
	opacity: 0.55;
	cursor: default;
}

.soc-btn--icon {
	display: inline-flex;
	align-items: center;
	gap: 8px;
}

/*
 * Anchors wearing a button's clothes. The theme underlines and recolours every
 * `a` inside .page-content (0,2,0), so both need undoing above that weight;
 * inline-flex is what stops an <a> from sitting a few pixels off from the
 * real <button> beside it.
 */
.soc-app a.soc-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	border-radius: var( --soc-pill, 5px );
	color: var(--soc-ink);
	text-decoration: none;
}

.soc-app a.soc-btn--primary,
.soc-app a.soc-btn--primary:hover {
	color: #fff;
	text-decoration: none;
}

/*
 * Account Status / Warm-Up badges. Read-only on purpose — staff set these on
 * the briefing screen, and the customer's copy is a report, so nothing here is
 * shaped like a control.
 */
.soc-statuses {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
}

.soc-status {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	border-radius: var( --soc-pill, 5px );
	padding: 5px 10px;
	font-size: 0.78rem;
	font-weight: 600;
	line-height: 1.2;
	white-space: nowrap;
}

.soc-status.soc-tip {
	cursor: help;
}

.soc-status.soc-tip:focus-visible {
	outline: 2px solid var(--soc-accent);
	outline-offset: 2px;
}

.soc-status--good {
	background: var(--soc-good-bg);
	color: var(--soc-good);
}

.soc-status--warn {
	background: #fdf0d5;
	color: #96591b;
}

/* Blocked and waiting on the customer — the one state that should catch the
   eye before anything else in the toolbar. */
.soc-status--alert {
	background: var(--soc-bad-bg);
	color: var(--soc-bad);
}

.soc-status--idle {
	background: var(--soc-plane);
	color: var(--soc-muted);
}

/* Secondary to the pink Sync now it sits beside — this is a route to settings,
   not something to compete with the account's own data. */
.soc-btn--ghost {
	background: none;
	border-radius: var( --soc-pill, 5px );
	color: var(--soc-muted);
	font-size: 0.85rem;
}

.soc-app a.soc-btn--ghost:hover {
	color: var(--soc-accent);
	border-color: var(--soc-accent);
	text-decoration: none;
}

.soc-notice__action {
	margin: 0 0 var(--soc-gap);
}

/*
 * Archived account. The data stays on screen but blurred — it reads as "this
 * is yours, it is paused" rather than "this is gone", which is the honest
 * message and the one most likely to bring someone back.
 *
 * pointer-events is what actually locks it; the blur alone is decoration and
 * would still let someone tab into charts they are not meant to read.
 */
.soc-locked {
	position: relative;
}

.soc-locked__content {
	filter: blur(7px);
	opacity: 0.55;
	pointer-events: none;
	user-select: none;
	/* Clips the blur's soft edge so it does not bleed past the card. */
	overflow: hidden;
}

/*
 * Placeholder shapes behind a gated tab's lock. Invented geometry, never real
 * numbers blurred — the tab is not fetched at all, so there is nothing to blur.
 */
.soc-skel {
	background: var(--soc-grid, #eceef1);
	border-radius: 4px;
}

.soc-skel--grade {
	width: 26px;
	height: 14px;
	margin-left: auto;
}

.soc-skel--value {
	width: 62%;
	height: 26px;
	margin: 14px auto 10px;
}

.soc-skel--label {
	width: 78%;
	height: 12px;
	margin: 0 auto;
}

.soc-skel--chart {
	height: 240px;
	margin-top: 16px;
}

/*
 * Warm-up ramp, drawn as a fill across the pace badge itself. The badge's own
 * tint stays as the track (the time still to run) and the fill is the days
 * done, so one pill carries pace and progress without a second widget beside
 * it competing with the other badges.
 */
/*
 * No overflow:hidden here on purpose. The fill is a background gradient set
 * inline, which the border-radius clips on its own — clipping with overflow
 * also swallowed the tooltip, which is a ::after sitting above the badge.
 */
.soc-status--ramp {
	position: relative;
	cursor: help;
}

.soc-status__text {
	display: inline-flex;
	align-items: baseline;
	gap: 6px;
}

.soc-status__day {
	font-weight: 600;
	opacity: 0.75;
	font-variant-numeric: tabular-nums;
}

/*
 * Modal for the "no available licences" explanation. Reuses the lock notice
 * panel so the refusal a customer meets here looks like the one they meet on a
 * gated tab, rather than a second visual language for the same idea.
 */
.soc-modal {
	position: fixed;
	inset: 0;
	z-index: 999999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 20px;
	background: rgba(28, 32, 38, 0.55);
}

/*
 * relative, not static: the close button is absolutely positioned, and with the
 * panel static it resolved against the fixed backdrop instead — putting the X
 * in the corner of the screen rather than on the panel it closes.
 */
.soc-modal .soc-locked__notice {
	position: relative;
	transform: none;
	top: auto;
	left: auto;
	width: min(460px, 100%);
	padding-top: 34px;
}

/*
 * Every property is pinned, because the theme styles bare `button` — border,
 * padding, min-width, and a pink `button:hover` — with !important. Declaring
 * only the handful we care about left a bordered chrome box sitting where a
 * quiet glyph belongs, and turned the hover state pink. Same treatment as
 * .soc-sw__x, which is the same control on the upgrade dialog.
 */
.soc-modal .soc-modal__close,
.soc-modal .soc-modal__close:hover,
.soc-modal .soc-modal__close:focus,
.soc-modal .soc-modal__close:active,
.soc-modal .soc-modal__close:focus-visible {
	position: absolute !important;
	top: 8px !important;
	right: 8px !important;
	width: 32px !important;
	height: 32px !important;
	min-width: 0 !important;
	min-height: 0 !important;
	margin: 0 !important;
	padding: 0 !important;
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	border: 0 !important;
	box-shadow: none !important;
	text-shadow: none !important;
	/* The standard radius, not a circle — it is the same control as every
	   other dismiss on the page and should not read as a different one. */
	border-radius: var(--soc-radius) !important;
	background: transparent !important;
	color: var(--soc-muted) !important;
	font-size: 15px !important;
	line-height: 1 !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	cursor: pointer !important;
}

.soc-modal .soc-modal__close:hover,
.soc-modal .soc-modal__close:focus-visible {
	background: var(--soc-plane) !important;
	color: var(--soc-ink) !important;
}

/* Crown on the lock panel's upgrade button, matching the sidebar card. */
.soc-locked__notice .soc-btn__icon {
	display: inline-flex;
	align-items: center;
	margin-left: 8px;
	font-size: 0.85em;
	line-height: 1;
}

/* Padlock on a tab the current plan does not open. */
.soc-tab__lock {
	margin-left: 6px;
	font-size: 0.75em;
	opacity: 0.6;
}

.soc-locked__notice {
	position: absolute;
	top: 40px;
	left: 50%;
	transform: translateX(-50%);
	z-index: 5;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 10px;
	width: min(460px, calc(100% - 32px));
	padding: 30px 26px;
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-radius: var(--soc-radius);
	box-shadow: 0 12px 40px rgba(34, 41, 47, 0.18);
}

.soc-locked__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	border-radius: 50%;
	background: var(--soc-plane);
	color: var(--soc-accent);
	font-size: 19px;
}

.soc-locked__title {
	margin: 0;
	font-size: 1.2rem;
	font-weight: 600;
	color: var(--soc-ink);
}

.soc-locked__body {
	margin: 0;
	color: var(--soc-muted);
	font-size: 0.92rem;
	line-height: 1.5;
}

.soc-locked__notice .soc-btn--primary {
	margin-top: 6px;
}

@media (max-width: 640px) {
	.soc-locked__notice {
		top: 20px;
		padding: 24px 18px;
	}
}

.soc-tabs {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 4px;
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-radius: var(--soc-radius);
	padding: 6px;
	margin-bottom: var(--soc-gap);
}

@media (max-width: 640px) {
	.soc-tabs {
		flex-wrap: nowrap;
		justify-content: flex-start;
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}

	.soc-tab {
		flex: none;
	}
}

.soc-tab {
	font: inherit;
	font-size: 0.94rem;
	font-weight: 500;
	color: var(--soc-ink-2);
	background: none;
	border: 0;
	/* Must track the selected tab below, or the hover fill is a different
	   shape from the tab it is previewing — obvious at a pill brand radius. */
	border-radius: var( --soc-pill, 5px );
	padding: 9px 16px;
	cursor: pointer;
	min-height: 40px;
}

.soc-tab:hover {
	background: var(--soc-accent);
	color: #fff;
}

.soc-tab[aria-selected="true"] {
	background: var(--soc-accent);
	border-radius: var( --soc-pill, 5px );
	color: #fff;
	font-weight: 700;
}

.soc-tab[aria-selected="true"]:hover {
	background: var(--soc-accent);
	color: #fff;
}

/* ------------------------------------------------------------- Stat tiles */

.soc-tiles {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: var(--soc-gap);
	margin-bottom: var(--soc-gap);
}

@media (max-width: 1024px) {
	.soc-tiles {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (max-width: 640px) {
	/*
	 * One column on a phone. minmax(0,1fr) rather than a bare 1fr so a long
	 * value can never widen the track past the screen.
	 */
	.soc-tiles {
		grid-template-columns: minmax(0, 1fr);
	}

	/*
	 * Audit stays one per row. Each of these carries a grade, a comparison line
	 * and an explanatory note — side by side on a phone that is a wall of text.
	 */
	.soc-tiles--audit,
	.soc-tiles--fit {
		grid-template-columns: minmax(0, 1fr);
	}

}

.soc-tile {
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-radius: var(--soc-radius);
	padding: 22px 18px;
	text-align: center;
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
}

.soc-tile__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	margin-bottom: 10px;
	font-size: 16px;
	line-height: 1;
}

.soc-tile__value {
	font-size: 1.98rem;
	font-weight: 600;
	line-height: 1.1;
	margin-bottom: 6px;
	word-break: break-word;
}

.soc-tile__label {
	color: var(--soc-ink-2);
	font-size: 0.96rem;
}

/*
 * The tooltip is a ::after bubble fed by data-tip. Hover *and* :focus-visible
 * both open it so it is reachable by keyboard, and tapping it on a phone
 * focuses the button, which is the only way this gets seen on touch — the
 * native `title` popup it replaced showed up on neither.
 */
button.soc-tile__info {
	position: absolute;
	top: 12px;
	left: 12px;
	width: 18px;
	height: 18px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: 50%;
	border: 0;
	background: none;
	/* Light on purpose — it is a hint marker, not something to draw the eye
	   away from the number it sits beside. */
	color: #d2d2d9;
	font-size: 14px;
	line-height: 1;
	cursor: help;
	padding: 0;
}

/*
 * The theme paints a solid `background: #cc3366; color: #fff` onto *every*
 * button:hover/:focus, which turned this icon into a pink blob. Ours is a bare
 * glyph, so the background has to be knocked back out on both states.
 */
button.soc-tile__info:hover,
button.soc-tile__info:focus,
button.soc-tile__info:focus-visible {
	background: none;
	color: #eda4cb;
}

/*
 * Shared tooltip. Any element carrying .soc-tip and a data-tip attribute gets
 * one — the tile info icons and the status badges both use it, so there is a
 * single place to change how an explanation looks.
 *
 * Opens on hover *and* focus: focus is what makes it reachable by keyboard, and
 * on a phone a tap focuses, which is the only way these are seen on touch.
 */
.soc-tip {
	position: relative;
}

/*
 * Anchored to the right, not the left.
 *
 * These sit at the top-right of a tile and the panel is far wider than the
 * button. Growing rightwards from a button already at the tile's edge pushed
 * the panel past the tile, out of the grid and past the viewport — an
 * absolutely positioned box still counts towards scrollable overflow, so the
 * whole page gained a horizontal scrollbar. Growing leftwards keeps it inside:
 * overflow to the left of the origin does not create a scrollbar.
 */
.soc-tile__info.soc-tip::after {
	left: auto;
	right: 0;
	max-width: min( 240px, calc( 100vw - 24px ) );
}

.soc-tile__info.soc-tip::before {
	left: auto;
	right: 7px;
}

.soc-tip::after {
	content: attr(data-tip);
	position: absolute;
	bottom: calc(100% + 9px);
	left: 0;
	z-index: 20;
	width: max-content;
	max-width: 240px;
	padding: 7px 10px;
	/* A multi-line panel, not a pill: at a full pill radius the corners eat
	   into the text. Matches the chart tooltip, which is fixed at 5px. */
	border-radius: var( --soc-control-radius, 5px );
	background: #333333;
	color: #fff;
	font-size: 0.75rem;
	font-weight: 400;
	line-height: 1.4;
	text-align: left;
	white-space: normal;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.12s ease;
	pointer-events: none;
}

.soc-tip::before {
	content: '';
	position: absolute;
	bottom: calc(100% + 4px);
	left: 7px;
	z-index: 21;
	border: 5px solid transparent;
	border-top-color: #333333;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.12s ease;
	pointer-events: none;
}

.soc-tip:hover::after,
.soc-tip:hover::before,
.soc-tip:focus::after,
.soc-tip:focus::before {
	opacity: 1;
	visibility: visible;
}

/*
 * Opens downward instead. For anything sitting in the top toolbar an upward
 * bubble lands under the theme's breadcrumb bar, which is opaque and paints
 * over it — below there is the whole page.
 */
.soc-tip--below::after {
	bottom: auto;
	top: calc(100% + 9px);
}

.soc-tip--below::before {
	bottom: auto;
	top: calc(100% + 4px);
	border-top-color: transparent;
	border-bottom-color: #333333;
}

/*
 * Grades are chips everywhere they appear — audit tiles and the sources list
 * share one box spec and one colour set, so a B means the same thing and looks
 * the same wherever it lands. The box lives here; the colours are the
 * .soc-grade--* rules below, which are the single source of truth for them.
 */
.soc-tile__grade,
.soc-gradechip {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 34px;
	padding: 3px 8px;
	border-radius: var(--soc-pill, 5px);
	font-size: 0.78rem;
	font-weight: 700;
	line-height: 1.35;
	letter-spacing: 0.01em;
}

.soc-tile__grade {
	position: absolute;
	top: 12px;
	right: 14px;
}

.soc-grade--a\+\+,
.soc-grade--a {
	background: var(--soc-good-bg);
	color: var(--soc-good);
}

.soc-grade--b {
	background: #f1f0f6;
	color: var(--soc-ink-2);
}

/* C and D both read as red: below standard is a problem either way. */
.soc-grade--c,
.soc-grade--d {
	background: var(--soc-bad-bg);
	color: var(--soc-bad);
}

/*
 * Metrics with no published standard say so rather than showing a letter. The
 * label is a whole word where the others are one or two characters, so it drops
 * to the muted, unbolded treatment — it must read as an absence of a grade, not
 * as a bad one.
 */
.soc-grade--none {
	color: var(--soc-muted);
	font-size: 0.72rem;
	font-weight: 500;
	letter-spacing: 0.01em;
}

.soc-tile__note {
	margin-top: 10px;
	font-size: 0.75rem;
	line-height: 1.45;
	color: var(--soc-muted);
}

/* The "graded against …" line is context, not an alert. */
.soc-notice--quiet {
	background: none;
	border: 0;
	padding: 0;
	color: var(--soc-muted);
	font-size: 0.82rem;
}

/* As a closing footnote it needs air above it, not below. */
.soc-notice--footnote {
	margin: 18px 0 0;
}

.soc-tile__compare {
	font-size: 0.85rem;
	font-weight: 600;
	margin-top: 8px;
}

.soc-tile__compare-note {
	color: var(--soc-muted);
	font-size: 0.78rem;
	font-weight: 400;
}

.soc-bench {
	display: flex;
	justify-content: center;
	gap: 18px;
	margin-top: 12px;
	padding-top: 10px;
	border-top: 1px solid var(--soc-border);
	font-size: 0.78rem;
	color: var(--soc-muted);
}

/* Cohort tiles carry one sentence, not a min/avg/max row, so it spans. */
.soc-bench__note {
	flex: 1;
	text-align: center;
}

.soc-bench b {
	display: block;
	color: var(--soc-ink-2);
	font-variant-numeric: tabular-nums;
}

/* Deltas always pair colour with an arrow glyph, never colour alone. */

.soc-delta--up {
	color: var(--soc-good);
}

.soc-delta--down {
	color: var(--soc-bad);
}

.soc-delta--flat {
	color: var(--soc-muted);
}

.soc-pill {
	display: inline-block;
	border-radius: 6px;
	padding: 1px 6px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.soc-pill--up {
	background: var(--soc-good-bg);
	color: var(--soc-good);
}

.soc-pill--down {
	background: var(--soc-bad-bg);
	color: var(--soc-bad);
}

/* ----------------------------------------------------------------- Charts */

.soc-charts {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--soc-gap);
	margin-bottom: var(--soc-gap);
}

@media (max-width: 640px) {
	.soc-charts {
		grid-template-columns: 1fr;
	}
}

.soc-chart {
	background: var(--soc-surface);
	border: 0;
	border-radius: var(--soc-radius);
	/* A soft drop shadow instead of a hairline border: the chart cards sit on a
	   tinted page, and a border competes with the gridlines inside them. */
	box-shadow: 0 4px 24px rgba(34, 41, 47, 0.1);
	padding: 18px 21px 12px;
	min-width: 0;
	position: relative;

	/* Overridden per chart in JS; this is the fallback for any chart that does
	   not name a metric. */
	--soc-chart-line: var(--soc-series-1);
	--soc-chart-soft: #c7c8f9;
}

.soc-chart__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
	margin-bottom: 12px;
}

.soc-chart__title {
	color: #2a2e30;
	font-size: 18px;
	font-weight: 500;
	margin: 0;
}

.soc-chart__figure {
	position: relative;
	margin: 0;
}

.soc-chart__svg {
	display: block;
	width: 100%;
	height: auto;
	overflow: visible;
}

.soc-chart__empty {
	color: var(--soc-muted);
	font-size: 0.88rem;
	padding: 28px 4px;
	text-align: center;
}

.soc-grid-line {
	stroke: #ebe9f1;
	stroke-width: 1;
}

.soc-axis-line {
	stroke: var(--soc-axis);
	stroke-width: 1;
}

.soc-tick {
	fill: #b9b9c3;
	font-size: 12px;
	font-weight: 400;
}

/* Month boundaries carry the weight so the axis has an anchor to read from. */
.soc-tick--boundary {
	fill: #6e6b7b;
	font-weight: 600;
}

.soc-line {
	fill: none;
	stroke: var(--soc-chart-line);
	stroke-width: 4;
	stroke-linejoin: round;
	stroke-linecap: butt;
}

.soc-line--projected {
	stroke: var(--soc-series-2);
	stroke-dasharray: 5 4;
}

.soc-area {
	opacity: 1;
}

/* Gradient stops live here rather than on the element: stop-color set as an
   attribute would not resolve the custom property. */
.soc-area__from {
	stop-color: var(--soc-chart-line);
	stop-opacity: 0.42;
}

.soc-area__to {
	stop-color: var(--soc-chart-soft);
	stop-opacity: 0.25;
}

.soc-bar {
	fill: var(--soc-chart-line);
}

.soc-bar--negative {
	fill: var(--soc-series-2);
}

.soc-dot {
	fill: var(--soc-chart-line);
	stroke: var(--soc-surface);
	stroke-width: 2;
}

.soc-crosshair {
	stroke: #b6b6b6;
	stroke-width: 1;
	stroke-dasharray: 3;
}

.soc-hit {
	fill: transparent;
	cursor: crosshair;
}

.soc-tooltip {
	position: absolute;
	z-index: 20;
	pointer-events: none;
	background: rgba(255, 255, 255, 0.96);
	border: 1px solid #e3e3e3;
	border-radius: 5px;
	box-shadow: 2px 2px 6px -4px #999;
	padding: 8px 10px;
	font-size: 14px;
	white-space: nowrap;
	transform: translate(-50%, -100%);
	color: #6e6b7b;
}

.soc-tooltip__date {
	color: #6e6b7b;
	font-weight: 600;
	margin-bottom: 2px;
}

.soc-tooltip__value {
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.soc-tooltip[hidden] {
	display: none;
}

.soc-legend {
	display: flex;
	gap: 14px;
	flex-wrap: wrap;
	margin: 10px 0 0;
	padding: 0;
	list-style: none;
	font-size: 0.83rem;
	color: var(--soc-ink-2);
}

.soc-legend li {
	display: flex;
	align-items: center;
	gap: 6px;
}

.soc-legend__swatch {
	width: 10px;
	height: 10px;
	border-radius: 3px;
	flex: none;
}

/*
 * The data table behind each chart stays available to keyboard and screen
 * reader users, but its toggle is off-canvas until focused so the chart card
 * reads as just the chart.
 */
button.soc-chart__toggle {
	font: inherit;
	font-size: 0.8rem;
	color: var(--soc-muted);
	background: none;
	border: 0;
	border-radius: 0;
	padding: 4px 0;
	cursor: pointer;
	text-decoration: underline;
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

button.soc-chart__toggle:focus,
button.soc-chart__toggle:focus-visible,
button.soc-chart__toggle[aria-expanded="true"] {
	position: static;
	width: auto;
	height: auto;
	overflow: visible;
	clip-path: none;
}

/*
 * Same theme button:hover/:focus fill to undo — this one is a plain text link.
 * The theme drops the underline on hover too, so it has to be restated: colour
 * is the only thing that should change between states.
 */
button.soc-chart__toggle:hover,
button.soc-chart__toggle:focus {
	background: none;
	color: var(--soc-accent);
	text-decoration: underline;
}

.soc-chart__note {
	color: var(--soc-muted);
	font-size: 0.8rem;
	margin: 8px 0 0;
}

/* ----------------------------------------------------------------- Tables */

.soc-table-wrap {
	overflow-x: auto;
}

.soc-table {
	width: 100%;
	/*
	 * Separate, not collapse. Safari has a long-standing rendering bug where
	 * border-collapse merges a 0px edge against a 1px edge (exactly our
	 * case -- every side is 0 except border-bottom) into a faint hairline
	 * that the computed styles don't show, because it is a paint artifact,
	 * not a cascade problem -- Chrome renders the identical computed CSS
	 * correctly. Separate with zero spacing paints each cell's own border
	 * with no shared-edge computation, so there is nothing for that bug to
	 * act on, and it looks identical everywhere borders are already
	 * uniform (all of our tables).
	 */
	border-collapse: separate;
	border-spacing: 0;
	font-size: 0.9rem;
}

.soc-table caption {
	text-align: left;
	font-weight: 600;
	padding-bottom: 10px;
}

.soc-table th,
.soc-table td {
	text-align: right;
	/* Rows carry inline badges (delta pills, weekday chips) that sit almost on
	   the row border at tighter padding. */
	padding: 15px 14px;
	/*
	 * Two theme rules put a border on every table cell: reset.css's
	 * `table td, table th { border: 1px solid ... }` (plain, loses to any
	 * more specific selector) and account.css's `table td, table th
	 * { border: 1px solid #E4E7EB !important; }` (the one actually
	 * winning here -- !important beats specificity outright, so nothing
	 * short of !important on our side can clear it). Zero all four sides,
	 * then re-add only the row divider.
	 */
	border: 0 !important;
	border-bottom: 1px solid var(--soc-border) !important;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.soc-table tbody th,
.soc-table tbody td {
	line-height: 1.5;
	/* Taller than the header on purpose -- header stays as-is, body rows
	   get more breathing room. */
	padding-top: 22px;
	padding-bottom: 22px;
}

.soc-table th:first-child,
.soc-table td:first-child {
	text-align: left;
	font-variant-numeric: normal;
}

.soc-table thead th {
	background: var(--soc-plane);
	color: var(--soc-muted);
	font-size: 0.76rem;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-weight: 600;
}

/*
 * The theme zebra-stripes every table via
 * `table tbody > tr:nth-child(2n+1) > td` (0,1,3). Ours wants a tinted header
 * over plain white body rows, so the override has to out-specify that on the
 * cells themselves — setting it on the `tr` is not enough, the striped `td`
 * paints on top.
 */
.soc-app table.soc-table tbody > tr > th,
.soc-app table.soc-table tbody > tr > td {
	background-color: var(--soc-surface);
}

.soc-app table.soc-table tbody > tr:hover > th,
.soc-app table.soc-table tbody > tr:hover > td {
	background-color: var(--soc-plane);
}

.soc-table__date {
	font-weight: 600;
	color: var(--soc-ink);
}

.soc-table__weekday {
	display: inline-block;
	background: var(--soc-plane);
	color: var(--soc-muted);
	font-size: 0.72rem;
	font-weight: 600;
	padding: 1px 7px;
	border-radius: var( --soc-pill, 5px );
}

/* ------------------------------------------------------------------ Posts */

/* 320px: wider cards, ~4 per row on a standard desktop viewport.
   Still fully fluid -- auto-fill just packs fewer, roomier columns per row. */
.soc-posts {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
	gap: var(--soc-gap);
}

.soc-post {
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	border-radius: var(--soc-radius);
	overflow: hidden;
	display: flex;
	flex-direction: column;
}

.soc-post__thumb {
	aspect-ratio: 1;
	width: 100%;
	object-fit: cover;
	background: var(--soc-plane);
	display: block;
}

/* Stale/expired image link: the <img> has no src (removed on error, see
   attachMediaPreview) so its own background here is all that shows --
   .soc-post__broken-icon below is the only other thing layered on top,
   never the browser's own broken-image icon. */
.soc-post__broken-icon {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--soc-muted);
	font-size: 26px;
	pointer-events: none;
}

/* Positioning context for the hover-play video overlay below. */
.soc-post__media {
	position: relative;
}

.soc-post__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Purely visual -- clicks fall through to the <a> wrapping this card's
	   media, which is what keeps a click going to Instagram whether or not
	   a preview happens to be playing at that moment. */
	pointer-events: none;
}

/* Deliberately NOT pointer-events:none -- this is the one control on the
   hover preview that has to catch its own click rather than falling
   through to the Instagram link underneath. */
.soc-post__sound {
	position: absolute;
	right: 8px;
	bottom: 8px;
	width: 26px;
	height: 26px;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: 999px;
	background: rgba( 0, 0, 0, 0.55 );
	color: #fff;
	font-size: 12px;
	cursor: pointer;
	backdrop-filter: blur( 2px );
}
.soc-post__sound:hover,
.soc-post__sound:focus-visible {
	background: rgba( 0, 0, 0, 0.75 );
	outline: none;
}
.soc-post__sound.is-unmuted {
	color: var(--soc-accent);
}

/* Chevrons only appear on hover -- same reasoning as the sound button not
   sitting in the DOM until hover, just via opacity here since these are
   always-present (an album is swipeable any time, not only during a
   hover-triggered preview). */
.soc-post__carousel-nav {
	position: absolute;
	top: 50%;
	transform: translateY( -50% );
	width: 28px;
	height: 28px;
	padding: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: 999px;
	background: rgba( 0, 0, 0, 0.55 );
	color: #fff;
	font-size: 13px;
	line-height: 1;
	cursor: pointer;
	backdrop-filter: blur( 2px );
	opacity: 0;
	transition: opacity 0.15s ease;
}
/* The chevron glyph itself carries its own leading inside the icon font's
   em-square -- centering the button's line box (above) isn't enough, the
   <i> needs line-height: 1 too or the glyph still sits high inside it. */
.soc-post__carousel-nav i {
	line-height: 1;
}
.soc-post__media--has-carousel:hover .soc-post__carousel-nav,
.soc-post__carousel-nav:focus-visible {
	opacity: 1;
}
.soc-post__carousel-nav:hover,
.soc-post__carousel-nav:focus-visible {
	background: rgba( 0, 0, 0, 0.75 );
	outline: none;
}
.soc-post__carousel-nav--prev {
	left: 8px;
}
.soc-post__carousel-nav--next {
	right: 8px;
}

.soc-post__carousel-dots {
	position: absolute;
	left: 50%;
	bottom: 8px;
	transform: translateX( -50% );
	display: flex;
	align-items: center;
	gap: 4px;
}
.soc-post__carousel-dot {
	width: 5px;
	height: 5px;
	border-radius: 999px;
	background: rgba( 255, 255, 255, 0.55 );
}
.soc-post__carousel-dot.is-active {
	background: #fff;
}

.soc-post__body {
	padding: 12px 14px 14px;
	display: flex;
	flex-direction: column;
	gap: 8px;
	flex: 1;
}

.soc-post__stats {
	display: flex;
	align-items: center;
	/* Two groups now (engagement left, reel-only watch metrics right) --
	   space-between pins them to opposite edges instead of bunching all
	   six numbers together in the middle. */
	justify-content: space-between;
	flex-wrap: nowrap;
	font-size: 13px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.soc-post__stats-left,
.soc-post__stats-right {
	display: flex;
	align-items: center;
	flex-wrap: nowrap;
	gap: clamp( 3px, 1vw, 8px );
	min-width: 0;
}

/*
 * Same reasoning as .soc-tile__info.soc-tip's own left/right override
 * above: the right-hand stats (views, watch times) sit close to the card's
 * right edge, and a bubble that grows rightward from there overflows the
 * card and pushes the grid into horizontal scroll. Anchor those rightward
 * instead so they grow back in over the card.
 */
.soc-post__stats-right .soc-tip::after {
	left: auto;
	right: 0;
	max-width: min( 240px, calc( 100vw - 24px ) );
}

.soc-post__stats-right .soc-tip::before {
	left: auto;
	right: 7px;
}

.soc-post__stat {
	display: flex;
	align-items: center;
	gap: 6px;
	color: var(--soc-ink-2);
	font-size: 15px;
}

.soc-post__date {
	color: var(--soc-muted);
	font-size: 14px;
	font-weight: 500;
}

/* Hooks reuse the Posts tab's own stats/date rows, but sit inside a
   tight-gap flex column (.soc-taglist__item) rather than the Posts
   card's own padded body -- a little breathing room so they don't run
   straight into the why-it-works line above them. */
.soc-taglist--themes .soc-post__stats {
	margin-top: 6px;
	/* Posts tab keeps left/right pinned to opposite edges because that
	   card is narrow (grid column). This card runs the full width of the
	   tab, so the same split just leaves a huge gap in the middle --
	   group everything together on the left instead. Posts tab itself is
	   untouched; this only applies inside the hooks list. */
	justify-content: flex-start;
	gap: 18px;
}
.soc-hook-date {
	margin-top: 2px;
	font-size: 12px;
}

.soc-post__caption {
	color: var(--soc-ink-2);
	font-size: 0.85rem;
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Post-type chips. One colour per Instagram format so the grid can be
   scanned by type at a glance, instead of six identical grey outlines.
   These same four colours are the scheduler's content-type language. */
.soc-post__badge {
	align-self: flex-start;
	display: inline-flex;
	align-items: center;
	font-size: 0.72rem;
	font-weight: 600;
	line-height: 1;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	border: 0;
	border-radius: var( --soc-pill, 5px );
	/* Vertical padding does the centring: line-height:1 plus equal padding
	   sits the caps optically centred, which a bare 1px never did. */
	padding: 5px 8px;
	background: var(--soc-plane, #f6f6f8);
	color: var(--soc-muted);
}

.soc-post__badge--reel { background: #f3e8fd; color: #7c3aed; }
.soc-post__badge--video { background: #e1f0fd; color: #1c6dc4; }
.soc-post__badge--photo { background: #e3f8ea; color: #1e7a4d; }
.soc-post__badge--album { background: #fdedd8; color: #9a6215; }

/* Chips are <button>s that filter the grid by type. The theme's global
   button:hover paints white-on-#cc3366 (a red that is not our pink), so
   background AND color are pinned on every state — the recurring
   collision documented throughout this plugin. */
button.soc-post__badge {
	cursor: pointer;
	font-family: inherit;
	min-height: 0;
	box-shadow: none;
	transition: background .15s ease, color .15s ease;
}

/* Hover only. No active/selected styling: while a filter is on, every
   visible chip is that same type, so styling "active" turned the whole
   grid pink and destroyed the per-type colour coding that is the point
   of these chips. The tooltip still says a second tap clears the filter. */
button.soc-post__badge:hover,
button.soc-post__badge:focus-visible {
	background: var(--soc-accent, #d13684);
	color: #fff;
	box-shadow: none;
	filter: none;
}

/* How the post did vs. this account's normal — sits inline with the
   like/comment/ER stats. */
/* Exactly the header delta pill: same geometry, same two colour pairs, so
   "up is green / down is red" reads identically everywhere in the app. */
/* Own row beneath the stats — self-contained, so it cannot be pushed off
   the card by however wide the counts happen to be. */
.soc-post__perf {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	flex: 0 0 auto;
	margin-left: auto;
	font-size: inherit;
	padding: 1px 6px;
	border-radius: 6px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
	cursor: default;
}

.soc-post__perf--hot,
.soc-post__perf--above {
	background: var(--soc-good-bg);
	color: var(--soc-good);
}

.soc-post__perf--below {
	background: var(--soc-bad-bg);
	color: var(--soc-bad);
}

/* Neither good nor bad — "normal" did fine, "settling" is not knowable
   yet. Both stay neutral so green and red keep their meaning. */
.soc-post__perf--normal,
.soc-post__perf--settling,
.soc-post__perf--hidden {
	background: var(--soc-plane, #f6f6f8);
	color: var(--soc-muted, #767570);
}

/* Stat icons. The heart is a proper red — it was inheriting the muted
   text colour and reading as a dead glyph. */
.soc-post__icon {
	display: inline-flex;
	align-items: center;
	font-size: 0.92em;
	line-height: 1;
}

.soc-post__icon--like { color: #e0245e; }
.soc-post__icon--comment { color: #6b7fd7; }
.soc-post__icon--er { color: #f5a623; }
.soc-post__icon--views { color: #14b8a6; }
.soc-post__icon--watch { color: #9b6bd1; }
.soc-post__icon--totalwatch { color: #767570; }

/* Type chip left, performance verdict right (its own margin-left:auto
   already pushes it there), one row at the bottom of the card. Font-size
   set explicitly: .soc-post__perf uses font-size:inherit, which used to
   come from .soc-post__stats' clamped small size -- without it here the
   badge fell back to the ambient default and rendered noticeably bigger. */
.soc-post__footer {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: clamp( 0.68rem, 0.82vw, 0.88rem );
	/* Pins it to the bottom of the card regardless of caption length --
	   margin-top:auto on a column-flex child eats all the free space
	   above it instead of the footer just following wherever the text
	   happens to end. A short caption gets a bigger gap above the chips,
	   not chips that float up to meet it. */
	margin-top: auto;
}

/* The performance badge sits at the footer's right edge (margin-left:auto
   pushes it there, see .soc-post__perf below) -- same overflow risk as
   the right-hand stats, so its tooltip gets the same right anchor. */
.soc-post__footer .soc-tip::after {
	left: auto;
	right: 0;
	max-width: min( 240px, calc( 100vw - 24px ) );
}
.soc-post__footer .soc-tip::before {
	left: auto;
	right: 7px;
}

/* align-self:flex-start on .soc-post__badge meant something different
   when it sat directly in the (column) body -- horizontal hug, not
   vertical. Inside this (row) footer that same property would now pin
   it to the top instead of centring it beside the performance badge,
   so it's overridden here explicitly. */
.soc-post__footer .soc-post__badge {
	align-self: center;
}

/* --------------------------------------------------------------- A11y bits */

.soc-sr {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

@media (forced-colors: active) {
	.soc-line,
	.soc-bar,
	.soc-dot {
		forced-color-adjust: none;
	}

	.soc-card,
	.soc-tile,
	.soc-chart {
		border: 1px solid CanvasText;
	}
}

@media (max-width: 640px) {
	.soc-summary-grid {
		flex-wrap: wrap;
	}

	.soc-profile {
		gap: 14px;
	}

	.soc-profile__avatar {
		width: 64px;
		height: 64px;
	}

	.soc-profile__avatar-col {
		gap: 6px;
	}

	.soc-app a.soc-profile__ig-link {
		font-size: 26px;
	}

	.soc-score {
		/* Full-width track on phones — the card's own padding is enough room
		   for a bubble sitting at either end. */
		padding: 0;
	}

	/* Icons only, so the search box, settings and Sync now stay on one row.
	   Both keep their aria-label, so nothing is lost to a screen reader. */
	.soc-btn__label {
		display: none;
	}

	/*
	 * Account picker on its own row, then the badges and the controls sharing
	 * the next one. Giving the badges the full width used to push the buttons
	 * onto a third row of their own, which wasted a whole line on two icons.
	 * The badges take the slack and wrap inside themselves; the buttons keep
	 * their natural width on the right.
	 */
	.soc-toolbar__spacer {
		display: none;
	}

	.soc-toolbar .soc-combobox {
		width: 100%;
	}

	/*
	 * flex-basis 0, not auto. The toolbar wraps, and a wrapping flex container
	 * moves an item to the next line when it does not fit at its *base* size —
	 * it never gets the chance to shrink. With a base of zero the badges and
	 * the buttons always share the line, and the badges take whatever is left.
	 */
	.soc-toolbar .soc-statuses {
		flex: 1 1 0;
		min-width: 0;
	}

	/*
	 * Icon-only, matching .soc-btn__label just above: the pill shrinks to a
	 * plain circular glyph and the words move to its tooltip/aria-label
	 * (always present now -- see statusBadges() in dashboard.js) instead of
	 * text that wrapped "Needs Onboarding" and "Warm-Up: Not Started" onto
	 * two lines above the toolbar's buttons.
	 */
	.soc-status__label,
	.soc-status__text {
		display: none;
	}

	.soc-status__icon {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		line-height: 1;
		font-size: 0.85rem;
	}

	.soc-status {
		width: 30px;
		height: 30px;
		padding: 0;
		gap: 0;
		justify-content: center;
		/* Rounded square, not a circle -- and .soc-status__icon above centers
		   the glyph on both axes, not just horizontally via this row's own
		   align-items:center (an FA icon's line-height leaves it a hair off
		   the visual middle otherwise). */
		border-radius: 6px;
	}

	.soc-toolbar__actions {
		flex: 0 0 auto;
		justify-content: flex-end;
		margin-left: auto;
	}

	.soc-app a.soc-btn--ghost,
	.soc-toolbar .soc-btn--primary {
		padding: 9px 12px;
		font-size: 1rem;
	}

	.soc-profile__identity {
		flex-basis: 150px;
	}

	.soc-profile__summary {
		flex-basis: 100%;
	}

	.soc-profile__username {
		font-size: 1.4rem;
	}

	.soc-tile__value {
		font-size: 1.6rem;
	}
}

/* --------------------------------------------------------------- Insights */

.soc-insight {
	margin-bottom: var(--soc-gap);
}

.soc-insight__title {
	color: #2a2e30;
	font-size: 18px;
	font-weight: 500;
	margin: 0 0 4px;
}

.soc-insight__note {
	color: var(--soc-muted);
	font-size: 0.85rem;
	margin: 0 0 14px;
	max-width: 60ch;
}

/*
 * Weekday × 3-hour grid. Scrolls inside its own box rather than widening the
 * page, so the eight columns survive a phone.
 */
.soc-heat-wrap {
	overflow-x: auto;
}

.soc-heat {
	display: grid;
	grid-template-columns: auto repeat(8, minmax(44px, 1fr));
	gap: 4px;
	min-width: 420px;
}

.soc-heat__head,
.soc-heat__row-label {
	color: var(--soc-muted);
	font-size: 0.72rem;
	font-weight: 600;
	display: flex;
	align-items: center;
}

.soc-heat__head {
	justify-content: center;
}

.soc-heat__row-label {
	padding-right: 8px;
}

.soc-heat__cell {
	background: var(--soc-accent);
	border-radius: var( --soc-pill, 5px );
	height: 30px;
	cursor: default;
}

/* Same right-edge-anchor pattern as .soc-tile__info.soc-tip -- the last
   couple of columns sit at the grid's own right edge, and the default
   .soc-tip::after (left:0, growing rightward) would overflow past it. */
.soc-heat__cell--right.soc-tip::after {
	left: auto;
	right: 0;
	max-width: min( 240px, calc( 100vw - 24px ) );
}
.soc-heat__cell--right.soc-tip::before {
	left: auto;
	right: 7px;
}

/* A slot never posted in is not a bad slot — it is an unknown one. */
.soc-heat__cell.is-empty {
	background: var(--soc-plane, #f4f4f6);
	opacity: 1;
}

/* The real start date under a delta, when tracking does not reach back as far
   as the selected range. Quiet: it qualifies the figure, it is not the figure. */
.soc-summary__since {
	color: var(--soc-muted);
	font-size: 0.72rem;
	margin-top: 2px;
}

.soc-taglist {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.soc-taglist__item {
	background: var(--soc-plane, #f4f4f6);
	border-radius: var( --soc-control-radius, 5px );
	padding: 8px 12px;
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.soc-taglist__tag {
	font-weight: 600;
	font-size: 0.88rem;
}

.soc-taglist__meta {
	color: var(--soc-muted);
	font-size: 0.75rem;
}

/* Themes carry a full example sentence, not a short tag -- one per row
   reads far better than the hashtag list's wrapping tag-cloud layout. */
.soc-taglist--themes {
	flex-direction: column;
	gap: 6px;
}
.soc-taglist--themes .soc-taglist__item {
	flex-direction: column;
	align-items: stretch;
	/* Overrides the later unconditional ".soc-taglist__item { padding: 0; }"
	   rule below, written for the click-target chip variant where an inner
	   <a class="soc-taglist__link"> carries its own padding instead --
	   themes have no such inner link, so without this the row goes flush
	   to the card edge. Higher specificity (two classes) wins regardless
	   of source order, but kept after the flex rules for readability. */
	padding: 10px 12px;
}
.soc-taglist--themes .soc-taglist__tag,
.soc-taglist--themes .soc-taglist__meta {
	display: inline-block;
}
.soc-taglist--themes .soc-taglist__row {
	display: flex;
	align-items: center;
	justify-content: flex-start;
	gap: 8px;
}
.soc-taglist--themes .soc-taglist__meta {
	margin-left: auto;
}

/* Only the thumbnail and the hook title link out to the post -- the type
   badge, the multiplier, and the why-it-works line stay plain text, not
   part of the click target (see hookList() in dashboard.js). */
.soc-app a.soc-hook-link {
	color: inherit;
	text-decoration: none;
	font-weight: 600;
	font-size: 14px;
}
.soc-app a.soc-hook-link:hover {
	text-decoration: underline;
}
.soc-app a.soc-hook-thumb-link {
	display: block;
	flex: 0 0 auto;
}
/* Scoped to the hooks list -- .soc-post__perf's own font-size:inherit is
   correct on the Posts tab card it was built for, just too large sitting
   next to the smaller type/count badges in this list. */
.soc-taglist--themes .soc-post__perf {
	font-size: 14px;
}
/* This badge sits at the row's far right (margin-left:auto), so the
   default .soc-tip::after left:0 grows the tooltip off the right edge --
   same fix .soc-tile__info.soc-tip already uses above for the same
   right-edge-anchored-element problem. */
.soc-taglist--themes .soc-post__perf.soc-tip::after {
	left: auto;
	right: 0;
	max-width: min( 240px, calc( 100vw - 24px ) );
}
.soc-taglist--themes .soc-post__perf.soc-tip::before {
	left: auto;
	right: 7px;
}
.soc-hook-thumb {
	flex: 0 0 auto;
	width: 36px;
	height: 36px;
	border-radius: 6px;
	object-fit: cover;
	background: var(--soc-grid, #e9e9ec);
}

/* Type badge: actionable types (question/objection/request/purchase_intent)
   get a colored accent so they visually stand out from praise/other, which
   is the whole point of tagging them -- see comment_system_prompt() on the
   server for why those are ranked above equal-count praise. */
.soc-theme-type {
	flex: 0 0 auto;
	font-size: 0.68rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	padding: 2px 7px;
	border-radius: 6px;
	background: rgba(118, 117, 112, 0.14);
	color: var(--soc-muted);
}
.soc-theme-type--question         { background: rgba(37, 99, 235, 0.14); color: #2563eb; }
.soc-theme-type--objection        { background: rgba(192, 52, 31, 0.14); color: var(--soc-bad, #c0341f); }
.soc-theme-type--request          { background: rgba(124, 58, 237, 0.14); color: #7c3aed; }
.soc-theme-type--purchase_intent  { background: rgba(217, 119, 6, 0.16); color: #b45309; }
.soc-theme-type--praise           { background: rgba(26, 127, 55, 0.14); color: var(--soc-good, #1a7f37); }
.soc-theme-type--other            { background: rgba(234, 88, 12, 0.14); color: #ea580c; }

/* Same chip treatment as the post-card performance badge (.soc-post__perf)
   so a theme's frequency reads at the same glance-weight as everything
   else in the UI, instead of disappearing as plain grey text. */
.soc-theme-count {
	display: inline-flex;
	align-items: center;
	flex: 0 0 auto;
	margin-left: auto;
	padding: 1px 6px;
	border-radius: 6px;
	font-weight: 600;
	font-size: 0.78rem;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
	background: var(--soc-plane, #f6f6f8);
	color: var(--soc-muted, #767570);
}

/* Hook-type badges -- distinct taxonomy from the comment-theme types above,
   reuses the same .soc-theme-type chip shape for visual consistency. */
.soc-theme-type--bold_claim         { background: rgba(192, 52, 31, 0.14); color: var(--soc-bad, #c0341f); }
.soc-theme-type--stat_shock         { background: rgba(37, 99, 235, 0.14); color: #2563eb; }
.soc-theme-type--pattern_interrupt  { background: rgba(124, 58, 237, 0.14); color: #7c3aed; }
.soc-theme-type--story_open         { background: rgba(13, 148, 136, 0.14); color: #0d9488; }
.soc-theme-type--controversy        { background: rgba(190, 24, 93, 0.14); color: #be185d; }
.soc-theme-type--relatable_problem  { background: rgba(217, 119, 6, 0.16); color: #b45309; }
.soc-theme-type--direct_callout     { background: rgba(26, 127, 55, 0.14); color: var(--soc-good, #1a7f37); }
.soc-theme-type--no_spoken_hook     { background: rgba(118, 117, 112, 0.16); color: var(--soc-muted, #767570); }

.soc-hook-subhead {
	margin: 14px 0 8px;
	font-size: 0.85rem;
	font-weight: 700;
}
.soc-hook-subhead:first-child {
	margin-top: 0;
}
.soc-hook-subhead--bombed {
	margin-top: 29px;
}
.soc-hook-subhead--best::before,
.soc-hook-subhead--bombed::before {
	content: '';
	display: inline-block;
	width: 8px;
	height: 8px;
	border-radius: 999px;
	margin-right: 6px;
}
.soc-hook-subhead--best::before   { background: var(--soc-good, #1a7f37); }
.soc-hook-subhead--bombed::before { background: var(--soc-bad, #c0341f); }

/* Sentiment split: one continuous bar, segment widths are the real
   percentages rather than three separate bars -- reads at a glance the
   same way a stacked-bar chart does, without needing a chart library for
   something this simple. */
.soc-sentiment {
	display: flex;
	width: 100%;
	height: 10px;
	border-radius: 999px;
	overflow: hidden;
	background: var(--soc-plane, #f4f4f6);
	margin-bottom: 10px;
}
.soc-sentiment__seg {
	height: 100%;
}
.soc-sentiment__seg--positive { background: var(--soc-good, #1a7f37); }
.soc-sentiment__seg--neutral  { background: var(--soc-muted, #767570); }
.soc-sentiment__seg--negative { background: var(--soc-bad, #c0341f); }

.soc-sentiment__legend {
	display: flex;
	flex-wrap: wrap;
	gap: 14px;
	margin-bottom: 14px;
	font-size: 0.8rem;
	font-weight: 600;
}
.soc-sentiment__key { display: flex; align-items: center; gap: 5px; }
.soc-sentiment__key::before {
	content: '';
	width: 8px;
	height: 8px;
	border-radius: 999px;
	display: inline-block;
}
.soc-sentiment__key--positive::before { background: var(--soc-good, #1a7f37); }
.soc-sentiment__key--neutral::before  { background: var(--soc-muted, #767570); }
.soc-sentiment__key--negative::before { background: var(--soc-bad, #c0341f); }

.soc-sentiment__example {
	margin: 4px 0 0;
	font-size: 0.8rem;
	font-style: italic;
	color: var(--soc-ink-2);
}

/*
 * Tile rows whose count varies. auto-fit collapses the unused tracks, so four
 * tiles span the full width instead of leaving a fifth column empty.
 */
.soc-tiles--fit {
	grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
}

/*
 * Insights is the only tab carrying a heatmap and multi-column tables, which is
 * why it was the only one that scrolled sideways on a phone. The grid's 420px
 * floor and the table's desktop padding are what forced it; both are relaxed
 * here so the content fits the screen. The overflow-x on their wrappers stays
 * as a backstop for anything genuinely too wide, so nothing can ever break the
 * page width.
 */
@media (max-width: 640px) {
	/*
	 * One tile per row on a phone. This has to sit after the auto-fit rule
	 * above rather than with the other mobile tile rules further up the file:
	 * both selectors are a single class, so the later one wins outright and an
	 * earlier override is simply discarded. The auto-fit floor is 170px, so on
	 * a wide phone two tracks still fit and the row silently doubles up.
	 */
	.soc-tiles--fit {
		grid-template-columns: minmax(0, 1fr);
	}

	.soc-heat {
		min-width: 0;
		grid-template-columns: auto repeat(8, minmax(0, 1fr));
		gap: 3px;
	}

	.soc-heat__cell {
		font-size: 0.62rem;
	}

	.soc-heat__head,
	.soc-heat__row-label {
		font-size: 0.62rem;
	}

	.soc-table {
		font-size: 0.78rem;
	}

	.soc-table th,
	.soc-table td {
		padding: 7px 8px;
	}
}

/* "About this account" facts, Audit tab. */
.soc-facts {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: 14px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.soc-facts__item {
	background: var(--soc-plane, #f6f6f8);
	border-radius: var( --soc-radius, 6px );
	padding: 14px 16px;
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.soc-facts__label {
	color: var(--soc-muted);
	font-size: 0.78rem;
}

.soc-facts__value {
	font-size: 1.24rem;
	font-weight: 600;
}

/* Only shown when a fact carries an implication — an advisory, not a label. */
.soc-facts__note {
	color: var(--soc-ink-2);
	font-size: 0.76rem;
	margin-top: 4px;
	line-height: 1.4;
}

/*
 * Posts tagging this account. The grid and card chrome are soc-posts /
 * soc-post -- the same ones the Posts tab uses, not a mentions-specific
 * copy -- so the two read as one consistent grid rather than two similar
 * ones. Only the author-attribution row below is mentions-specific: a
 * Posts card has no "whose post is this" line to show.
 */
.soc-mentions__head {
	display: flex;
	align-items: center;
	gap: 6px;
	flex-wrap: wrap;
}

.soc-app a.soc-mentions__author {
	color: var(--soc-accent);
	font-weight: 600;
	font-size: 0.9rem;
	text-decoration: none;
}

.soc-app a.soc-mentions__author:hover {
	text-decoration: underline;
}

.soc-mentions__followers {
	color: var(--soc-muted);
	font-size: 0.74rem;
}

/* The whole chip is the target, not just the word. */
.soc-taglist__item {
	padding: 0;
}

.soc-app a.soc-taglist__link {
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding: 8px 12px;
	color: inherit;
	text-decoration: none;
	border-radius: var( --soc-control-radius, 5px );
}

.soc-app a.soc-taglist__link:hover,
.soc-app a.soc-taglist__link:focus {
	background: var(--soc-grid);
	text-decoration: none;
}

.soc-app a.soc-taglist__link:hover .soc-taglist__tag {
	color: var(--soc-accent);
}

/* ----------------------------------------------------------- Competitors */

.soc-rivals__self th,
.soc-rivals__self td {
	font-weight: 700;
}

.soc-app a.soc-rivals__handle {
	color: var(--soc-accent);
	text-decoration: none;
}

.soc-app a.soc-rivals__handle:hover {
	text-decoration: underline;
}

.soc-rivals__remove {
	background: none;
	border: 0;
	color: var(--soc-muted);
	cursor: pointer;
	padding: 4px 6px;
	line-height: 1;
}

.soc-rivals__remove:hover {
	color: var(--soc-bad);
	background: none;
}

.soc-rivals__add {
	display: flex;
	gap: 8px;
	margin-top: 14px;
	flex-wrap: wrap;
}

.soc-rivals__add .soc-input {
	flex: 1 1 200px;
	min-width: 0;
	padding: 9px 12px;
	border: 1px solid var(--soc-border);
	border-radius: var( --soc-control-radius, 5px );
	font: inherit;
}

.soc-rivals__error {
	color: var(--soc-bad);
	font-size: 0.82rem;
	margin: 8px 0 0;
}

.soc-rivals__suggest {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin-top: 12px;
}

.soc-rivals__suggest-label {
	color: var(--soc-muted);
	font-size: 0.8rem;
}

.soc-chip {
	background: var(--soc-plane, #f6f6f8);
	border: 1px solid var(--soc-border);
	border-radius: var( --soc-pill, 5px );
	padding: 6px 10px;
	font-size: 0.8rem;
	cursor: pointer;
	font: inherit;
	font-size: 0.8rem;
}

.soc-chip:hover {
	background: var(--soc-grid);
	border-color: var(--soc-accent);
	color: var(--soc-accent);
}

/*
 * Suggestion chip: a checkbox that stages the account for comparison, beside a
 * link that goes to the profile. The chip itself is inert — only the two
 * controls inside it do anything, so the whole thing must stop advertising
 * itself as one big button.
 */
.soc-chip--pick {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 5px 10px 5px 8px;
	cursor: default;
}

.soc-chip--pick:hover {
	background: var(--soc-plane, #f6f6f8);
	border-color: var(--soc-border);
	color: inherit;
}

.soc-chip--pick:focus-within {
	border-color: var(--soc-accent);
}

.soc-chip__check {
	margin: 0;
	cursor: pointer;
	accent-color: var(--soc-accent);
}

.soc-chip__check:disabled {
	cursor: not-allowed;
	opacity: 0.45;
}

.soc-chip__link {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	color: inherit;
	text-decoration: none;
}

.soc-chip__link:hover,
.soc-chip__link:focus {
	color: var(--soc-accent);
	text-decoration: underline;
}

.soc-chip__out {
	font-size: 0.72em;
	opacity: 0.55;
}

.soc-rivals__suggest-hint {
	color: var(--soc-muted);
	font-size: 0.8rem;
	margin: 14px 0 0;
}

.soc-rivals__suggest-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
	margin-top: 10px;
}

.soc-rivals__slots {
	color: var(--soc-muted);
	font-size: 0.8rem;
}

.soc-rivals__loading {
	color: var(--soc-muted);
	font-size: 0.85rem;
	margin: 0;
}

/* Four distinct, colour-blind-safe line colours for the comparison chart. */
.soc-app {
	--soc-series-3: #0f9d8f;
	--soc-series-4: #b3459b;
}

.soc-rivalchart {
	margin-top: 16px;
}

.soc-rivalchart .soc-chart {
	box-shadow: none;
	padding: 0;
}

.soc-rivalchart__legend {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	list-style: none;
	margin: 10px 0 0;
	padding: 0;
}

.soc-rivalchart__key {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	background: none;
	border: 1px solid var(--soc-border);
	border-radius: var( --soc-pill, 5px );
	padding: 5px 10px;
	font: inherit;
	font-size: 0.78rem;
	cursor: pointer;
	color: var(--soc-ink);
}

.soc-rivalchart__key.is-off {
	color: var(--soc-muted);
	text-decoration: line-through;
}

.soc-rivalchart__swatch {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	flex: none;
}

.soc-rivals__pending {
	color: var(--soc-muted);
	font-size: 0.85rem;
	margin: 14px 0 0;
}

/*
 * The theme paints every `button` with its own pink fill (and again on hover),
 * which turns the chart key into a row of solid buttons. Out-specify it the
 * same way the other controls here do.
 */
.soc-app button.soc-rivalchart__key,
.soc-app button.soc-rivalchart__key:hover,
.soc-app button.soc-rivalchart__key:focus {
	background: var(--soc-surface);
	border: 1px solid var(--soc-border);
	color: var(--soc-ink);
	font-weight: 500;
	text-transform: none;
	letter-spacing: normal;
	box-shadow: none;
}

.soc-app button.soc-rivalchart__key:hover {
	border-color: var(--soc-accent);
}

.soc-app button.soc-rivalchart__key.is-off,
.soc-app button.soc-rivalchart__key.is-off:hover {
	color: var(--soc-muted);
	background: var(--soc-plane, #f6f6f8);
}

/* Same treatment for the suggestion chips and the remove control. */
.soc-app button.soc-chip,
.soc-app button.soc-chip:hover,
.soc-app button.soc-chip:focus {
	background: var(--soc-plane, #f6f6f8);
	color: var(--soc-ink);
	border: 1px solid var(--soc-border);
	text-transform: none;
	letter-spacing: normal;
	box-shadow: none;
}

.soc-app button.soc-chip:hover {
	border-color: var(--soc-accent);
	color: var(--soc-accent);
}

.soc-app button.soc-rivals__remove,
.soc-app button.soc-rivals__remove:hover,
.soc-app button.soc-rivals__remove:focus {
	background: none;
	border: 0;
	box-shadow: none;
	color: var(--soc-muted);
}

.soc-app button.soc-rivals__remove:hover {
	color: var(--soc-bad);
}

/* Most-engaged commenters. */
.soc-fans {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
	gap: 12px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.soc-fans__item {
	background: var(--soc-plane, #f6f6f8);
	border-radius: var( --soc-radius, 6px );
	padding: 14px;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 4px;
}

.soc-fans__pic {
	width: 52px;
	height: 52px;
	border-radius: 50%;
	object-fit: cover;
	background: var(--soc-grid);
}

.soc-fans__who {
	display: flex;
	align-items: center;
	gap: 4px;
}

.soc-app a.soc-fans__handle {
	color: var(--soc-accent);
	font-weight: 600;
	font-size: 0.85rem;
	text-decoration: none;
}

.soc-app a.soc-fans__handle:hover {
	text-decoration: underline;
}

.soc-fans__meta {
	color: var(--soc-muted);
	font-size: 0.74rem;
}

/*
 * Mobile tooltip placement.
 *
 * Active sources (Growth tab)
 * --------------------------------------------------------------------------
 * Placed before the trailing media queries on purpose: an unconditional rule
 * added after them outranks anything they set at the same specificity, which
 * has silently broken the mobile layout here before.
 */

/*
 * Engagement band chips. A separate scale from the grade letters on purpose:
 * this one describes engagement relative to account size and nothing else.
 * The copy stays a statement about engagement rather than about the audience —
 * Instagram reports no reach, so low engagement cannot be pinned on the
 * followers rather than on distribution or the content.
 */
/*
 * One row: the niche chip hugs its text on the left, the engagement chip takes
 * the rest of the width so its tinted bar still runs the eye across to the
 * grade on the right. Wraps rather than squashing on a narrow viewport.
 */
.soc-srclist__flags {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
	margin-top: 4px;
}

.soc-srclist__eng {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 3px 9px;
	border-radius: var(--soc-pill, 5px);
	font-size: 0.72rem;
	font-weight: 600;
	line-height: 1.4;
	/* Default: hug the text. */
	flex: 0 0 auto;
}

/* Neutral: a caution about fit, not a fault with the account. */
.soc-eng--broad,
.soc-eng--limited {
	background: #f1f0f6;
	color: var(--soc-ink-2);
}

.soc-eng--high {
	background: var(--soc-good-bg);
	color: var(--soc-good);
}

.soc-eng--normal {
	background: var(--soc-warn-bg);
	color: var(--soc-warn);
}

.soc-eng--low {
	background: var(--soc-bad-bg);
	color: var(--soc-bad);
}

/*
 * Card-level action, pinned top-right. The card is the positioning context, so
 * it needs position:relative — added via a modifier rather than to every
 * .soc-insight, which would change stacking on cards that never asked for it.
 */
.soc-insight--action {
	position: relative;
}

/*
 * Same spec as .soc-rangepick__button, minus the caret.
 *
 * Chained under .soc-card because the theme styles links inside cards with its
 * own padding — an unchained single class ties on specificity and loses to it
 * on source order.
 */
.soc-card .soc-insight__action,
.soc-insight__action {
	position: absolute;
	top: 16px;
	right: 16px;
	display: inline-flex;
	align-items: center;
	font: inherit;
	font-size: 0.9rem;
	font-weight: 600;
	min-height: 40px;
	padding: 9px 14px;
	border: none;
	border-radius: var( --soc-pill, 5px );
	background: var(--soc-accent);
	color: #fff;
	cursor: pointer;
	text-decoration: none;
}

/*
 * Same theme guard and the same darken-the-accent hover as the range button.
 * text-decoration is repeated on hover/focus because the theme re-underlines
 * links on hover — killing it once at rest is not enough.
 */
.soc-card .soc-insight__action:hover,
.soc-card .soc-insight__action:focus,
.soc-card .soc-insight__action:focus-visible,
.soc-insight__action:hover,
.soc-insight__action:focus,
.soc-insight__action:focus-visible {
	background: var(--soc-accent);
	background: color-mix( in srgb, var(--soc-accent) 82%, #000 );
	color: #fff;
	text-decoration: none;
}

/*
 * Tooltips on anything sitting at the right-hand edge must grow LEFTWARDS.
 *
 * This is the same bug the tile info icons already carry a fix for: the panel
 * is far wider than the chip, and an absolutely positioned box still counts
 * towards scrollable overflow — so a right-edge chip opening rightwards gave
 * the whole Growth tab a horizontal scrollbar. Overflow to the left of the
 * origin creates no scrollbar, which is why anchoring right fixes it.
 */
.soc-srclist__grade.soc-tip::after,
.soc-srcscore__badge.soc-tip::after {
	left: auto;
	right: 0;
	max-width: min( 260px, calc( 100vw - 24px ) );
}

.soc-srclist__grade.soc-tip::before,
.soc-srcscore__badge.soc-tip::before {
	left: auto;
	right: 7px;
}

/*
 * The dial and the full-width flag chips are wide and start at the left, so
 * their panels are clamped rather than re-anchored — enough to keep them
 * inside the card at any viewport.
 */
.soc-dial.soc-tip::after,
.soc-srclist__eng.soc-tip::after {
	max-width: min( 280px, calc( 100vw - 32px ) );
}

/* ---- Score dial ---------------------------------------------------- */

.soc-srcscore {
	display: flex;
	align-items: center;
	gap: 22px;
	padding: 4px 0 20px;
	margin: 0 0 4px;
	border-bottom: 1px solid var(--soc-border);
}

.soc-srcscore--pending {
	padding-top: 0;
}

.soc-dial {
	position: relative;
	flex: 0 0 120px;
	width: 120px;
	height: 120px;
}

.soc-dial__ring {
	width: 120px;
	height: 120px;
	/* 12 o'clock start, so the arc grows the way a gauge is read. */
	transform: rotate( -90deg );
}

.soc-dial__track {
	stroke: currentColor;
	opacity: 0.14;
}

.soc-dial__fill {
	stroke: currentColor;
	transition: stroke-dashoffset 900ms cubic-bezier( 0.22, 0.61, 0.36, 1 );
}

/*
 * The dial carries its grade as `color`, so track and fill are one hue at two
 * strengths and the state reads across the whole ring rather than only the
 * filled part. B — meeting expectations — sits on the house accent, so the
 * common case looks like the brand rather than like a warning.
 */
.soc-dial {
	color: var(--soc-accent);
}

.soc-dial--a\+\+,
.soc-dial--a {
	color: var(--soc-good);
}

.soc-dial--c,
.soc-dial--d {
	color: var(--soc-bad);
}

/* Progress rather than score: neutral, so it cannot read as a verdict. */
.soc-dial--pending {
	color: var(--soc-muted);
}

.soc-dial--pending .soc-dial__value {
	font-size: 1.4rem;
	color: var(--soc-muted);
}

.soc-dial__value {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 2rem;
	font-weight: 600;
	line-height: 1;
	/* Ink, not the dial colour: a value in pale amber is unreadable, and the
	   ring already carries the severity. */
	color: var(--soc-ink);
	font-variant-numeric: tabular-nums;
}

.soc-srcscore__body {
	min-width: 0;
}

.soc-srcscore__label {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0;
	font-size: 1.05rem;
	font-weight: 600;
	color: var(--soc-ink);
}

.soc-srcscore__sub {
	margin: 6px 0 0;
	font-size: 0.9rem;
	color: var(--soc-muted);
}

.soc-srcscore__flag {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 10px 0 0;
	font-size: 0.85rem;
	font-weight: 600;
	color: var(--soc-bad);
}

.soc-srcscore__flagicon {
	display: inline-flex;
	align-items: center;
	line-height: 1;
}

@media ( prefers-reduced-motion: reduce ) {
	.soc-dial__fill {
		transition: none;
	}
}

/* Small in-card variant of .soc-tabs -- same pill/fill language, scaled
   down for a toggle that lives inside a card rather than the page header. */
.soc-srctabs {
	display: inline-flex;
	gap: 4px;
	background: var(--soc-plane);
	border: 1px solid var(--soc-border);
	border-radius: var(--soc-pill, 999px);
	padding: 3px;
	margin-bottom: 10px;
}

.soc-srctabs__tab {
	font: inherit;
	font-size: 0.82rem;
	font-weight: 600;
	color: var(--soc-ink-2);
	background: none;
	border: 0;
	border-radius: var(--soc-pill, 999px);
	padding: 5px 12px;
	cursor: pointer;
}

.soc-srctabs__tab:hover {
	color: var(--soc-ink);
}

.soc-srctabs__tab.is-active {
	background: var(--soc-accent);
	color: #fff;
}

.soc-srclist {
	list-style: none;
	margin: 0;
	padding: 0;
}

.soc-srclist__item {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 10px 0;
	border-bottom: 1px solid var(--soc-border);
}

.soc-srclist__item:last-child {
	border-bottom: 0;
}

.soc-srclist__avatar {
	width: 36px;
	height: 36px;
	border-radius: 50%;
	object-fit: cover;
	flex: 0 0 36px;
	background: var(--soc-border);
}

.soc-srclist__meta {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
	flex: 1 1 auto;
}

.soc-srclist__handle {
	font-weight: 600;
	color: var(--soc-ink);
	text-decoration: none;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.soc-srclist__handle:hover {
	color: var(--soc-accent);
}

.soc-srclist__stat {
	font-size: 0.8rem;
	color: var(--soc-muted);
}

.soc-srclist__stat--warn {
	color: var(--soc-accent);
}

/* Chip styling comes from .soc-gradechip; this only places it in the row. */
.soc-srclist__grade {
	flex: 0 0 auto;
	margin-left: auto;
}

/*
 * This has to live after the general .soc-tile__info.soc-tip rules above:
 * both selectors carry the same specificity, so whichever comes last in the
 * file wins — and inside an earlier media query it lost silently, which is why
 * the panel kept ignoring these values.
 *
 * The panel is anchored to an 18px button, so a fixed width has to go
 * somewhere: rightwards it left the screen and dragged the page width with it,
 * leftwards it ran off the other edge unreadable. Making the button static
 * hands positioning to the tile, which is already position:relative, so the
 * panel starts in the tile's top-left corner and stops at its right edge.
 */
@media (max-width: 640px) {
	.soc-tile__info.soc-tip::after {
		/* Below the marker, not above it: these tiles put the marker at their
		   top edge, so a panel opening upwards would sit off the tile. */
		top: calc( 100% + 8px );
		bottom: auto;
		/* Grows rightwards from the marker in the corner. The marker sits 12px
		   inside a tile that is itself 20px inside the screen, so capping the
		   panel at the viewport less both insets keeps it on screen at any
		   phone width without pinning it to the tile and stretching it. */
		left: 0;
		right: auto;
		max-width: calc( 100vw - 56px );
	}

	/* The arrow points upwards; the panel now opens downwards. */
	.soc-tile__info.soc-tip::before {
		display: none;
	}
}


/* ------------------------------------------------------------------------
 * Reports tab.
 *
 * Reuses .soc-card, .soc-btn--primary/--ghost and the .soc-delta--up/
 * down tokens verbatim rather than inventing a parallel set -- see
 * [[never-mock-without-real-styles]].
 * ---------------------------------------------------------------------- */

.soc-reports-wrap {
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.soc-reports-latest {
	display: flex;
	align-items: center;
	gap: 18px;
	flex-wrap: wrap;
}

.soc-reports-latest__icon {
	width: 50px;
	height: 50px;
	border-radius: var( --soc-radius, 6px );
	background: var( --soc-good-bg );
	color: var( --soc-good );
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 1.25rem;
	flex: none;
}

.soc-reports-latest__title {
	font-size: 1.02rem;
	font-weight: 700;
	margin: 0;
	color: var( --soc-ink );
}

.soc-reports-latest__meta {
	font-size: 0.8rem;
	color: var( --soc-muted );
	margin: 3px 0 0;
}

.soc-reports-latest__stats {
	display: flex;
	gap: 22px;
	margin-left: 8px;
	padding-left: 22px;
	border-left: 1px solid var( --soc-border );
}

.soc-reports-latest__stat-label {
	font-size: 0.68rem;
	color: var( --soc-muted );
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

.soc-reports-latest__stat-value {
	font-size: 0.96rem;
	font-weight: 700;
	margin-top: 2px;
	color: var( --soc-ink );
	font-variant-numeric: tabular-nums;
}

.soc-reports__actions {
	margin-left: auto;
	display: flex;
	gap: 8px;
	flex: none;
}

.soc-reports {
	display: flex;
	flex-direction: column;
}

.soc-report {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 14px 20px;
	border-top: 1px solid var( --soc-border );
	flex-wrap: wrap;
}

.soc-report:first-child {
	border-top: 0;
}

.soc-report__icon {
	width: 34px;
	height: 34px;
	border-radius: var( --soc-radius, 6px );
	background: var( --soc-plane );
	color: var( --soc-ink-2 );
	display: flex;
	align-items: center;
	justify-content: center;
	font-size: 0.9rem;
	flex: none;
}

.soc-report__period {
	font-weight: 600;
	font-size: 0.9rem;
	color: var( --soc-ink );
}

.soc-report__date {
	font-size: 0.78rem;
	color: var( --soc-muted );
	margin-top: 1px;
}

.soc-report__delta {
	font-size: 0.8rem;
	font-weight: 600;
}

.soc-report__delta.is-flat {
	background: var( --soc-plane );
	color: var( --soc-muted );
	padding: 3px 9px;
	border-radius: 999px;
}

.soc-reports-viewbar {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 10px;
}

.soc-reports-viewbar .soc-reports__actions {
	margin-left: auto;
}

.soc-reports-frame {
	width: 100%;
	height: 80vh;
	min-height: 640px;
	border: 1px solid var( --soc-border );
	border-radius: var( --soc-radius, 6px );
	background: #fff;
}

.soc-empty {
	background: var( --soc-surface );
	border: 1px solid var( --soc-border );
	border-radius: var( --soc-radius, 6px );
	padding: 40px 24px;
	text-align: center;
}

.soc-empty__title {
	font-weight: 700;
	font-size: 0.98rem;
	color: var( --soc-ink );
	margin: 0 0 6px;
}

.soc-empty__body {
	font-size: 0.85rem;
	color: var( --soc-muted );
	margin: 0;
	max-width: 420px;
	margin-left: auto;
	margin-right: auto;
}

.soc-section-label {
	font-size: 0.7rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var( --soc-muted );
	margin: 4px 2px 0;
}

@media ( max-width: 720px ) {
	.soc-reports-latest {
		align-items: flex-start;
	}

	.soc-reports-latest__stats {
		margin-left: 0;
		padding-left: 0;
		border-left: 0;
		border-top: 1px solid var( --soc-border );
		padding-top: 12px;
		width: 100%;
	}

	.soc-reports__actions {
		margin-left: 0;
		width: 100%;
	}

	.soc-reports__actions .soc-btn {
		flex: 1 1 auto;
		justify-content: center;
	}

	.soc-report {
		flex-direction: column;
		align-items: flex-start;
	}

	.soc-report__delta {
		margin-left: 48px;
	}
}

/* ---- Audience demographics (Insights tab) ---------------------------- */

.soc-demo {
	display: flex;
	flex-direction: column;
	gap: 25px;
}

.soc-demo__row {
	display: flex;
	gap: 32px;
	flex-wrap: wrap;
	align-items: flex-start;
}

.soc-demo__col {
	flex: 1 1 320px;
	min-width: 0;
}

.soc-demo__section-title {
	margin: 0 0 14px;
	font-size: 0.95rem;
	font-weight: 600;
	color: var(--soc-ink);
}

.soc-demo__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-bottom: 14px;
}

.soc-demo__head .soc-demo__section-title {
	margin-bottom: 0;
}

/*
 * Element-prefixed like .soc-chart__toggle above -- the theme applies its
 * own default fill/hover to a bare <button>, and a class alone doesn't
 * out-specify that.
 */
button.soc-demo__toggle {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	flex: 0 0 auto;
	font: inherit;
	font-size: 0.8rem;
	font-weight: 500;
	padding: 6px 12px;
	border: 1px solid var(--soc-border);
	border-radius: var( --soc-pill, 5px );
	background: var(--soc-surface);
	color: var(--soc-muted);
	cursor: pointer;
}

button.soc-demo__toggle:hover,
button.soc-demo__toggle:focus-visible {
	background: var(--soc-accent);
	border-color: transparent;
	color: #fff;
}

/* Same bottom margin as every .soc-card on this tab -- the connect prompt
   replaces the card entirely (see showConnectPrompt() in dashboard.js) and
   doesn't inherit that spacing on its own. */
.soc-demo-connect {
	margin-bottom: var(--soc-gap);
}

.soc-donut-row {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 32px;
}

.soc-donut {
	position: relative;
	flex: 0 0 auto;
	width: 180px;
	height: 180px;
}

.soc-donut__ring circle {
	cursor: pointer;
	transition: opacity 0.12s ease;
}

.soc-donut__ring:hover circle:not(:hover) {
	opacity: 0.45;
}

.soc-donut__legend {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 10px;
	min-width: 160px;
}

.soc-donut__legend-item {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 0.85rem;
	color: var(--soc-ink);
}

.soc-donut__swatch {
	flex: 0 0 12px;
	width: 12px;
	height: 12px;
	border-radius: 3px;
}

.soc-donut__legend-pct {
	margin-left: auto;
	padding-left: 12px;
	color: var(--soc-muted);
	font-variant-numeric: tabular-nums;
}

.soc-donut__tip {
	position: fixed;
	z-index: 30;
	padding: 7px 10px;
	border-radius: var(--soc-control-radius, 5px);
	background: #333333;
	color: #fff;
	font-size: 0.8rem;
	font-weight: 500;
	line-height: 1.3;
	white-space: nowrap;
	pointer-events: none;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.12s ease;
	display: flex;
	align-items: center;
	gap: 7px;
}

.soc-donut__tip.is-visible {
	opacity: 1;
	visibility: visible;
}

.soc-donut__tip-swatch {
	width: 9px;
	height: 9px;
	border-radius: 2px;
	flex: 0 0 9px;
}

.soc-bars {
	display: flex;
	align-items: flex-end;
	gap: 14px;
	padding: 0 4px;
}

.soc-bars__col {
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: flex-end;
	gap: 8px;
	min-width: 0;
}

.soc-bars__value {
	font-size: 0.76rem;
	font-weight: 600;
	color: var(--soc-ink);
	font-variant-numeric: tabular-nums;
}

.soc-bars__bar {
	width: 60%;
	max-width: 34px;
	min-height: 3px;
	/*
	 * Same technique as the "when to post" heatmap: one hue (--soc-accent),
	 * intensity carried by an inline opacity set per-bar in JS from that
	 * bar's share of the tallest one. Darker = more, lighter = less, one
	 * color story across both charts on this tab.
	 */
	background: var(--soc-accent);
	border-radius: 4px 4px 0 0;
}

.soc-bars__label {
	font-size: 0.72rem;
	color: var(--soc-muted);
	white-space: nowrap;
}

.soc-demo__scroll {
	max-height: 258px;
	overflow-y: auto;
	border: 1px solid var(--soc-border);
	border-radius: var(--soc-radius);
}

@media ( max-width: 767px ) {
	.soc-donut-row {
		gap: 20px;
	}

	.soc-donut {
		width: 150px;
		height: 150px;
	}
}
