/*
 * The study buddy's button and drawer.
 *
 * It sits on pages that already have a look of their own — the IDE, the quiz
 * runner, a study guide — so it borrows the study-guide palette (navy ground,
 * violet structure, sky for the thing you act on) and stays out of the way:
 * one small round button, and a drawer that slides over the right of the page
 * rather than moving anything the student was reading.
 *
 * Ligatures are off here too. A student asking about >= must see >= in the
 * answer, and this file is loaded on pages that do not all carry cozy-fonts.css
 * (see pitfall 17).
 */

/*
 * THE hidden ATTRIBUTE NEEDS THESE RULES. An author `display` beats the
 * browser's own `[hidden] { display: none }`, because author styles win over
 * the user-agent stylesheet whatever the specificity. Both the button and the
 * overlay set `display`, and the JS shows and hides them with `.hidden = `, so
 * without these they are NEVER hidden.
 *
 * That is not a cosmetic bug. The overlay is a full-viewport element at the top
 * of the stacking order, so a page carrying this stylesheet had every click
 * land in an invisible sheet instead of on the page: the Cloud IDE could not be
 * used at all. Shipped and caught 2026-09-25. Never set `display` on either of
 * these without a matching `[hidden]` rule; studyBuddyHidden.test.ts fails if
 * one goes missing.
 */
.sb-fab[hidden],
.sb-overlay[hidden],
.sb-note[hidden] {
	display: none !important;
}

/*
 * Belt and braces for the one that can take a whole page down. Even if the
 * overlay is somehow rendered while closed, it must not swallow clicks: it only
 * becomes a click target once it is actually open, which is the one moment a
 * click on it means something (tap outside to close).
 */
.sb-overlay:not(.is-open) {
	pointer-events: none;
}

.sb-overlay.is-open {
	pointer-events: auto;
}

.sb-panel *,
.sb-panel *::before,
.sb-panel *::after,
.sb-fab {
	font-variant-ligatures: none;
}

:root {
	--sb-ground: #141a2e;
	--sb-raised: #1b2340;
	--sb-line: #2c3558;
	--sb-text: #e8ecf8;
	--sb-dim: #9aa6c8;
	--sb-violet: #a78bfa;
	--sb-sky: #56ccf2;
	--sb-amber: #f2c94c;
	--sb-red: #eb5757;
}

/* ── The button ─────────────────────────────────────────────────────────── */

.sb-fab {
	position: fixed;
	right: 18px;
	bottom: 18px;
	z-index: 2147483000;
	width: 52px;
	height: 52px;
	min-width: 44px;
	min-height: 44px;
	border-radius: 50%;
	border: 1px solid var(--sb-line);
	background: linear-gradient(140deg, var(--sb-g1), var(--sb-g2));
	animation: sb-fab-drift 90s ease-in-out infinite;
	color: var(--sb-sky);
	display: grid;
	place-items: center;
	cursor: pointer;
	box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
	transition:
		transform 0.15s ease,
		border-color 0.15s ease,
		color 0.15s ease;
}

.sb-fab svg {
	width: 26px;
	height: 26px;
}

.sb-fab:hover {
	transform: translateY(-2px);
	border-color: var(--sb-sky);
}

.sb-fab:focus-visible {
	outline: 2px solid var(--sb-sky);
	outline-offset: 3px;
}

/* The button's colour drifts through a few deep gradients over a minute and a
 * half and back. Registered properties let the colours themselves interpolate,
 * so the change is too slow to notice unless you watch for it. */
@property --sb-g1 {
	syntax: '<color>';
	inherits: false;
	initial-value: #2b3566;
}

@property --sb-g2 {
	syntax: '<color>';
	inherits: false;
	initial-value: #1b2340;
}

@keyframes sb-fab-drift {
	0%,
	100% {
		--sb-g1: #2b3566;
		--sb-g2: #1b2340;
	}
	25% {
		--sb-g1: #3a2257;
		--sb-g2: #1d1236;
	}
	50% {
		--sb-g1: #4a1f4a;
		--sb-g2: #21123a;
	}
	75% {
		--sb-g1: #1f3f5a;
		--sb-g2: #172038;
	}
}

/* Several runs in a row ending in an error, or printing the same thing after
 * edits: a soft ring pulses out from the button until it is pressed. */
