/**
 * Fancy Fonts — front end.
 *
 * Everything is scoped under .ff-root so the plugin can never leak styles into
 * the surrounding theme, and every colour, radius and spacing value comes from
 * the custom properties generated by Design Settings.
 *
 * Fallback values are given throughout, so the plugin still looks right if the
 * generated stylesheet has not been built yet.
 */

.ff-root {
	--ff-card-fallback: #f8fafc;

	box-sizing: border-box;
	width: 100%;
	max-width: 100%;
	/* Side padding in every theme, so the input and cards never sit flush
	   against the container edge. */
	padding: 8px clamp(12px, 2vw, 20px) 28px;
	color-scheme: light;
	font-family: var(--ff-font, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
	font-size: var(--ff-text-size, 16px);
	background: var(--ff-background, transparent);
}

/*
 * Break out of the theme's centred content column when the owner asks for it.
 *
 * 100vw counts the vertical scrollbar, while the width available to the page
 * does not, so a plain 100vw breakout overhangs by the scrollbar's width and
 * puts a horizontal scrollbar at the bottom of the page. There is no CSS unit
 * for "viewport minus scrollbar", so the width is measured once in JS and
 * published as --ff-scrollbar. The 0px fallback means a browser with
 * JavaScript blocked, or one with overlay scrollbars that take no space, still
 * gets the correct full-bleed result.
 */
.ff-root--full {
	--ff-full-width: calc(100vw - var(--ff-scrollbar, 0px));
	/*
	 * !important is required, not defensive. Block themes ship
	 * `.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull))`
	 * with `margin-left: auto !important; margin-right: auto !important`, which
	 * silently beats any breakout margin we set. The element then keeps the
	 * theme's global padding as an inset while taking the full viewport width,
	 * and overhangs to the right by exactly that inset.
	 */
	width: var(--ff-full-width) !important;
	max-width: var(--ff-full-width) !important;
	margin-left: calc(50% - var(--ff-full-width) / 2) !important;
	margin-right: calc(50% - var(--ff-full-width) / 2) !important;
	padding-left: clamp(16px, 4vw, 48px);
	padding-right: clamp(16px, 4vw, 48px);
}

.ff-root *,
.ff-root *::before,
.ff-root *::after {
	box-sizing: inherit;
}

/*
 * The browser hides [hidden] elements with display:none, but that is a
 * user-agent rule — any author rule setting `display` beats it. Several
 * elements here are display:grid / flex / block AND toggled with the hidden
 * attribute (the loading skeleton, the "Show more" button, filtered category
 * chips), so without this they stay visible forever.
 */
.ff-root [hidden] {
	display: none !important;
}

.ff-root.ff-dark {
	color-scheme: dark;
	color: #e8eaed;
	/*
	 * Dark mode must paint its own surface. Without this the plugin's dark
	 * cards and sticky input sat on the theme's light page, which read as
	 * elements overlapping and text being cut off.
	 */
	background: var(--ff-background, #0f172a);
	border-radius: var(--ff-radius, 8px);
}

.ff-root.ff-dark .ff-card__name,
.ff-root.ff-dark .ff-count,
.ff-root.ff-dark .ff-counter {
	/* Low-opacity greys disappear on a dark surface. */
	opacity: .85;
}

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

/* Toolbar ----------------------------------------------------------------- */

.ff-toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	flex-wrap: wrap;
	padding: 10px 0;
	margin-bottom: 12px;
	border-bottom: 1px solid rgba(127, 127, 127, .2);
}

.ff-toolbar__brand {
	display: flex;
	align-items: center;
	gap: 8px;
}

.ff-toolbar__name {
	font-weight: 700;
	font-size: 1.05em;
}

.ff-toolbar__logo {
	max-height: 40px;
	width: auto;
}

.ff-toolbar__actions {
	display: flex;
	align-items: center;
	gap: 6px;
	/* Keeps the icons on the right even when the branding area is hidden. */
	margin-left: auto;
}

/*
 * Two of these four are anchors and two are buttons, so a theme underlining
 * its links drew a line under the gear and the heart but not under the tray
 * and theme toggle. The decoration propagates from the anchor to both spans
 * inside it, so it landed under the icon glyph as much as the label. These
 * are toolbar controls that happen to be links, never running text, so the
 * decoration is switched off on all four for a consistent row -- and again on
 * hover, which is where themes that leave links bare tend to add it back.
 */
.ff-icon-button {
	position: relative;
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	padding: 6px 10px;
	border: 0;
	background: none;
	color: inherit;
	cursor: pointer;
	border-radius: var(--ff-radius, 8px);
	font: inherit;
	line-height: 1.2;
	text-decoration: none;
}

.ff-icon-button:hover,
.ff-icon-button:focus-visible {
	background: rgba(127, 127, 127, .12);
	text-decoration: none;
}

.ff-icon-button__label {
	font-size: .72em;
}

.ff-badge {
	position: absolute;
	top: 0;
	right: 0;
	min-width: 18px;
	padding: 1px 5px;
	border-radius: 999px;
	background: var(--ff-accent, #4f46e5);
	color: #fff;
	font-size: .68em;
	font-weight: 700;
	text-align: center;
}

/* Input ------------------------------------------------------------------- */

.ff-input-wrap {
	/*
	 * Sticky AND the positioning context for the clear button. These were two
	 * separate rules, and the later `position: relative` silently cancelled the
	 * sticky behaviour — sticky already establishes a containing block, so one
	 * rule does both jobs.
	 */
	position: sticky;
	top: 0;
	z-index: 5;
	/*
	 * Shared by the padding below and the clear button's offset, so the two
	 * can never drift apart and leave the button outside the textarea.
	 */
	--ff-input-inset: 14px;
	padding: 12px var(--ff-input-inset);
	margin-bottom: 4px;
	background: var(--ff-background, #fff);
	/* Hides cards scrolling underneath the rounded input corners. */
	box-shadow: 0 6px 12px -8px rgba(0, 0, 0, .25);
}

.ff-input {
	width: 100%;
	padding: 14px 40px 14px 14px;
	border: 2px solid rgba(127, 127, 127, .25);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, var(--ff-card-fallback));
	color: inherit;
	font: inherit;
	font-size: 1.05em;
	resize: vertical;
}

.ff-input:focus {
	outline: none;
	border-color: var(--ff-accent, #4f46e5);
}

.ff-clear {
	position: absolute;
	top: 22px;
	/* Measured from the wrap's padding box, so the inset has to be added on. */
	right: calc(var(--ff-input-inset, 0px) + 10px);
	width: 26px;
	height: 26px;
	/*
	 * Themes routinely style every `button` with generous padding. Under
	 * border-box sizing that padding cannot shrink the box, so it stretches
	 * the 26px circle sideways into a grey oval - which is why this showed up
	 * on the live theme and never locally. Zeroing the padding, and any theme
	 * min-width, keeps the button exactly the size asked for; the flex centring
	 * then holds the x in the middle, since padding no longer places it.
	 *
	 * The width is clamped rather than just set, so no theme min-width can
	 * grow it back. The !important on the padding is required, not defensive:
	 * some themes and page builders mark their button padding !important, and
	 * under border-box the padding is a floor the max-width cannot clamp below,
	 * so without it the oval survives both other rules.
	 */
	min-width: 26px;
	max-width: 26px;
	padding: 0 !important;
	display: flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: 50%;
	background: rgba(127, 127, 127, .2);
	color: inherit;
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
}

.ff-input-meta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	flex-wrap: wrap;
	margin-top: 6px;
}

.ff-preview-open {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 12px;
	border: 1px solid rgba(127, 127, 127, .3);
	border-radius: 999px;
	background: var(--ff-card, var(--ff-card-fallback));
	color: inherit;
	font: inherit;
	font-size: .85em;
	cursor: pointer;
}

.ff-preview-open:hover {
	border-color: var(--ff-accent, #4f46e5);
}

.ff-counter {
	font-size: .8em;
	opacity: .7;
}

.ff-counter.is-near-limit {
	color: #b45309;
	opacity: 1;
	font-weight: 600;
}

/* Filters ----------------------------------------------------------------- */

.ff-filters {
	margin: 10px 0;
}

.ff-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.ff-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 7px 14px;
	border: 1px solid rgba(127, 127, 127, .3);
	border-radius: 999px;
	background: var(--ff-card, var(--ff-card-fallback));
	color: inherit;
	font: inherit;
	font-size: .9em;
	cursor: pointer;
}

.ff-chip:hover {
	border-color: var(--ff-accent, #4f46e5);
}

.ff-chip.is-active {
	background: var(--ff-accent, #4f46e5);
	border-color: var(--ff-accent, #4f46e5);
	color: #fff;
}

.ff-filter-panel {
	margin-top: 10px;
	padding: 14px;
	border: 1px solid rgba(127, 127, 127, .2);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, var(--ff-card-fallback));
}

.ff-filter-search {
	width: 100%;
	padding: 9px 12px;
	margin-bottom: 12px;
	border: 1px solid rgba(127, 127, 127, .3);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-background, #fff);
	color: inherit;
	font: inherit;
}

.ff-filter-group {
	margin-bottom: 12px;
}

.ff-filter-group__title {
	margin: 0 0 6px;
	font-size: .8em;
	text-transform: uppercase;
	letter-spacing: .05em;
	opacity: .7;
}

/* Sort row ---------------------------------------------------------------- */

.ff-sort-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	flex-wrap: wrap;
	margin: 12px 0;
}

.ff-count {
	font-size: .9em;
	opacity: .75;
}

.ff-select {
	padding: 7px 10px;
	border: 1px solid rgba(127, 127, 127, .3);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, var(--ff-card-fallback));
	color: inherit;
	font: inherit;
}

/* Grid -------------------------------------------------------------------- */

/* Digit index ------------------------------------------------------------- */

/*
 * The numbers page is ten small galleries rather than one long one, so each
 * digit needs a heading that reads as a section break without competing with
 * the theme's own headings.
 */
.ff-digit + .ff-digit {
	margin-top: 28px;
}

.ff-digit__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	flex-wrap: wrap;
	margin-bottom: 10px;
	padding-bottom: 6px;
	border-bottom: 1px solid rgba(127, 127, 127, .25);
}

.ff-digit__title {
	margin: 0;
	font-size: 1.5em;
	line-height: 1.2;
	/* The theme's h2 colour and weight are whatever they are; these are ours. */
	color: inherit;
	font-weight: 700;
}

/*
 * Sits below its own digit's cards as the way on to that digit's page, so it
 * is centred and given room rather than tucked beside the heading, where it
 * read as an afterthought. The button look itself comes from .ff-button and
 * .ff-button--ghost, so it tracks the admin's accent colour and radius.
 */
/*
 * Stands where the typing box would be on a digit page, so the eye lands on
 * the way onward rather than on a gap.
 */
.ff-typeown {
	margin: 4px 0 14px;
	text-align: center;
}

/* Themes underline content links; this one is a button, so it should not be. */
.ff-typeown a {
	text-decoration: none;
}

.ff-typeown a:hover,
.ff-typeown a:focus {
	border-color: var(--ff-accent, #4f46e5);
	color: var(--ff-accent, #4f46e5);
}

.ff-digit__foot {
	margin-top: 16px;
	text-align: center;
}

.ff-digit__more {
	text-decoration: none;
}

.ff-digit__more:hover,
.ff-digit__more:focus {
	border-color: var(--ff-accent, #4f46e5);
	color: var(--ff-accent, #4f46e5);
}

.ff-grid {
	display: grid;
	gap: var(--ff-gap, 14px);
	/* Column counts are set per device by the site owner. */
	grid-template-columns: repeat(var(--ff-cols-mobile, 1), minmax(0, 1fr));
}

@media (min-width: 600px) {
	.ff-grid {
		grid-template-columns: repeat(var(--ff-cols-tablet, 2), minmax(0, 1fr));
	}
}

@media (min-width: 960px) {
	.ff-grid {
		grid-template-columns: repeat(var(--ff-cols-desktop, 3), minmax(0, 1fr));
	}
}

.ff-card {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 10px;
	padding: 14px;
	border: 1px solid rgba(127, 127, 127, .18);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, var(--ff-card-fallback));
	box-shadow: var(--ff-shadow, none);
	transition: transform .12s ease, border-color .12s ease;
}

.ff-card:hover {
	transform: translateY(var(--ff-hover-lift, 0px));
	border-color: var(--ff-accent, #4f46e5);
}

.ff-card__text {
	font-size: 1.25em;
	line-height: 1.5;
	word-break: break-word;
	/* Long styled text must never widen the page. */
	overflow-wrap: break-word;
	min-height: 1.5em;
}

/*
 * Name above buttons on every card. As a wrapping row, the two shared a line
 * only when the name was short enough to fit beside the buttons, so the same
 * grid mixed both layouts, and which cards changed shape shifted with the
 * column width.
 */
.ff-card__footer {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
}

.ff-card__name {
	font-size: .8em;
	opacity: .65;
	max-width: 100%;
	overflow-wrap: anywhere;
}

/* The name, plus the compatibility note on the cards that carry one. */
.ff-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 8px;
	max-width: 100%;
}

/*
 * A small tag, not a control: soft amber, small type, no button chrome. It is
 * a span, so theme button styles never reach it; the few properties a theme
 * might still set on inline text are pinned here.
 */
.ff-root .ff-card__compat {
	position: relative;
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 3px;
	width: auto;
	margin: 0;
	padding: 1px 7px;
	border: 1px solid #fde68a;
	border-radius: 999px;
	background: #fef3c7;
	color: #92400e;
	font-size: .68em;
	font-weight: 500;
	line-height: 1.5;
	white-space: nowrap;
	text-decoration: none;
	text-transform: none;
	letter-spacing: normal;
	cursor: help;
}

.ff-card__compat-icon {
	font-size: .95em;
	line-height: 1;
}

.ff-root .ff-card__compat:hover,
.ff-root .ff-card__compat:focus {
	background: #fde68a;
	color: #92400e;
	text-decoration: none;
}

/* A tap focuses the tag too; the ring is only wanted for keyboards. */
.ff-root .ff-card__compat:focus {
	outline: none;
}

.ff-root .ff-card__compat:focus-visible {
	outline: 2px solid #b45309;
	outline-offset: 2px;
}

/*
 * The note sits at the card's left edge, so a tooltip centred on it would
 * hang off the left of the screen in the first column. It opens rightwards.
 */
.ff-root .ff-card__compat[data-ff-tip]::after {
	left: 0;
	transform: none;
	max-width: 220px;
	text-align: left;
}

/*
 * Full card width with the buttons spread across it. space-between rather
 * than space-around so the first button lines up with the name above it and
 * the last with the card's right edge.
 */
.ff-card__actions {
	display: flex;
	align-self: stretch;
	justify-content: space-between;
	align-items: center;
	gap: 4px;
	/*
	 * The owner can set up to 12 columns, and at the narrow end a card is
	 * barely wider than one button. Without wrapping, this row keeps its
	 * full width and pushes the whole page sideways.
	 */
	flex-wrap: wrap;
}

/*
 * At 320px wide the five buttons need about 225px and a card has about 202,
 * so the last one dropped onto a line of its own. Narrower icon buttons make
 * the row fit; Copy keeps its size since it is the one people press most.
 */
@media (max-width: 359px) {
	.ff-card__actions .ff-action:not(.ff-action--copy) {
		padding-left: 5px;
		padding-right: 5px;
	}
}

.ff-action {
	/* Positioning context for the tooltip below. */
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 4px;
	padding: 6px 9px;
	border: 1px solid transparent;
	border-radius: var(--ff-radius, 8px);
	background: rgba(127, 127, 127, .1);
	color: inherit;
	font: inherit;
	font-size: .82em;
	cursor: pointer;
	line-height: 1;
}

/*
 * Every icon gets the same box, whatever glyph is in it.
 *
 * These buttons were sized by their icon's own advance width, and a clipboard,
 * a heart, a plus, an arrow and a downward arrow are all different widths — so
 * the row of actions under each card came out ragged, by seven pixels between
 * the widest and the narrowest. Fixing the glyph's box rather than the
 * button's means the row stays even on a platform whose emoji are wider still,
 * which a min-width on the button would not survive.
 */
.ff-action > [aria-hidden="true"] {
	display: inline-block;
	width: 1.15em;
	text-align: center;
	/* Keeps a tall glyph from making one button taller than its neighbours. */
	line-height: 1;
}

.ff-action:hover,
.ff-action:focus-visible {
	background: rgba(127, 127, 127, .2);
}

.ff-action--like.is-active {
	color: #e0245e;
	background: rgba(224, 36, 94, .12);
}

/*
 * Shared tooltip, used by the card action icons and the toolbar icons.
 *
 * These relied on the browser's own `title` tooltip, which takes about a
 * second to appear, cannot be styled, and never shows at all on a touch
 * screen. This draws the label instead, so it appears immediately.
 *
 * Any element inside the plugin carrying data-ff-tip gets one, as long as it
 * establishes a positioning context of its own.
 */
.ff-root [data-ff-tip]::after {
	content: attr(data-ff-tip);
	position: absolute;
	bottom: calc(100% + 8px);
	left: 50%;
	transform: translateX(-50%);
	z-index: 20;
	width: max-content;
	max-width: 180px;
	padding: 6px 10px;
	border-radius: 6px;
	background: rgba(17, 24, 39, .94);
	color: #fff;
	font-size: 11px;
	line-height: 1.35;
	text-align: center;
	white-space: normal;
	/*
	 * display:none rather than opacity/visibility. A merely invisible tooltip
	 * still takes part in layout, and the ones on the right-hand icons reach
	 * past the viewport edge, which widens the page and puts a horizontal
	 * scrollbar under it.
	 */
	display: none;
	/* Never swallow a click meant for the button underneath. */
	pointer-events: none;
}

/*
 * Hover-capable pointers only: on a phone a tap counts as a hover and would
 * leave the tooltip stuck on screen after the button has been pressed.
 */
@media (hover: hover) {
	.ff-root [data-ff-tip]:hover::after {
		display: block;
	}
}

/* Keyboard users get the same label when tabbing through the icons. */
.ff-root [data-ff-tip]:focus-visible::after {
	display: block;
}

/*
 * The toolbar sits at the very top of the block, where a tooltip opening
 * upwards would run into the theme's own header. These open downwards.
 */
.ff-root .ff-icon-button[data-ff-tip]::after {
	top: calc(100% + 8px);
	bottom: auto;
}

/* States ------------------------------------------------------------------ */

.ff-empty {
	padding: 36px 16px;
	text-align: center;
	opacity: .8;
}

.ff-empty__title {
	margin: 0 0 4px;
	font-weight: 600;
}

.ff-empty__hint {
	margin: 0;
	font-size: .9em;
}

.ff-skeleton {
	display: grid;
	gap: var(--ff-gap, 14px);
	grid-template-columns: repeat(var(--ff-cols-mobile, 1), minmax(0, 1fr));
	margin-top: var(--ff-gap, 14px);
}

@media (min-width: 600px) {
	.ff-skeleton {
		grid-template-columns: repeat(var(--ff-cols-tablet, 2), minmax(0, 1fr));
	}
}

@media (min-width: 960px) {
	.ff-skeleton {
		grid-template-columns: repeat(var(--ff-cols-desktop, 3), minmax(0, 1fr));
	}
}

.ff-skeleton__card {
	height: 92px;
	border-radius: var(--ff-radius, 8px);
	background: linear-gradient(90deg, rgba(127, 127, 127, .1) 25%, rgba(127, 127, 127, .18) 50%, rgba(127, 127, 127, .1) 75%);
	background-size: 200% 100%;
	animation: ff-shimmer 1.2s infinite linear;
}

@keyframes ff-shimmer {
	to {
		background-position: -200% 0;
	}
}

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

	.ff-card {
		transition: none;
	}
}

/* Buttons ----------------------------------------------------------------- */

/*
 * Same reason as .ff-icon-button above: several of these are anchors pointing
 * at pages the owner set up, so a theme underlining its links drew a line
 * through the middle of a solid button. A button is a control, never running
 * text, so the decoration is off here and on hover too.
 */
.ff-button {
	display: inline-block;
	padding: 10px 18px;
	border: 0;
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-accent, #4f46e5);
	color: #fff;
	font: inherit;
	cursor: pointer;
	text-decoration: none;
}

.ff-button:hover,
.ff-button:focus-visible {
	text-decoration: none;
}

.ff-button--ghost {
	background: transparent;
	border: 1px solid rgba(127, 127, 127, .35);
	color: inherit;
}

.ff-load-more {
	display: block;
	margin: 20px auto 0;
}

/* Toast, tray, notices ---------------------------------------------------- */

.ff-toast {
	position: fixed;
	left: 50%;
	bottom: 24px;
	z-index: 9999;
	transform: translateX(-50%) translateY(8px);
	padding: 10px 18px;
	border-radius: 999px;
	background: rgba(17, 24, 39, .94);
	color: #fff;
	font-size: .9em;
	opacity: 0;
	transition: opacity .15s ease, transform .15s ease;
	pointer-events: none;
}

.ff-toast.is-visible {
	opacity: 1;
	transform: translateX(-50%) translateY(0);
}

.ff-tray-panel {
	position: fixed;
	right: 16px;
	bottom: 16px;
	z-index: 9998;
	width: min(320px, calc(100vw - 32px));
	max-height: 60vh;
	overflow-y: auto;
	padding: 14px;
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, #fff);
	border: 1px solid rgba(127, 127, 127, .25);
	box-shadow: 0 8px 30px rgba(0, 0, 0, .18);
}

.ff-tray-list {
	margin: 0 0 12px;
	padding: 0;
	list-style: none;
}

.ff-tray-list li {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	padding: 7px 0;
	border-bottom: 1px solid rgba(127, 127, 127, .15);
}

.ff-tray-text {
	word-break: break-word;
}

.ff-tray-actions {
	display: flex;
	gap: 8px;
}

.ff-tray-empty {
	margin: 0;
	font-size: .9em;
	opacity: .75;
}

.ff-privacy-notice {
	position: fixed;
	left: 16px;
	bottom: 16px;
	z-index: 9998;
	width: min(340px, calc(100vw - 32px));
	padding: 14px;
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, #fff);
	border: 1px solid rgba(127, 127, 127, .25);
	box-shadow: 0 8px 30px rgba(0, 0, 0, .18);
	font-size: .9em;
}

.ff-privacy-notice p {
	margin: 0 0 10px;
}

.ff-maintenance {
	padding: 40px 20px;
	text-align: center;
	border: 1px dashed rgba(127, 127, 127, .4);
	border-radius: 8px;
}

/* Ads --------------------------------------------------------------------- */

.ff-ad {
	margin: 16px 0;
	text-align: center;
	/* Reserves space so a loading ad cannot shift the page around. */
	min-height: 90px;
}

/*
 * The in-between slot is a child of the card grid, so it has to span every
 * column — left as a normal grid item it would sit in one cell and break the
 * run of cards.
 */
.ff-ad--inline {
	grid-column: 1 / -1;
	margin: 4px 0;
}

/* Preview on Profile ------------------------------------------------------ */

.ff-modal {
	position: fixed;
	inset: 0;
	z-index: 10000;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 16px;
}

.ff-modal__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, .55);
}

.ff-modal__panel {
	position: relative;
	width: min(420px, 100%);
	max-height: 88vh;
	overflow-y: auto;
	padding: 24px 22px 22px;
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, #fff);
	color: inherit;
	box-shadow: 0 18px 50px rgba(0, 0, 0, .3);
}

/*
 * The close button sets its own box, so it has to reset what the browser
 * gives a <button>: a padding of 1px 6px and display: block, which left the
 * icon sitting at the top of a 32px circle rather than in the middle of it.
 *
 * The icon is an SVG rather than the × character for the same reason the
 * markup says so: a glyph is positioned by its font's metrics, so it landed
 * differently on a phone, where the default button font is not the one this
 * was first eyeballed in. Two crossed lines centred by flex are geometric,
 * and sit dead centre whatever font the browser would have used.
 */
.ff-modal__close {
	position: absolute;
	top: 8px;
	right: 10px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(127, 127, 127, .15);
	color: inherit;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
}

/* The click always lands on the button, never on the icon inside it. */
.ff-modal__close svg {
	pointer-events: none;
}

.ff-modal__title {
	margin: 0 0 12px;
	font-size: 1.05em;
}

.ff-platforms {
	display: flex;
	gap: 6px;
	overflow-x: auto;
	/*
	 * overflow-x: auto forces overflow-y to compute to auto as well — the two
	 * axes cannot disagree — so this row clips vertically whether or not that
	 * was intended. Without padding at the top, the active button's rounded
	 * background sat flush against that clip edge and was shaved off. The
	 * padding gives the highlight somewhere to sit.
	 */
	padding-top: 6px;
	padding-bottom: 8px;
	margin-bottom: 8px;
	/* Keeps the row swipeable on a phone rather than wrapping to many lines. */
	-webkit-overflow-scrolling: touch;
}

.ff-platform {
	flex: 0 0 auto;
	padding: 8px 16px;
	line-height: 1.5;
	border: 1px solid rgba(127, 127, 127, .3);
	border-radius: 999px;
	background: transparent;
	color: inherit;
	font: inherit;
	font-size: .82em;
	cursor: pointer;
	white-space: nowrap;
}

.ff-platform.is-active {
	background: var(--ff-accent, #4f46e5);
	border-color: var(--ff-accent, #4f46e5);
	color: #fff;
}

.ff-style-pick {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 14px;
}

.ff-style-pick label {
	font-size: .85em;
	opacity: .8;
}

.ff-style-pick .ff-select {
	flex: 1;
	min-width: 0;
}

.ff-modal__disclaimer {
	margin: 12px 0 0;
	font-size: .8em;
	opacity: .7;
	text-align: center;
}

/* Platform mockups -------------------------------------------------------- */

/*
 * One markup structure, themed per platform. Every block is hidden by default
 * and each platform opts in to the parts it needs, so the mockups read as the
 * real thing rather than one generic card with a different label.
 * Pure CSS — no brand images or web fonts are loaded.
 */
.ff-mockup {
	--mock-bg: #fff;
	--mock-fg: #111;
	--mock-accent: #4f46e5;
	--mock-muted: rgba(0, 0, 0, .55);
	--mock-line: rgba(0, 0, 0, .1);

	overflow: hidden;
	border: 1px solid var(--mock-line);
	border-radius: 12px;
	background: var(--mock-bg);
	color: var(--mock-fg);
	font-size: 14px;
}

.ff-mockup__bar,
.ff-mockup__cover,
.ff-mockup__header,
.ff-mockup__stats,
.ff-mockup__bio,
.ff-mockup__actions,
.ff-mockup__chat,
.ff-mockup__tiles,
.ff-mockup__player {
	display: none;
}

.ff-mockup__bar {
	align-items: center;
	gap: 10px;
	padding: 12px 14px;
	border-bottom: 1px solid var(--mock-line);
	font-weight: 600;
}

.ff-mockup__bar-back {
	font-size: 20px;
	line-height: 1;
	opacity: .8;
}

.ff-mockup__bar-text {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.ff-mockup__cover {
	height: 72px;
	background: linear-gradient(120deg, var(--mock-accent), rgba(255, 255, 255, .35));
}

.ff-mockup__header {
	align-items: center;
	gap: 14px;
	padding: 16px;
}

.ff-mockup__avatar {
	width: 64px;
	height: 64px;
	flex: 0 0 64px;
	border-radius: 50%;
	background: linear-gradient(135deg, rgba(127, 127, 127, .35), rgba(127, 127, 127, .12));
}

.ff-mockup__meta {
	min-width: 0;
}

.ff-mockup__name {
	font-weight: 700;
	font-size: 1.05em;
	line-height: 1.45;
	word-break: break-word;
}

.ff-mockup__handle {
	font-size: .85em;
	color: var(--mock-muted);
}

.ff-mockup__stats {
	justify-content: space-around;
	gap: 10px;
	padding: 0 16px 14px;
	text-align: center;
	font-size: .8em;
	color: var(--mock-muted);
}

.ff-mockup__stats strong {
	display: block;
	font-size: 1.25em;
	color: var(--mock-fg);
}

.ff-mockup__bio {
	padding: 0 16px 14px;
	line-height: 1.6;
	word-break: break-word;
}

.ff-mockup__actions {
	gap: 8px;
	padding: 0 16px 16px;
}

.ff-mockup__button {
	flex: 1;
	padding: 8px 10px;
	border-radius: 8px;
	background: rgba(127, 127, 127, .15);
	text-align: center;
	font-size: .85em;
	font-weight: 600;
}

.ff-mockup__button--primary {
	background: var(--mock-accent);
	color: #fff;
}

.ff-mockup__chat {
	flex-direction: column;
	gap: 10px;
	padding: 16px;
	min-height: 150px;
}

.ff-mockup__bubble {
	max-width: 82%;
	padding: 9px 13px;
	border-radius: 14px;
	line-height: 1.5;
	word-break: break-word;
	box-shadow: 0 1px 1px rgba(0, 0, 0, .08);
}

.ff-mockup__bubble--in {
	align-self: flex-start;
	background: #fff;
	border-top-left-radius: 4px;
	color: #111;
}

.ff-mockup__bubble--out {
	align-self: flex-end;
	background: #d9fdd3;
	border-top-right-radius: 4px;
	color: #111;
	font-size: .9em;
}

.ff-mockup__tiles {
	grid-template-columns: repeat(3, 1fr);
	gap: 2px;
	padding: 0 2px 2px;
}

.ff-mockup__tiles span {
	aspect-ratio: 1;
	background: rgba(127, 127, 127, .18);
}

.ff-mockup__player {
	flex-direction: column;
	align-items: center;
	gap: 8px;
	padding: 22px 16px;
	text-align: center;
}

.ff-mockup__level {
	padding: 3px 12px;
	border-radius: 999px;
	background: rgba(255, 196, 0, .2);
	border: 1px solid rgba(255, 196, 0, .55);
	color: #ffc400;
	font-size: .72em;
	font-weight: 700;
	letter-spacing: .08em;
}

.ff-mockup__player-name {
	font-size: 1.3em;
	font-weight: 800;
	letter-spacing: .02em;
	word-break: break-word;
}

/* Instagram: profile header, stats, bio, photo grid. */
[data-ff-platform-current="instagram"] {
	--mock-accent: #d62976;
}

[data-ff-platform-current="instagram"] .ff-mockup__bar,
[data-ff-platform-current="instagram"] .ff-mockup__header,
[data-ff-platform-current="instagram"] .ff-mockup__stats,
[data-ff-platform-current="instagram"] .ff-mockup__bio {
	display: flex;
}

[data-ff-platform-current="instagram"] .ff-mockup__tiles {
	display: grid;
}

[data-ff-platform-current="instagram"] .ff-mockup__avatar {
	background: linear-gradient(45deg, #f09433, #dc2743, #bc1888);
	padding: 3px;
	box-shadow: inset 0 0 0 3px #fff;
}

/* Facebook: blue bar, cover photo, name and actions. */
[data-ff-platform-current="facebook"] {
	--mock-accent: #1877f2;
}

[data-ff-platform-current="facebook"] .ff-mockup__bar,
[data-ff-platform-current="facebook"] .ff-mockup__header,
[data-ff-platform-current="facebook"] .ff-mockup__bio,
[data-ff-platform-current="facebook"] .ff-mockup__actions {
	display: flex;
}

[data-ff-platform-current="facebook"] .ff-mockup__cover {
	display: block;
}

[data-ff-platform-current="facebook"] .ff-mockup__bar {
	background: #1877f2;
	color: #fff;
	border-bottom: 0;
}

[data-ff-platform-current="facebook"] .ff-mockup__header {
	margin-top: -34px;
}

[data-ff-platform-current="facebook"] .ff-mockup__avatar {
	box-shadow: 0 0 0 4px #fff;
}

/* WhatsApp: green header over the familiar chat wallpaper. */
[data-ff-platform-current="whatsapp"] {
	--mock-bg: #ece5dd;
	--mock-accent: #25d366;
}

[data-ff-platform-current="whatsapp"] .ff-mockup__bar,
[data-ff-platform-current="whatsapp"] .ff-mockup__chat {
	display: flex;
}

[data-ff-platform-current="whatsapp"] .ff-mockup__bar {
	background: #075e54;
	color: #fff;
	border-bottom: 0;
}

/* Telegram: blue header, pale blue outgoing bubbles. */
[data-ff-platform-current="telegram"] {
	--mock-bg: #e7ebf0;
	--mock-accent: #2aabee;
}

[data-ff-platform-current="telegram"] .ff-mockup__bar,
[data-ff-platform-current="telegram"] .ff-mockup__chat {
	display: flex;
}

[data-ff-platform-current="telegram"] .ff-mockup__bar {
	background: #2aabee;
	color: #fff;
	border-bottom: 0;
}

[data-ff-platform-current="telegram"] .ff-mockup__bubble--out {
	background: #eeffde;
}

/* Twitter / X: black, name over handle, follower counts. */
[data-ff-platform-current="twitter"] {
	--mock-bg: #000;
	--mock-fg: #e7e9ea;
	--mock-accent: #1d9bf0;
	--mock-muted: #71767b;
	--mock-line: #2f3336;
}

[data-ff-platform-current="twitter"] .ff-mockup__header,
[data-ff-platform-current="twitter"] .ff-mockup__bio,
[data-ff-platform-current="twitter"] .ff-mockup__stats {
	display: flex;
}

[data-ff-platform-current="twitter"] .ff-mockup__cover {
	display: block;
	height: 60px;
	background: #333639;
}

[data-ff-platform-current="twitter"] .ff-mockup__header {
	margin-top: -28px;
}

[data-ff-platform-current="twitter"] .ff-mockup__avatar {
	box-shadow: 0 0 0 3px #000;
}

/* TikTok: dark, centred profile with a red follow button. */
[data-ff-platform-current="tiktok"] {
	--mock-bg: #111;
	--mock-fg: #fff;
	--mock-accent: #fe2c55;
	--mock-muted: rgba(255, 255, 255, .6);
	--mock-line: rgba(255, 255, 255, .12);
}

[data-ff-platform-current="tiktok"] .ff-mockup__header,
[data-ff-platform-current="tiktok"] .ff-mockup__stats,
[data-ff-platform-current="tiktok"] .ff-mockup__bio,
[data-ff-platform-current="tiktok"] .ff-mockup__actions {
	display: flex;
}

[data-ff-platform-current="tiktok"] .ff-mockup__header {
	flex-direction: column;
	text-align: center;
	padding-top: 22px;
}

[data-ff-platform-current="tiktok"] .ff-mockup__bio {
	text-align: center;
}

[data-ff-platform-current="tiktok"] .ff-mockup__tiles {
	display: grid;
}

/* Snapchat: the unmistakable yellow. */
[data-ff-platform-current="snapchat"] {
	--mock-bg: #fffc00;
	--mock-fg: #111;
	--mock-accent: #111;
	--mock-line: rgba(0, 0, 0, .15);
}

[data-ff-platform-current="snapchat"] .ff-mockup__header,
[data-ff-platform-current="snapchat"] .ff-mockup__bio,
[data-ff-platform-current="snapchat"] .ff-mockup__actions {
	display: flex;
}

[data-ff-platform-current="snapchat"] .ff-mockup__header {
	flex-direction: column;
	text-align: center;
	padding-top: 24px;
}

[data-ff-platform-current="snapchat"] .ff-mockup__avatar {
	background: #fff;
	box-shadow: 0 2px 6px rgba(0, 0, 0, .15);
}

/* Discord: dark member panel with a coloured role name. */
[data-ff-platform-current="discord"] {
	--mock-bg: #313338;
	--mock-fg: #f2f3f5;
	--mock-accent: #5865f2;
	--mock-muted: #b5bac1;
	--mock-line: rgba(255, 255, 255, .08);
}

[data-ff-platform-current="discord"] .ff-mockup__header,
[data-ff-platform-current="discord"] .ff-mockup__bio,
[data-ff-platform-current="discord"] .ff-mockup__actions {
	display: flex;
}

[data-ff-platform-current="discord"] .ff-mockup__cover {
	display: block;
	height: 56px;
	background: #5865f2;
}

[data-ff-platform-current="discord"] .ff-mockup__header {
	margin-top: -30px;
}

[data-ff-platform-current="discord"] .ff-mockup__avatar {
	box-shadow: 0 0 0 5px #313338;
}

[data-ff-platform-current="discord"] .ff-mockup__name {
	color: #7ee787;
}

[data-ff-platform-current="discord"] .ff-mockup__bio {
	margin: 0 16px 16px;
	padding: 12px;
	border-radius: 8px;
	background: #232428;
}

/* Gaming: neon player card for PUBG, Free Fire and general gaming. */
[data-ff-platform-current="pubg"],
[data-ff-platform-current="freefire"],
[data-ff-platform-current="gaming"] {
	--mock-bg: #10141c;
	--mock-fg: #fff;
	--mock-muted: rgba(255, 255, 255, .6);
	--mock-line: rgba(255, 255, 255, .12);
}

[data-ff-platform-current="pubg"] .ff-mockup__player,
[data-ff-platform-current="freefire"] .ff-mockup__player,
[data-ff-platform-current="gaming"] .ff-mockup__player,
[data-ff-platform-current="pubg"] .ff-mockup__stats,
[data-ff-platform-current="freefire"] .ff-mockup__stats,
[data-ff-platform-current="gaming"] .ff-mockup__stats {
	display: flex;
}

[data-ff-platform-current="pubg"] {
	--mock-accent: #f2a900;
	background: radial-gradient(circle at 50% 0%, #2a2313, #10141c 70%);
}

[data-ff-platform-current="freefire"] {
	--mock-accent: #ff5a1f;
	background: radial-gradient(circle at 50% 0%, #331a12, #10141c 70%);
}

[data-ff-platform-current="freefire"] .ff-mockup__level {
	background: rgba(255, 90, 31, .18);
	border-color: rgba(255, 90, 31, .55);
	color: #ff8a5c;
}

[data-ff-platform-current="gaming"] {
	--mock-accent: #22d3ee;
	background: radial-gradient(circle at 50% 0%, #10303a, #10141c 70%);
}

[data-ff-platform-current="gaming"] .ff-mockup__level {
	background: rgba(34, 211, 238, .15);
	border-color: rgba(34, 211, 238, .5);
	color: #22d3ee;
}

/* Font Mixer ---------------------------------------------------------------
 *
 * The mixer shares the generator's shell (.ff-root), so colours, radius and
 * spacing all come from the same custom properties set in Design Settings.
 */

.ff-mixer-root {
	/* The picker is positioned against this, not the page. */
	position: relative;
}

.ff-tabs {
	display: flex;
	gap: 6px;
	margin-bottom: 10px;
}

.ff-tab {
	flex: 0 0 auto;
	padding: 8px 18px;
	border: 1px solid rgba(127, 127, 127, .3);
	border-radius: 999px;
	background: transparent;
	color: inherit;
	font: inherit;
	font-size: .9em;
	cursor: pointer;
}

.ff-tab.is-active {
	background: var(--ff-accent, #4f46e5);
	border-color: var(--ff-accent, #4f46e5);
	color: #fff;
}

.ff-mixer-hint {
	margin: 0 0 10px;
	font-size: .85em;
	opacity: .75;
}

.ff-mixer-input {
	/* Not sticky: the character boxes below it have to stay in view together. */
	position: static;
	box-shadow: none;
}

/* One box per character of the input. */
.ff-keys {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 14px 0;
}

.ff-key {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	min-width: 56px;
}

.ff-key__glyph {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 46px;
	padding: 6px 8px;
	border: 1px solid rgba(127, 127, 127, .3);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, var(--ff-card-fallback));
	color: inherit;
	font: inherit;
	font-size: 1.35em;
	line-height: 1.3;
	cursor: pointer;
}

.ff-key__glyph:hover,
.ff-key__glyph:focus-visible {
	border-color: var(--ff-accent, #4f46e5);
}

.ff-key__name {
	max-width: 72px;
	overflow: hidden;
	font-size: .65em;
	line-height: 1.2;
	text-align: center;
	text-overflow: ellipsis;
	white-space: nowrap;
	opacity: .7;
}

.ff-key__lock {
	padding: 2px 6px;
	border: 0;
	border-radius: 999px;
	background: rgba(127, 127, 127, .12);
	font-size: .75em;
	line-height: 1.4;
	cursor: pointer;
}

.ff-key__lock.is-locked {
	background: rgba(224, 36, 94, .14);
}

.ff-mixer-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 16px;
}

.ff-button--ghost {
	background: transparent;
	border: 1px solid rgba(127, 127, 127, .3);
	color: inherit;
}

/* The combined output. */
.ff-result {
	padding: 16px;
	border: 1px solid rgba(127, 127, 127, .2);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, var(--ff-card-fallback));
}

.ff-result__title {
	margin: 0 0 8px;
	font-size: .8em;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	opacity: .6;
}

.ff-result__text {
	margin-bottom: 12px;
	font-size: 1.5em;
	line-height: 1.5;
	word-break: break-word;
	overflow-wrap: break-word;
	min-height: 1.5em;
}

.ff-result__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.ff-result__actions .ff-action.is-active {
	color: #e0245e;
	background: rgba(224, 36, 94, .12);
}

/* Per-character style picker ------------------------------------------------
 *
 * A popover rather than a <select>: with a hundred styles a dropdown of names
 * tells the visitor nothing, so each choice is previewed as the actual
 * character they are styling.
 */
.ff-picker {
	position: absolute;
	z-index: 30;
	width: min(320px, calc(100% - 8px));
	padding: 10px;
	border: 1px solid rgba(127, 127, 127, .25);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, var(--ff-card-fallback));
	box-shadow: 0 12px 28px -12px rgba(0, 0, 0, .45);
}

.ff-picker__head {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 8px;
}

.ff-picker__search {
	flex: 1;
	min-width: 0;
	padding: 7px 10px;
	border: 1px solid rgba(127, 127, 127, .3);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-background, #fff);
	color: inherit;
	font: inherit;
	font-size: .85em;
}

.ff-picker__close {
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	border: 0;
	border-radius: 50%;
	background: rgba(127, 127, 127, .15);
	color: inherit;
	font-size: 17px;
	line-height: 1;
	cursor: pointer;
}

.ff-picker__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
	gap: 6px;
	/* Caps the popover's height so a long list scrolls inside it. */
	max-height: 260px;
	overflow-y: auto;
}

.ff-picker__tile {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	padding: 7px 4px;
	border: 1px solid transparent;
	border-radius: var(--ff-radius, 8px);
	background: rgba(127, 127, 127, .08);
	color: inherit;
	font: inherit;
	cursor: pointer;
}

.ff-picker__tile:hover,
.ff-picker__tile:focus-visible {
	border-color: var(--ff-accent, #4f46e5);
}

.ff-picker__tile.is-active {
	border-color: var(--ff-accent, #4f46e5);
	background: rgba(79, 70, 229, .12);
}

.ff-picker__glyph {
	font-size: 1.25em;
	line-height: 1.3;
}

.ff-picker__name {
	max-width: 100%;
	overflow: hidden;
	font-size: .6em;
	text-align: center;
	text-overflow: ellipsis;
	white-space: nowrap;
	opacity: .7;
}

.ff-picker__empty {
	margin: 10px 0 2px;
	font-size: .85em;
	text-align: center;
	opacity: .7;
}

/* Favourites ----------------------------------------------------------------
 *
 * The grid and cards are the generator's, so only the pieces unique to this
 * page are defined here.
 */

.ff-device-notice {
	margin: 0 0 14px;
	padding: 8px 12px;
	border-radius: var(--ff-radius, 8px);
	background: rgba(127, 127, 127, .1);
	font-size: .82em;
	opacity: .85;
}

.ff-favorites-root .ff-empty .ff-button {
	margin-top: 10px;
}

/* Mixes saved from the Font Mixer: text, not styles, so a list rather than cards. */
.ff-mixes {
	margin-top: 22px;
}

.ff-mixes__title {
	margin: 0 0 10px;
	font-size: .8em;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	opacity: .6;
}

.ff-mixes__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.ff-mixes__row {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 10px 12px;
	margin-bottom: 8px;
	border: 1px solid rgba(127, 127, 127, .18);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, var(--ff-card-fallback));
}

.ff-mixes__text {
	flex: 1;
	min-width: 0;
	font-size: 1.15em;
	line-height: 1.5;
	word-break: break-word;
	overflow-wrap: break-word;
}

/* Shared result -------------------------------------------------------------
 *
 * One page serves every share, so this is deliberately plain: the shared text
 * is the reason somebody followed the link, and the call to action is the
 * reason the page exists.
 */

.ff-shared {
	padding: 28px 20px;
	margin-bottom: 18px;
	border: 1px solid rgba(127, 127, 127, .2);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, var(--ff-card-fallback));
	text-align: center;
}

.ff-shared__text {
	margin-bottom: 10px;
	font-size: 2em;
	line-height: 1.45;
	word-break: break-word;
	overflow-wrap: break-word;
}

.ff-shared__name {
	margin: 0 0 16px;
	font-size: .85em;
	opacity: .65;
}

.ff-shared__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	justify-content: center;
}

.ff-shared__actions .ff-action.is-active {
	color: #e0245e;
	background: rgba(224, 36, 94, .12);
}

.ff-shared__cta {
	padding: 20px;
	border-radius: var(--ff-radius, 8px);
	background: rgba(127, 127, 127, .08);
	text-align: center;
}

.ff-shared__cta-text {
	margin: 0 0 12px;
	font-size: .95em;
}

.ff-button--large {
	padding: 12px 26px;
	font-size: 1.05em;
}

/* Share popup ---------------------------------------------------------------
 *
 * Reuses the modal shell from Preview on Profile. Sharing always opens this,
 * so the visitor sees where the link is going instead of it being copied
 * silently.
 */

.ff-share-preview {
	padding: 12px;
	margin-bottom: 14px;
	border-radius: var(--ff-radius, 8px);
	background: rgba(127, 127, 127, .08);
	font-size: 1.2em;
	line-height: 1.4;
	text-align: center;
	word-break: break-word;
	overflow-wrap: break-word;
}

.ff-share-options {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
	gap: 8px;
	margin-bottom: 14px;
}

.ff-share-option {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 5px;
	padding: 12px 6px;
	border: 1px solid rgba(127, 127, 127, .22);
	border-radius: var(--ff-radius, 8px);
	background: transparent;
	color: inherit;
	font: inherit;
	font-size: .8em;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
}

.ff-share-option:hover,
.ff-share-option:focus-visible {
	border-color: var(--ff-accent, #4f46e5);
}

.ff-share-option__icon {
	font-size: 1.5em;
	line-height: 1;
}

.ff-share-option__label {
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* The link itself, for anyone who would rather select it by hand. */
.ff-share-link {
	width: 100%;
	padding: 9px 11px;
	border: 1px solid rgba(127, 127, 127, .3);
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-background, #fff);
	color: inherit;
	font: inherit;
	font-size: .8em;
}

/* Cookie consent ------------------------------------------------------------
 *
 * Asks before any ad code is put into the page, which is why the ad slots are
 * held in templates until a choice is made.
 */

.ff-consent {
	position: fixed;
	left: 16px;
	right: 16px;
	bottom: 16px;
	z-index: 9999;
	max-width: 640px;
	margin: 0 auto;
	padding: 14px 16px;
	border-radius: var(--ff-radius, 8px);
	background: var(--ff-card, #fff);
	border: 1px solid rgba(127, 127, 127, .25);
	box-shadow: 0 10px 34px rgba(0, 0, 0, .22);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;
}

.ff-consent__text {
	flex: 1 1 260px;
	margin: 0;
	font-size: .85em;
	line-height: 1.45;
}

.ff-consent__actions {
	display: flex;
	gap: 8px;
	flex: 0 0 auto;
}

/* The owner's reminder that maintenance mode is on. */
.ff-maintenance-flag {
	padding: 10px 14px;
	margin-bottom: 14px;
	border-radius: var(--ff-radius, 8px);
	border: 1px solid rgba(217, 119, 6, .45);
	background: rgba(217, 119, 6, .12);
}

.ff-maintenance-flag p {
	margin: 0;
	font-size: .85em;
}