.sb-fab--nudge {
	animation:
		sb-fab-drift 90s ease-in-out infinite,
		sb-fab-nudge 2.4s ease-out infinite;
}

@keyframes sb-fab-nudge {
	0% {
		box-shadow:
			0 6px 20px rgba(0, 0, 0, 0.45),
			0 0 0 0 rgba(86, 204, 242, 0.55);
	}
	70%,
	100% {
		box-shadow:
			0 6px 20px rgba(0, 0, 0, 0.45),
			0 0 0 16px rgba(86, 204, 242, 0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.sb-fab--nudge {
		animation: sb-fab-drift 90s ease-in-out infinite;
		border-color: var(--sb-sky);
		box-shadow:
			0 6px 20px rgba(0, 0, 0, 0.45),
			0 0 0 3px rgba(86, 204, 242, 0.5);
	}
}

/* Coaching costs coins, so the button says so before it is pressed. */
.sb-fab--coach {
	color: var(--sb-amber);
}

.sb-fab--coach:hover {
	border-color: var(--sb-amber);
}

/* ── The drawer ─────────────────────────────────────────────────────────── */

.sb-overlay {
	position: fixed;
	inset: 0;
	z-index: 2147483001;
	background: rgba(8, 11, 22, 0);
	transition: background 0.2s ease;
	display: flex;
	justify-content: flex-end;
}

.sb-overlay.is-open {
	background: rgba(8, 11, 22, 0.5);
}

.sb-panel {
	width: min(420px, 100vw);
	height: 100%;
	display: flex;
	flex-direction: column;
	background: var(--sb-ground);
	border-left: 1px solid var(--sb-line);
	box-shadow: -12px 0 32px rgba(0, 0, 0, 0.4);
	transform: translateX(100%);
	transition: transform 0.2s ease;
	font-family: 'Space Grotesk', 'DM Sans', system-ui, sans-serif;
	color: var(--sb-text);
}

.sb-overlay.is-open .sb-panel {
	transform: translateX(0);
}

.sb-head {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	padding: 14px 16px;
	border-bottom: 1px solid var(--sb-line);
	background: var(--sb-raised);
}

.sb-head-text {
	flex: 1;
	min-width: 0;
}

.sb-title {
	font-size: 15px;
	font-weight: 600;
	letter-spacing: 0.01em;
}

.sb-subtitle {
	margin-top: 2px;
	font-size: 12px;
	color: var(--sb-dim);
	overflow-wrap: anywhere;
}

.sb-close {
	width: 44px;
	height: 44px;
	margin: -8px -8px 0 0;
	border: 0;
	background: none;
	color: var(--sb-dim);
	cursor: pointer;
	display: grid;
	place-items: center;
	border-radius: 8px;
}

.sb-close svg {
	width: 18px;
	height: 18px;
}

.sb-close:hover {
	color: var(--sb-text);
	background: rgba(255, 255, 255, 0.05);
}

/* ── The conversation ───────────────────────────────────────────────────── */

.sb-list {
	flex: 1;
	overflow-y: auto;
	padding: 14px 16px;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.sb-empty {
	color: var(--sb-dim);
	font-size: 13px;
	line-height: 1.55;
	border-left: 2px solid var(--sb-violet);
	padding-left: 12px;
}

.sb-empty p {
	margin: 0;
}

.sb-msg {
	display: flex;
}

.sb-msg--student {
	justify-content: flex-end;
}

.sb-msg .sb-body {
	max-width: 88%;
	padding: 9px 12px;
	border-radius: 12px;
	font-size: 13.5px;
	line-height: 1.6;
	overflow-wrap: anywhere;
}

.sb-msg--student .sb-body {
	background: #2b3566;
	border: 1px solid var(--sb-line);
	border-bottom-right-radius: 4px;
	white-space: pre-wrap;
}

.sb-msg--buddy .sb-body {
	background: var(--sb-raised);
	border: 1px solid var(--sb-line);
	border-bottom-left-radius: 4px;
}

.sb-body p {
	margin: 0 0 8px;
}

.sb-body p:last-child {
	margin-bottom: 0;
}

.sb-body ul {
	margin: 0 0 8px;
	padding-left: 18px;
}

.sb-body code {
	font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
	font-size: 0.92em;
	background: rgba(167, 139, 250, 0.14);
	border-radius: 4px;
	padding: 1px 4px;
}

.sb-body .sb-code {
	margin: 8px 0;
	padding: 10px 12px;
	border-radius: 8px;
	background: #10131f;
	border: 1px solid var(--sb-line);
	overflow-x: auto;
}

.sb-body .sb-code code {
	background: none;
	padding: 0;
	font-size: 12.5px;
	line-height: 1.5;
}

.sb-body em {
	color: var(--sb-dim);
	font-style: normal;
	font-size: 0.95em;
}

/* Waiting for the first token. */
.sb-dots {
	display: inline-flex;
	gap: 4px;
	align-items: center;
	height: 16px;
}

.sb-dots i {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--sb-violet);
	animation: sb-pulse 1.1s ease-in-out infinite;
}

.sb-dots i:nth-child(2) {
	animation-delay: 0.15s;
}

.sb-dots i:nth-child(3) {
	animation-delay: 0.3s;
}

@keyframes sb-pulse {
	0%,
	100% {
		opacity: 0.25;
		transform: translateY(0);
	}
	50% {
		opacity: 1;
		transform: translateY(-3px);
	}
}

@media (prefers-reduced-motion: reduce) {
	.sb-dots i {
		animation: none;
		opacity: 0.6;
	}
	.sb-panel,
	.sb-overlay {
		transition: none;
	}
}

/* ── Blocks inside an answer ────────────────────────────────────────────── */
/*
 * The same vocabulary the study guides and the task cards use, at chat size:
 * a sample joined to what it prints, a callout wearing its label in its stripe,
 * numbered circles, amber dots on the spaces inside a string. The model never
 * writes any of this markup — it writes plain markers and the drawer draws.
 *
 * Colours carry the same meanings as everywhere else: violet organises, sky is
 * the thing being shown, green is what a program produced, red is the warning.
 */

.sb-blocks > * {
	margin: 0 0 8px;
}

.sb-blocks > *:last-child {
	margin-bottom: 0;
}

/* A sample: the code, and under it what it printed. */
.sb-sample {
	border: 1px solid var(--sb-line);
	border-radius: 8px;
	overflow: hidden;
	background: #10131f;
}

.sb-sample .sb-code {
	margin: 0;
	padding: 9px 11px;
	background: none;
	border: 0;
	border-radius: 0;
	overflow-x: auto;
}

.sb-out {
	border-top: 1px solid var(--sb-line);
	background: var(--sb-raised);
	padding: 7px 11px 8px;
}

.sb-out-tag {
	display: block;
	font-size: 9.5px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--sb-dim);
	margin-bottom: 3px;
}

.sb-out pre {
	margin: 0;
	font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
	font-size: 12.5px;
	line-height: 1.5;
	color: #4ade80;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
}

/* A space that is part of the answer, inside a string. Same amber as the cards. */
.sb-body .cozy-ws {
	color: #f59e0b;
	opacity: 0.85;
	user-select: none;
}

/* Callouts. The label lives in the stripe, as it does in the study guides. */
.sb-callout {
	border-left: 3px solid var(--sb-violet);
	background: rgba(167, 139, 250, 0.09);
	border-radius: 0 8px 8px 0;
	padding: 8px 11px;
}

.sb-callout--watch {
	border-left-color: #f87171;
	background: rgba(248, 113, 113, 0.09);
}

.sb-callout-tag {
	display: block;
	font-family: 'JetBrains Mono', ui-monospace, monospace;
	font-size: 10px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--sb-violet);
	margin-bottom: 3px;
}

.sb-callout--watch .sb-callout-tag {
	color: #f87171;
}

/* A short walkthrough: numbered circles, as on a practice card. */
.sb-steps {
	list-style: none;
	counter-reset: sb-step;
	margin: 0;
	padding: 0;
}

.sb-steps li {
	counter-increment: sb-step;
	position: relative;
	padding-left: 26px;
	margin-bottom: 5px;
}

.sb-steps li:last-child {
	margin-bottom: 0;
}

.sb-steps li::before {
	content: counter(sb-step);
	position: absolute;
	left: 0;
	top: 1px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	border: 1px solid var(--sb-line);
	background: var(--sb-raised);
	color: var(--sb-sky);
	font-family: 'JetBrains Mono', ui-monospace, monospace;
	font-size: 10.5px;
	display: grid;
	place-items: center;
}

.sb-list {
	margin: 0;
	padding-left: 18px;
}

.sb-list li {
	margin-bottom: 4px;
}

/*
 * Arrival.
 *
 * Only on an answer that came in one piece: a streamed reply is re-rendered on
 * every delta, so animating it would restart the rise on every token. The
 * stagger is by block, not by character, so a two-block answer settles in a
 * third of a second and never feels like waiting.
 */
.sb-blocks.is-settled > * {
	animation: sb-rise 260ms ease-out both;
	animation-delay: calc(var(--sb-i, 0) * 60ms);
}

@keyframes sb-rise {
	from {
		opacity: 0;
		transform: translateY(6px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.sb-blocks.is-settled > * {
		animation: none;
	}
}

/* ── The line under the conversation ────────────────────────────────────── */

.sb-note {
	margin: 0 16px 8px;
	padding: 7px 10px;
	border-radius: 8px;
	font-size: 12px;
	background: rgba(167, 139, 250, 0.12);
	border: 1px solid rgba(167, 139, 250, 0.3);
	color: var(--sb-text);
}

.sb-note--charged {
	background: rgba(86, 204, 242, 0.12);
	border-color: rgba(86, 204, 242, 0.32);
}

.sb-note--saving {
	background: rgba(242, 201, 76, 0.12);
	border-color: rgba(242, 201, 76, 0.32);
}

/* Why they cannot ask: a fact, not a failure, so violet rather than red. */
.sb-note--blocked {
	background: rgba(167, 139, 250, 0.12);
	border-color: rgba(167, 139, 250, 0.32);
}

.sb-input:disabled {
	opacity: 0.55;
	cursor: not-allowed;
}

.sb-note--error {
	background: rgba(235, 87, 87, 0.12);
	border-color: rgba(235, 87, 87, 0.32);
}

/* ── Asking ─────────────────────────────────────────────────────────────── */

.sb-form {
	display: flex;
	gap: 8px;
	align-items: flex-end;
	padding: 10px 16px;
	border-top: 1px solid var(--sb-line);
	background: var(--sb-raised);
}

.sb-input {
	flex: 1;
	resize: none;
	min-height: 44px;
	max-height: 140px;
	padding: 11px 12px;
	border-radius: 10px;
	border: 1px solid var(--sb-line);
	background: var(--sb-ground);
	color: var(--sb-text);
	font-family: inherit;
	font-size: 13.5px;
	line-height: 1.5;
}

.sb-input:focus {
	outline: none;
	border-color: var(--sb-sky);
}

.sb-input::placeholder {
	color: var(--sb-dim);
}

.sb-send {
	width: 44px;
	height: 44px;
	flex: 0 0 44px;
	border-radius: 10px;
	border: 1px solid var(--sb-line);
	background: linear-gradient(140deg, #3a7bd5, #56ccf2);
	color: #0d1020;
	display: grid;
	place-items: center;
	cursor: pointer;
}

.sb-send svg {
	width: 18px;
	height: 18px;
}

.sb-send:disabled {
	opacity: 0.45;
	cursor: default;
}

.sb-foot {
	padding: 0 16px 12px;
	font-size: 11.5px;
	color: var(--sb-dim);
	line-height: 1.45;
}

/* ── Narrow screens ─────────────────────────────────────────────────────── */

@media (max-width: 720px) {
	.sb-panel {
		width: 100vw;
		border-left: 0;
	}

	.sb-fab {
		right: 14px;
		bottom: 14px;
	}
}

/* The IDE keeps a dock along the bottom on a phone; the button clears it. */
body.has-mobile-dock .sb-fab {
	bottom: 86px;
}

/* ── Asking about a rationale (StudyBuddy.askAbout) ─────────────────────────
 * A card beside the "Ask about this" button, never a full-page layer: it
 * covers only itself, so nothing on the game or quiz page stops taking clicks.
 * Created when opened and removed when closed, never shown and hidden with the
 * hidden attribute (see the rules at the top of this file).
 */
.sb-pop {
	position: fixed;
	z-index: 2147483001;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	border-radius: 14px;
	border: 1px solid var(--sb-line);
	background: var(--sb-ground);
	color: var(--sb-text);
	box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
	font-family: 'DM Sans', system-ui, sans-serif;
	font-size: 13.5px;
	text-align: left;
	animation: sb-pop-in 0.16s ease-out;
}

.sb-pop *,
.sb-pop *::before,
.sb-pop *::after {
	font-variant-ligatures: none;
	box-sizing: border-box;
}

@keyframes sb-pop-in {
	from {
		opacity: 0;
		transform: translateY(6px);
	}
}

@media (prefers-reduced-motion: reduce) {
	.sb-pop {
		animation: none;
	}
}

.sb-pop-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 10px 10px 10px 16px;
	border-bottom: 1px solid var(--sb-line);
	background: var(--sb-raised);
}

.sb-pop-title {
	font-family: 'JetBrains Mono', ui-monospace, monospace;
	font-size: 11px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--sb-violet);
}

.sb-pop-close {
	width: 36px;
	height: 36px;
	display: grid;
	place-items: center;
	border: 0;
	border-radius: 8px;
	background: transparent;
	color: var(--sb-dim);
	cursor: pointer;
}

.sb-pop-close:hover {
	color: var(--sb-text);
	background: rgba(255, 255, 255, 0.06);
}

.sb-pop-close svg {
	width: 16px;
	height: 16px;
}

.sb-pop-scroll {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	padding: 12px 16px;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.sb-pop-thread {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.sb-pop-thread:empty {
	display: none;
}

.sb-pop-label {
	font-size: 11.5px;
	color: var(--sb-dim);
}

.sb-pop-label[hidden],
.sb-pop-chips[hidden] {
	display: none !important;
}

.sb-pop-chips {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.sb-chip {
	min-height: 40px;
	padding: 8px 12px;
	border-radius: 10px;
	border: 1px solid rgba(86, 204, 242, 0.35);
	background: rgba(86, 204, 242, 0.08);
	color: var(--sb-text);
	font: inherit;
	text-align: left;
	line-height: 1.35;
	cursor: pointer;
	transition:
		background 0.12s ease,
		border-color 0.12s ease;
}

.sb-chip:hover,
.sb-chip:focus-visible {
	background: rgba(86, 204, 242, 0.16);
	border-color: var(--sb-sky);
	outline: none;
}

.sb-chip:disabled {
	opacity: 0.55;
	cursor: default;
}

.sb-pop-wait {
	color: var(--sb-dim);
	font-size: 12.5px;
}

.sb-pop .sb-note {
	margin: 0 16px 8px;
}

.sb-pop .sb-msg .sb-body {
	max-width: 92%;
}

.sb-pop-form {
	padding: 10px 12px;
}

/* ── Tabs: Ask and Explainers ───────────────────────────────────────────── */

.sb-tabs {
	display: flex;
	gap: 4px;
	padding: 8px 16px 0;
	border-bottom: 1px solid var(--sb-line);
	background: var(--sb-raised);
}

.sb-tabs[hidden],
.sb-tab[hidden],
.sb-pane[hidden],
.sb-x-indexwrap[hidden],
.sb-x-detail[hidden] {
	display: none !important;
}

.sb-tab {
	min-height: 40px;
	padding: 0 14px;
	border: 0;
	border-bottom: 2px solid transparent;
	background: none;
	color: var(--sb-dim);
	font: inherit;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
}

.sb-tab:hover {
	color: var(--sb-text);
}

.sb-tab.is-active {
	color: var(--sb-text);
	border-bottom-color: var(--sb-violet);
}

.sb-pane {
	flex: 1;
	min-height: 0;
	display: flex;
	flex-direction: column;
}

/* ── Explainers ─────────────────────────────────────────────────────────── */

.sb-x {
	overflow-y: auto;
	padding: 14px 16px 24px;
}

.sb-x-search {
	width: 100%;
	box-sizing: border-box;
	padding: 10px 12px;
	border: 1px solid var(--sb-line);
	border-radius: 10px;
	background: var(--sb-raised);
	color: var(--sb-text);
	font: inherit;
	font-size: 14px;
}

.sb-x-search:focus {
	outline: none;
	border-color: var(--sb-sky);
}

.sb-x-index {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin-top: 12px;
}

.sb-x-group {
	margin: 10px 0 2px;
	font-family: ui-monospace, 'JetBrains Mono', monospace;
	font-size: 11px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--sb-violet);
}

.sb-x-item {
	display: flex;
	flex-direction: column;
	gap: 2px;
	padding: 10px 12px;
	border: 1px solid var(--sb-line);
	border-radius: 10px;
	background: none;
	color: var(--sb-text);
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.sb-x-item:hover,
.sb-x-item:focus-visible {
	border-color: var(--sb-sky);
	outline: none;
}

.sb-x-item-title {
	font-size: 14px;
	font-weight: 600;
}

.sb-x-item-sum {
	font-size: 12px;
	color: var(--sb-dim);
	line-height: 1.45;
}

.sb-x-wait {
	color: var(--sb-dim);
	font-size: 13px;
	padding: 8px 0;
}

.sb-x-back {
	min-height: 36px;
	padding: 0 12px;
	border: 1px solid var(--sb-line);
	border-radius: 8px;
	background: none;
	color: var(--sb-dim);
	font: inherit;
	font-size: 12px;
	cursor: pointer;
}

.sb-x-back::before {
	content: '\2190\00a0';
}

.sb-x-back:hover {
	color: var(--sb-text);
}

.sb-x-title {
	margin: 14px 0 4px;
	font-size: 18px;
	font-weight: 600;
}

.sb-x-sum {
	margin: 0 0 12px;
	color: var(--sb-dim);
	font-size: 13px;
	line-height: 1.5;
}

.sb-x-body {
	font-size: 14px;
	line-height: 1.6;
}

.sb-x-body > * + * {
	margin-top: 10px;
}

.sb-x-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 12px 0;
}

.sb-x-chips-label {
	flex-basis: 100%;
	font-size: 11px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--sb-violet);
}

.sb-x-chip,
.sb-x-link {
	padding: 4px 10px;
	border: 1px solid var(--sb-line);
	border-radius: 999px;
	background: none;
	color: var(--sb-sky);
	font: inherit;
	font-size: 12px;
	cursor: pointer;
}

.sb-x-link {
	padding: 0 6px;
	font-size: inherit;
}

.sb-x-chip:hover,
.sb-x-link:hover {
	border-color: var(--sb-sky);
}

/* In a game: the right edge, half-way down, clear of the action bar and HUD. */
.sb-fab.sb-fab--edge {
	right: 0;
	bottom: auto;
	top: 50%;
	width: 40px;
	height: 48px;
	border-radius: 12px 0 0 12px;
	border-right: 0;
	transform: translateY(-50%);
}

.sb-fab.sb-fab--edge svg {
	width: 20px;
	height: 20px;
}

.sb-fab.sb-fab--edge:hover {
	transform: translateY(-50%) translateX(-2px);
}

/* A Bro Code clip at the end of an explainer (public/data/concept-videos.json). */
.sb-x-video {
	margin: 14px 0 12px;
}
.sb-x-video figcaption,
.sb-x-video-link span {
	display: block;
	font-size: 13px;
	font-weight: 600;
	margin-bottom: 6px;
}
.sb-x-video-frame {
	position: relative;
	aspect-ratio: 16 / 9;
	border-radius: 8px;
	overflow: hidden;
	border: 1px solid var(--sb-line);
}
.sb-x-video-frame iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}
.sb-x-video-link {
	display: block;
	color: inherit;
	text-decoration: none;
}
.sb-x-video-link img {
	width: 100%;
	border-radius: 8px;
	border: 1px solid var(--sb-line);
	margin-bottom: 6px;
}
.sb-x-video-link:hover span {
	color: var(--sb-sky);
}
.sb-x-video-credit {
	display: block;
	font-size: 11px;
	color: var(--sb-dim);
	margin-top: 4px;
}

/* A study guide topic in place of the concept body (guide-topics.json). */
.sb-x-guide {
	margin: 4px 0 8px;
}
.sb-x-source {
	display: inline-block;
	font-size: 12px;
	color: var(--sb-dim);
	text-decoration: underline;
	text-underline-offset: 3px;
	margin: 4px 0 8px;
}
.sb-x-source:hover {
	color: var(--sb-sky);
}
