:root {
	--shell-rail-size: 4rem;
	--shell-top-size: 2.25rem;
}

#shell {
	display: flex;
	flex-direction: column;
	min-block-size: 100dvb;
}

#shell > header {
	align-items: center;
	background-attachment: fixed;
	background-blend-mode: soft-light;
	background-color: var(--gray-1);
	background-image: url("/images/textures/texture-01.jpg");
	background-size: 400px;
	block-size: var(--shell-top-size);
	display: flex;
	inset-block-start: 0;
	inset-inline: 0;
	justify-content: space-between;
	padding-inline: 0.5rem;
	position: fixed;
	z-index: 30;
}

#shell > header::before,
#shell > header::after {
	block-size: 0.375rem;
	content: "";
	inset-inline: 0;
	mask-image: url("/images/torn-edge.svg");
	mask-position: center;
	mask-repeat: repeat-x;
	mask-size: 3840px 100%;
	position: absolute;
}

#shell > header::before {
	background-color: color-mix(in srgb, var(--gray-9) 15%, transparent);
	filter: blur(0.25rem);
	inset-block-start: calc(100% + 2px);
}

#shell > header::after {
	background-attachment: fixed;
	background-blend-mode: soft-light;
	background-color: var(--gray-1);
	background-image: url("/images/textures/texture-01.jpg");
	background-size: 400px;
	inset-block-start: 100%;
}

@media (prefers-color-scheme: dark) {
	#shell > header,
	#shell > header::after {
		background-blend-mode: normal, soft-light;
		background-image: linear-gradient(
				color-mix(in srgb, var(--gray-1) 70%, transparent),
				color-mix(in srgb, var(--gray-1) 70%, transparent)
			),
			url("/images/textures/texture-01.jpg");
		background-size: auto, 400px;
	}

	#shell > header::before {
		background-color: color-mix(in srgb, var(--gray-1) 65%, transparent);
	}
}

nav[aria-label="Breadcrumb"] {
	align-items: center;
	display: flex;
}

nav[aria-label="Breadcrumb"] ol {
	align-items: center;
	display: flex;
	gap: 0.5rem;
	list-style: none;
}

nav[aria-label="Breadcrumb"] a {
	align-items: center;
	color: var(--gray-11);
	display: flex;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	gap: 0.375rem;
	text-decoration: none;
}

nav[aria-label="Breadcrumb"] a:hover {
	color: var(--gray-12);
}

/* Board trail: a faint slash before each crumb, the current board shown muted (not a link). */
nav[aria-label="Breadcrumb"] [data-crumb] {
	align-items: center;
	display: flex;
	gap: 0.5rem;
}

nav[aria-label="Breadcrumb"] [data-crumb]::before {
	color: var(--gray-9);
	content: "/";
	font-size: 0.6875rem;
}

nav[aria-label="Breadcrumb"] [data-crumb] [aria-current="page"] {
	align-items: center;
	color: var(--gray-11);
	display: flex;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	gap: 0.375rem;
}

/* Crumbs double as drop targets, so give them room to breathe — and a matching offset margin so the
   padding doesn't push the trail wider at rest. */
nav[aria-label="Breadcrumb"] [data-crumb-drop] {
	border-radius: 0.375rem;
	margin-inline: -0.375rem;
	padding-block: 0.25rem;
	padding-inline: 0.375rem;
}

/* A widget dragged over a crumb drops into that ancestor board (Home = root) — ring it in our usual
   dark border so it reads as the live drop target, matching the board tile's drop highlight. */
nav[aria-label="Breadcrumb"] [data-crumb-drop][data-board-over] {
	box-shadow: 0 0 0 0.1875rem var(--gray-12);
	color: var(--gray-12);
}

/* A little block in the board's colour (the bold step-9 tile fill) before its crumb name. */
nav[aria-label="Breadcrumb"] [data-crumb-chip] {
	background-color: var(--bold, var(--gray-4));
	block-size: 1rem;
	border-radius: 0.25rem;
	flex-shrink: 0;
	inline-size: 1rem;
}

nav[aria-label="Breadcrumb"] a > span {
	align-items: center;
	background-color: var(--gray-12);
	block-size: 1.25rem;
	border-radius: 50%;
	color: var(--gray-1);
	display: flex;
	flex-shrink: 0;
	inline-size: 1.25rem;
	justify-content: center;
}

aside[aria-label="Tools"] {
	background-blend-mode: soft-light;
	background-color: var(--gray-3);
	background-image: url("/images/textures/texture-21.jpg");
	background-size: 400px;
	border-inline-end: 1px solid var(--gray-6);
	display: flex;
	flex-direction: column;
	inline-size: var(--shell-rail-size);
	inset-block-end: 0;
	inset-block-start: var(--shell-top-size);
	inset-inline-start: 0;
	overflow: hidden;
	position: fixed;
	z-index: 20;
}

@media (prefers-color-scheme: dark) {
	aside[aria-label="Tools"] {
		background-blend-mode: normal, soft-light;
		background-image: linear-gradient(
				color-mix(in srgb, var(--gray-3) 70%, transparent),
				color-mix(in srgb, var(--gray-3) 70%, transparent)
			),
			url("/images/textures/texture-21.jpg");
		background-size: auto, 400px;
	}
}

aside[aria-label="Tools"] > menu[aria-label="Widgets"] {
	align-items: center;
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 1rem;
	list-style: none;
	min-block-size: 0;
	overflow-y: auto;
	padding-block: 0.75rem;
}

aside[aria-label="Tools"] > menu[aria-label="Trash"] {
	align-items: center;
	border-block-start: 1px solid var(--gray-6);
	display: flex;
	flex-direction: column;
	flex-shrink: 0;
	list-style: none;
	padding-block: 0.75rem;
}

aside[aria-label="Tools"] > menu[data-options] {
	align-items: center;
	display: none;
	flex: 1;
	flex-direction: column;
	gap: 0.75rem;
	list-style: none;
	min-block-size: 0;
	overflow-y: auto;
	padding-block-end: 0.75rem;
}

aside[aria-label="Tools"][data-selection] > menu[aria-label="Widgets"] {
	display: none;
}

aside[aria-label="Tools"][data-selection]:not([data-editing]) > menu[data-options="widget"] {
	display: flex;
}

aside[aria-label="Tools"][data-editing] > menu[data-options="text"] {
	display: flex;
}

aside[aria-label="Tools"] > menu[data-options] > li:first-child {
	align-self: stretch;
	border-block-end: 1px solid var(--gray-6);
	display: flex;
	justify-content: center;
	padding-block: 0.5rem;
}

aside[aria-label="Tools"] > menu[data-options] > li:first-child button {
	transform: translateY(0.125rem);
}

aside[aria-label="Tools"] > menu[data-options] [data-rail-back] > span {
	block-size: auto;
}

aside[aria-label="Tools"] button[data-option][data-active] > span,
aside[aria-label="Tools"] button[data-cmd][data-active] > span,
aside[aria-label="Tools"] button[popovertarget="link-popover"][data-active] > span,
aside[aria-label="Tools"] button[popovertarget="text-style"][data-active] > span {
	background-color: var(--gray-12);
	border-radius: 0.25rem;
	color: var(--gray-1);
}

aside[aria-label="Tools"] button[popovertarget="text-style"][data-active] > span {
	background-color: var(--gray-5);
	color: var(--gray-12);
}


aside[aria-label="Tools"] button {
	align-items: center;
	background: none;
	border: 0;
	color: var(--gray-11);
	cursor: pointer;
	display: flex;
	flex-direction: column;
	font-size: 0.6rem;
	font-weight: 500;
	gap: 0.25rem;
	padding: 0;
}

aside[aria-label="Tools"] button > span {
	align-items: center;
	block-size: 1.75rem;
	display: flex;
	inline-size: 2.25rem;
	justify-content: center;
}

aside[aria-label="Tools"] button > span:not([data-bare]) {
	border: 1px solid var(--gray-6);
	border-radius: 0.25rem;
	box-shadow: 0 1px 2px color-mix(in srgb, var(--gray-10) 12%, transparent);
}

aside[aria-label="Tools"] button > span:not([data-bare]):not([data-surface]) {
	background-color: var(--gray-1);
	color: var(--gray-12);
}

aside[aria-label="Tools"] button:hover > span:not([data-bare]):not([data-surface]) {
	background-color: var(--gray-2);
	border-color: var(--gray-7);
}

aside[aria-label="Tools"] button:hover > span[data-bare] {
	color: var(--gray-12);
}

aside[aria-label="Tools"] button[data-soon] {
	cursor: default;
	opacity: 0.6;
}

aside[aria-label="Tools"] > menu[aria-label="Trash"] button[data-drop-active] {
	color: var(--tomato-9);
}

aside[aria-label="Tools"] > menu[aria-label="Trash"] button[data-drop-active] > span {
	scale: 1.2;
}

[data-tint="grass"] {
	--icon-accent: var(--grass-9);
}

[data-tint="iris"] {
	--icon-accent: var(--iris-9);
}

[data-tint="lime"] {
	--icon-accent: var(--lime-9);
}

[data-tint="mint"] {
	--icon-accent: var(--mint-9);
}

[data-tint="sky"] {
	--icon-accent: var(--sky-9);
}

[data-tint="tomato"] {
	--icon-accent: var(--tomato-9);
}

[data-tint="yellow"] {
	--icon-accent: var(--yellow-9);
}

aside[aria-label="Tools"] button > span[data-surface="blue"] {
	background-color: var(--blue-9);
	block-size: 2.25rem;
	border-color: var(--blue-10);
	color: var(--gray-1);
	color-scheme: light;
}

aside[aria-label="Tools"] button:hover > span[data-surface="blue"] {
	background-color: var(--blue-10);
	border-color: var(--blue-11);
}

aside[aria-label="Tools"] button > span[data-surface="gray"] {
	background-color: var(--gray-10);
	block-size: 2.25rem;
	border-color: var(--gray-11);
	color: var(--gray-1);
	color-scheme: light;
}

aside[aria-label="Tools"] button:hover > span[data-surface="gray"] {
	background-color: var(--gray-11);
	border-color: var(--gray-12);
}

@media (prefers-color-scheme: dark) {
	aside[aria-label="Tools"] button > span:not([data-bare]):not([data-surface]) {
		background-color: var(--gray-5);
		border-color: var(--gray-6);
		box-shadow: 0 1px 2px color-mix(in srgb, var(--gray-1) 40%, transparent);
	}

	aside[aria-label="Tools"] button:hover > span:not([data-bare]):not([data-surface]) {
		background-color: var(--gray-6);
		border-color: var(--gray-7);
	}

	[data-tint="grass"] {
		--icon-accent: var(--grass-6);
	}

	[data-tint="iris"] {
		--icon-accent: var(--iris-6);
	}

	[data-tint="lime"] {
		--icon-accent: var(--lime-6);
	}

	[data-tint="mint"] {
		--icon-accent: var(--mint-6);
	}

	[data-tint="sky"] {
		--icon-accent: var(--sky-6);
	}

	[data-tint="tomato"] {
		--icon-accent: var(--tomato-6);
	}

	[data-tint="yellow"] {
		--icon-accent: var(--yellow-6);
	}
}

aside[aria-label="Tools"] button > span[data-overflow]:not([data-surface]) {
	background-color: var(--gray-6);
	block-size: 0.75rem;
	border: 0;
	border-radius: 0.125rem;
	box-shadow: none;
	inline-size: 1.5rem;
}

aside[aria-label="Tools"] button:hover > span[data-overflow]:not([data-surface]) {
	background-color: var(--gray-7);
}

#widget-overflow,
#color-picker,
#text-style,
#link-popover {
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.5rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	list-style: none;
	margin: 0;
	padding: 0.875rem;
	position: fixed;
}

#link-popover {
	padding: 0.5rem;
}

#link-popover:popover-open {
	display: block;
}

#link-popover [data-link-input] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	inline-size: 13rem;
	outline: none;
	padding-block: 0.375rem;
	padding-inline: 0.625rem;
}

#link-popover [data-link-input]:focus {
	border-color: var(--gray-8);
}

#link-popover [data-link-input]::placeholder {
	color: var(--gray-9);
}

#widget-overflow:popover-open {
	display: grid;
	gap: 0.75rem 0.5rem;
	grid-template-columns: repeat(3, 4rem);
}

#color-picker:popover-open {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

#widget-overflow::before,
#widget-overflow::after,
#color-picker::before,
#color-picker::after,
#text-style::before,
#text-style::after {
	border-block: 0.5rem solid transparent;
	content: "";
	inset-block-start: var(--notch-top, 50%);
	position: absolute;
	transform: translateY(-50%);
}

#widget-overflow::before,
#color-picker::before,
#text-style::before {
	border-inline-end: 0.5rem solid var(--gray-6);
	filter: drop-shadow(-1px 1px 1.5px color-mix(in srgb, var(--gray-10) 16%, transparent));
	inset-inline-end: 100%;
}

#widget-overflow::after,
#color-picker::after,
#text-style::after {
	border-inline-end: 0.5rem solid var(--gray-3);
	inset-inline-end: calc(100% - 1px);
}

#widget-overflow li,
#color-picker li {
	display: flex;
}

#widget-overflow button {
	font-size: 0.6875rem;
	gap: 0.375rem;
	inline-size: 100%;
}

#emoji-picker {
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.5rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	margin: 0;
	padding: 0;
	position: fixed;
}

#shape-picker {
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.5rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	margin: 0;
	padding: 0;
	position: fixed;
}

#shape-picker:popover-open {
	block-size: 26rem;
	display: flex;
	inline-size: 26rem;
}

#shape-picker [data-shape-nav] {
	border-inline-end: 1px solid var(--gray-6);
	display: flex;
	flex-direction: column;
	flex-shrink: 0;
	gap: 0.125rem;
	inline-size: 8rem;
	overflow-y: auto;
	padding: 0.5rem;
}

#shape-picker [data-shape-nav] button {
	background: none;
	border: 0;
	border-radius: 0.375rem;
	color: var(--gray-11);
	cursor: pointer;
	display: block;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 500;
	padding-block: 0.375rem;
	padding-inline: 0.5rem;
	text-align: start;
}

#shape-picker [data-shape-nav] button:hover {
	background-color: var(--gray-4);
	color: var(--gray-12);
}

#shape-picker [data-shape-body] {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-inline-size: 0;
}

#shape-picker [data-shape-search] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	margin: 0.5rem;
	outline: none;
	padding-block: 0.375rem;
	padding-inline: 0.625rem;
}

#shape-picker [data-shape-search]:focus {
	border-color: var(--gray-8);
}

#shape-picker [data-shape-search]::placeholder {
	color: var(--gray-9);
}

#shape-picker [data-shape-scroll] {
	flex: 1;
	overflow-x: hidden;
	overflow-y: auto;
	padding-block-end: 0.5rem;
	padding-inline: 0.5rem;
}

#shape-picker section[hidden],
#shape-picker [data-shape-grid] button[hidden],
#shape-picker [data-shape-nav][hidden] {
	display: none;
}

#shape-picker h3 {
	background-color: var(--gray-3);
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	inset-block-start: 0;
	margin: 0;
	padding-block: 0.5rem 0.25rem;
	position: sticky;
}

#shape-picker [data-shape-grid] {
	display: grid;
	gap: 0.125rem;
	grid-template-columns: repeat(auto-fill, minmax(3.5rem, 1fr));
}

#shape-picker [data-shape-grid] button {
	align-items: center;
	aspect-ratio: 1;
	background: none;
	border: 0;
	border-radius: 0.375rem;
	color: var(--shape-fill, var(--gray-12));
	cursor: pointer;
	display: flex;
	justify-content: center;
	padding: 0.625rem;
}

#shape-picker [data-shape-grid] button:hover {
	background-color: var(--gray-4);
}

#shape-picker [data-shape-grid] button svg {
	block-size: 100%;
	inline-size: 100%;
}

#shape-picker [data-shape-colors] {
	border-block-start: 1px solid var(--gray-6);
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
	justify-content: space-between;
	padding: 0.5rem;
}

#shape-picker [data-shape-colors] button {
	background: none;
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	padding: 0;
}

#shape-picker [data-shape-colors] [data-swatch] {
	background-color: var(--shape-fill, var(--gray-12));
	block-size: 1.25rem;
	border: 1px solid color-mix(in srgb, var(--gray-12) 25%, transparent);
	border-radius: 50%;
	box-sizing: border-box;
	display: block;
	inline-size: 1.25rem;
}

#shape-picker [data-shape-color="default"] [data-swatch] {
	background-color: var(--gray-12);
}

#doodle-picker {
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.5rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	margin: 0;
	padding: 0;
	position: fixed;
}

#doodle-picker:popover-open {
	block-size: 26rem;
	display: flex;
	inline-size: 26rem;
}

#doodle-picker [data-doodle-nav] {
	border-inline-end: 1px solid var(--gray-6);
	display: flex;
	flex-direction: column;
	flex-shrink: 0;
	gap: 0.125rem;
	inline-size: 8rem;
	overflow-y: auto;
	padding: 0.5rem;
}

#doodle-picker [data-doodle-nav] button {
	background: none;
	border: 0;
	border-radius: 0.375rem;
	color: var(--gray-11);
	cursor: pointer;
	display: block;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 500;
	padding-block: 0.375rem;
	padding-inline: 0.5rem;
	text-align: start;
}

#doodle-picker [data-doodle-nav] button:hover {
	background-color: var(--gray-4);
	color: var(--gray-12);
}

#doodle-picker [data-doodle-body] {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-inline-size: 0;
}

#doodle-picker [data-doodle-search] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	margin: 0.5rem;
	outline: none;
	padding-block: 0.375rem;
	padding-inline: 0.625rem;
}

#doodle-picker [data-doodle-search]:focus {
	border-color: var(--gray-8);
}

#doodle-picker [data-doodle-search]::placeholder {
	color: var(--gray-9);
}

#doodle-picker [data-doodle-scroll] {
	flex: 1;
	overflow-x: hidden;
	overflow-y: auto;
	padding-block-end: 0.5rem;
	padding-inline: 0.5rem;
}

#doodle-picker section[hidden],
#doodle-picker [data-doodle-grid] button[hidden],
#doodle-picker [data-doodle-nav][hidden] {
	display: none;
}

#doodle-picker h3 {
	background-color: var(--gray-3);
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	inset-block-start: 0;
	margin: 0;
	padding-block: 0.5rem 0.25rem;
	position: sticky;
}

#doodle-picker [data-doodle-grid] {
	display: grid;
	gap: 0.375rem;
	grid-template-columns: repeat(2, 1fr);
}

#doodle-picker [data-doodle-grid] button {
	align-items: center;
	aspect-ratio: 1;
	background: none;
	border: 0;
	border-radius: 0.375rem;
	cursor: pointer;
	display: flex;
	justify-content: center;
	padding: 0.625rem;
}

#doodle-picker [data-doodle-grid] button:hover {
	background-color: var(--gray-4);
}

#doodle-picker [data-doodle-grid] button svg {
	block-size: 100%;
	inline-size: 100%;
	object-fit: contain;
}

/* The board-icon picker — like the doodle picker, but a denser grid of small duotone glyphs
   (drawn in currentColor → dark in the light picker) and a fixed Default/None row up top. */
#board-icon-picker {
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.5rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	margin: 0;
	padding: 0;
	position: fixed;
}

#board-icon-picker:popover-open {
	block-size: 26rem;
	display: flex;
	inline-size: 28rem;
}

#board-icon-picker [data-board-icon-nav] {
	border-inline-end: 1px solid var(--gray-6);
	display: flex;
	flex-direction: column;
	flex-shrink: 0;
	gap: 0.125rem;
	inline-size: 8rem;
	overflow-y: auto;
	padding: 0.5rem;
}

#board-icon-picker [data-board-icon-nav] button {
	background: none;
	border: 0;
	border-radius: 0.375rem;
	color: var(--gray-11);
	cursor: pointer;
	display: block;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 500;
	padding-block: 0.375rem;
	padding-inline: 0.5rem;
	text-align: start;
}

#board-icon-picker [data-board-icon-nav] button:hover {
	background-color: var(--gray-4);
	color: var(--gray-12);
}

#board-icon-picker [data-board-icon-body] {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-inline-size: 0;
}

/* Search box + the "No icon" button share a row; the button is squared to the search height. */
#board-icon-picker [data-board-icon-top] {
	align-items: stretch;
	display: flex;
	gap: 0.375rem;
	margin: 0.5rem;
}

#board-icon-picker [data-board-icon-search] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	flex: 1;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	min-inline-size: 0;
	outline: none;
	padding-block: 0.375rem;
	padding-inline: 0.625rem;
}

#board-icon-picker [data-board-icon-top] button[data-board-icon] {
	align-items: center;
	aspect-ratio: 1;
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-11);
	cursor: pointer;
	display: flex;
	flex-shrink: 0;
	justify-content: center;
	padding: 0.375rem;
}

#board-icon-picker [data-board-icon-top] button[data-board-icon]:hover {
	background-color: var(--gray-4);
	color: var(--gray-12);
}

#board-icon-picker [data-board-icon-search]:focus {
	border-color: var(--gray-8);
}

#board-icon-picker [data-board-icon-search]::placeholder {
	color: var(--gray-9);
}

#board-icon-picker [data-board-icon-scroll] {
	flex: 1;
	overflow-x: hidden;
	overflow-y: auto;
	padding-block-end: 0.5rem;
	padding-inline: 0.5rem;
}

#board-icon-picker section[hidden],
#board-icon-picker [data-board-icon-grid] button[hidden],
#board-icon-picker [data-board-icon-nav][hidden] {
	display: none;
}

#board-icon-picker h3 {
	background-color: var(--gray-3);
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	inset-block-start: 0;
	margin: 0;
	padding-block: 0.5rem 0.25rem;
	position: sticky;
}

#board-icon-picker [data-board-icon-grid] {
	display: grid;
	gap: 0.375rem;
	grid-template-columns: repeat(5, 1fr);
}

#board-icon-picker [data-board-icon-grid] button {
	align-items: center;
	aspect-ratio: 1;
	background: none;
	border: 0;
	border-radius: 0.375rem;
	color: var(--gray-12);
	cursor: pointer;
	display: flex;
	justify-content: center;
	padding: 0.4375rem;
}

#board-icon-picker [data-board-icon-grid] button:hover {
	background-color: var(--gray-4);
}

#board-icon-picker button svg {
	block-size: 100%;
	inline-size: 100%;
	object-fit: contain;
}

#painting-picker {
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.5rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	margin: 0;
	padding: 0;
	position: fixed;
}

#painting-picker:popover-open {
	block-size: 28rem;
	display: flex;
	inline-size: 28rem;
}

#painting-picker [data-painting-nav] {
	border-inline-end: 1px solid var(--gray-6);
	display: flex;
	flex-direction: column;
	flex-shrink: 0;
	gap: 0.125rem;
	inline-size: 9rem;
	overflow-y: auto;
	padding: 0.5rem;
}

#painting-picker [data-painting-nav] button {
	background: none;
	border: 0;
	border-radius: 0.375rem;
	color: var(--gray-11);
	cursor: pointer;
	display: block;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 500;
	padding-block: 0.375rem;
	padding-inline: 0.5rem;
	text-align: start;
}

#painting-picker [data-painting-nav] button:hover {
	background-color: var(--gray-4);
	color: var(--gray-12);
}

#painting-picker [data-painting-body] {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-inline-size: 0;
}

#painting-picker [data-painting-search] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	margin: 0.5rem;
	outline: none;
	padding-block: 0.375rem;
	padding-inline: 0.625rem;
}

#painting-picker [data-painting-search]:focus {
	border-color: var(--gray-8);
}

#painting-picker [data-painting-search]::placeholder {
	color: var(--gray-9);
}

#painting-picker [data-painting-scroll] {
	flex: 1;
	overflow-x: hidden;
	overflow-y: auto;
	padding-block-end: 0.5rem;
	padding-inline: 0.5rem;
}

#painting-picker section[hidden],
#painting-picker [data-painting-grid] button[hidden],
#painting-picker [data-painting-nav][hidden] {
	display: none;
}

#painting-picker h3 {
	background-color: var(--gray-3);
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	inset-block-start: 0;
	margin: 0;
	padding-block: 0.5rem 0.25rem;
	position: sticky;
}

#painting-picker [data-painting-grid] {
	display: grid;
	gap: 0.375rem;
	grid-template-columns: repeat(3, 1fr);
}

#painting-picker [data-painting-grid] button {
	align-items: center;
	aspect-ratio: 1;
	background: none;
	border: 0;
	border-radius: 0.375rem;
	cursor: pointer;
	display: flex;
	justify-content: center;
	padding: 0.375rem;
}

#painting-picker [data-painting-grid] button:hover {
	background-color: var(--gray-4);
}

#painting-picker [data-painting-grid] button img {
	block-size: 100%;
	inline-size: 100%;
	object-fit: contain;
}

#emoji-picker:popover-open {
	block-size: 28rem;
	display: flex;
	inline-size: 28rem;
}

#emoji-picker [data-emoji-nav] {
	border-inline-end: 1px solid var(--gray-6);
	display: flex;
	flex-direction: column;
	flex-shrink: 0;
	gap: 0.125rem;
	inline-size: 8.5rem;
	overflow-y: auto;
	padding: 0.5rem;
}

#emoji-picker [data-emoji-nav] button {
	align-items: stretch;
	background: none;
	border: 0;
	border-radius: 0.375rem;
	color: var(--gray-11);
	cursor: pointer;
	display: block;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 500;
	padding-block: 0.375rem;
	padding-inline: 0.5rem;
	text-align: start;
}

#emoji-picker [data-emoji-nav] button:hover {
	background-color: var(--gray-4);
	color: var(--gray-12);
}

#emoji-picker [data-emoji-body] {
	display: flex;
	flex: 1;
	flex-direction: column;
	min-inline-size: 0;
}

#emoji-picker [data-emoji-search] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	margin: 0.5rem;
	outline: none;
	padding-block: 0.375rem;
	padding-inline: 0.625rem;
}

#emoji-picker [data-emoji-search]:focus {
	border-color: var(--gray-8);
}

#emoji-picker [data-emoji-search]::placeholder {
	color: var(--gray-9);
}

#emoji-picker [data-emoji-scroll] {
	flex: 1;
	overflow-x: hidden;
	overflow-y: auto;
	padding-block-end: 0.5rem;
	padding-inline: 0.5rem;
}

#emoji-picker section[hidden],
#emoji-picker [data-emoji][hidden],
#emoji-picker [data-emoji-nav] button[hidden] {
	display: none;
}

#emoji-picker h3 {
	background-color: var(--gray-3);
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	inset-block-start: 0;
	margin: 0;
	padding-block: 0.5rem 0.25rem;
	position: sticky;
}

#emoji-picker [data-grid] {
	display: grid;
	gap: 0.125rem;
	grid-template-columns: repeat(auto-fill, minmax(3rem, 1fr));
}

#emoji-picker [data-emoji] {
	align-items: center;
	aspect-ratio: 1;
	background: none;
	border: 0;
	border-radius: 0.375rem;
	cursor: pointer;
	display: flex;
	justify-content: center;
	padding: 0.25rem;
}

#emoji-picker [data-emoji]:hover {
	background-color: var(--gray-4);
}

#emoji-picker [data-emoji][data-on] {
	background-color: var(--blue-5);
	box-shadow: inset 0 0 0 1.5px var(--blue-8);
}

#emoji-picker [data-emoji] img {
	block-size: 2.5rem;
	inline-size: 2.5rem;
}

#widget-overflow button > span:not([data-bare]) {
	block-size: 2.75rem;
	inline-size: 2.75rem;
}

#color-picker [role="tablist"] {
	border-block-end: 1px solid var(--gray-6);
	display: flex;
	gap: 0.25rem;
	padding-block-end: 0.625rem;
}

#color-picker [data-tab] {
	align-items: center;
	border-radius: 0.3125rem;
	color: var(--gray-11);
	display: flex;
	flex-direction: row;
	font-size: 0.6875rem;
	font-weight: 500;
	gap: 0.25rem;
	justify-content: center;
	padding-block: 0.25rem;
	padding-inline: 0.4375rem;
}

#color-picker [data-tab]:hover {
	background-color: var(--gray-4);
}

#color-picker[data-tab="color"] [data-tab="color"],
#color-picker[data-tab="strip"] [data-tab="strip"] {
	background-color: var(--gray-12);
	color: var(--gray-1);
}

#color-picker [data-grid] {
	display: none;
	gap: 0.5rem;
	grid-template-columns: repeat(4, auto);
	list-style: none;
	margin: 0;
	padding: 0;
}

#color-picker[data-tab="color"] [data-grid="color"],
#color-picker[data-tab="strip"] [data-grid="strip"] {
	display: grid;
}

#color-picker button {
	border-radius: 0.3125rem;
	padding: 0.125rem;
}

#color-picker [data-swatch] {
	block-size: 1.5rem;
	border: 1px solid color-mix(in srgb, var(--gray-12) 12%, transparent);
	border-radius: 0.25rem;
	display: block;
	inline-size: 1.5rem;
}

#color-picker [data-dim="color"] [data-swatch] { background-color: var(--bg); }
#color-picker [data-dim="strip"] [data-swatch] { background-color: var(--strip); }

/* For a board, the swatch previews the solid tile fill (the bold step-9), matching the card. */
aside[aria-label="Tools"][data-selection="board"] #color-picker [data-dim="color"] [data-swatch] {
	background-color: var(--bold);
}

/* For a clock, the swatch previews its step-10 tile frame (`--muted`), matching the card — except
   the default swatch, which is the distinct neutral gray-6 (so it isn't a twin of the gray hue). */
aside[aria-label="Tools"][data-selection="clock"] #color-picker [data-dim="color"] [data-swatch] {
	background-color: var(--muted);
}

aside[aria-label="Tools"][data-selection="clock"] #color-picker button[data-color="default"] [data-swatch] {
	background-color: var(--gray-6);
}

/* A date card's swatch previews its accent (the bold step-9, like the board); default = red-9. */
aside[aria-label="Tools"][data-selection="date"] #color-picker [data-dim="color"] [data-swatch] {
	background-color: var(--bold);
}

aside[aria-label="Tools"][data-selection="date"] #color-picker button[data-color="default"] [data-swatch] {
	background-color: var(--red-9);
}

/* The date's red slot is shown as lime (it would otherwise twin the red default — see above). */
aside[aria-label="Tools"][data-selection="date"] #color-picker button[data-color="red"] [data-swatch] {
	background-color: var(--lime-9);
}

#color-picker button[data-color="default"] [data-swatch],
#color-picker button[data-strip="none"] [data-swatch] {
	border-color: var(--gray-7);
}

#color-picker button[data-strip="none"] [data-swatch] {
	background-image: linear-gradient(
		to top right,
		transparent calc(50% - 1px),
		var(--gray-8) calc(50% - 1px),
		var(--gray-8) calc(50% + 1px),
		transparent calc(50% + 1px)
	);
}

#color-picker button:hover [data-swatch] {
	border-color: var(--gray-9);
}

#color-picker button[data-active] [data-swatch] {
	box-shadow: 0 0 0 2px var(--gray-1), 0 0 0 4px var(--gray-12);
}

aside[aria-label="Tools"][data-selection="board"] [data-color-preview] {
	background-color: var(--bold);
}

aside[aria-label="Tools"][data-selection="clock"] [data-color-preview] {
	background-color: var(--muted);
}

aside[aria-label="Tools"][data-selection="clock"] [data-color-preview][data-color="default"] {
	background-color: var(--gray-6);
}

aside[aria-label="Tools"][data-selection="date"] [data-color-preview] {
	background-color: var(--bold);
}

aside[aria-label="Tools"][data-selection="date"] [data-color-preview][data-color="default"] {
	background-color: var(--red-9);
}

aside[aria-label="Tools"][data-selection="date"] [data-color-preview][data-color="red"] {
	background-color: var(--lime-9);
}

aside[aria-label="Tools"] [data-color-preview] {
	background-color: var(--bg);
	block-size: 1.125rem;
	border: 1px solid var(--gray-8);
	border-radius: 0.25rem;
	display: block;
	inline-size: 1.125rem;
	overflow: hidden;
	position: relative;
}

aside[aria-label="Tools"] [data-color-preview]:not([data-strip="none"])::before {
	background-color: var(--strip);
	block-size: 0.3125rem;
	content: "";
	inset-block-start: 0;
	inset-inline: 0;
	position: absolute;
}

aside[aria-label="Tools"] [data-color-preview][data-color="mixed"] {
	background-image: conic-gradient(
		from 0.25turn,
		var(--red-9),
		var(--amber-9),
		var(--grass-9),
		var(--sky-9),
		var(--purple-9),
		var(--red-9)
	);
}

aside[aria-label="Tools"] [data-color-preview][data-strip="mixed"]::before {
	background-image: linear-gradient(
		to right,
		var(--red-9),
		var(--amber-9),
		var(--grass-9),
		var(--sky-9),
		var(--purple-9)
	);
}

#text-style:popover-open {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	inline-size: 13rem;
	max-block-size: 80dvb;
	overflow-y: auto;
}

#text-style ul {
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

#text-style :where([data-styles], [data-grid]) li {
	display: flex;
}

#text-style [data-styles] button {
	align-items: center;
	border-radius: 0.375rem;
	color: var(--gray-12);
	flex-direction: row;
	font-family: var(--font-serif);
	font-size: 0.9375rem;
	font-weight: 300;
	inline-size: 100%;
	justify-content: flex-start;
	line-height: 1.2;
	min-block-size: 1.75rem;
	padding-block: 0.1875rem;
	padding-inline: 0.5rem;
	text-align: start;
}

#text-style [data-styles] button:hover,
#text-style [data-styles] button[data-active] {
	background-color: var(--gray-4);
}

#text-style [data-styles] button[data-active]::after {
	background-color: currentColor;
	block-size: 0.875rem;
	content: "";
	flex: none;
	inline-size: 0.875rem;
	margin-inline-start: auto;
	mask: url("/images/check.svg") center / contain no-repeat;
}

#text-style [data-styles] button[data-preview="h1"] {
	font-size: 1.3rem;
	font-weight: 600;
}

#text-style [data-styles] button[data-preview="h2"] {
	font-size: 1.1rem;
	font-weight: 600;
}

#text-style [data-styles] button[data-preview="small"] {
	font-size: 0.8rem;
}

#text-style [data-styles] button[data-preview="code"] {
	font-family: var(--font-mono);
	font-size: 0.8rem;
	font-weight: 400;
}

#text-style [data-styles] button[data-preview="callout"] {
	font-family: var(--font-sans);
	font-size: 0.8rem;
	font-weight: 550;
}

#text-style [data-styles] button[data-preview="callout"]::before {
	background: url("/images/openmoji/26A0.svg") center / contain no-repeat;
	block-size: 1em;
	content: "";
	display: inline-block;
	flex: none;
	inline-size: 1em;
	margin-inline-end: 0.35em;
}

#text-style [data-styles] button[data-preview="quote"] {
	font-style: italic;
}

#text-style [data-section] {
	color: var(--gray-10);
	font-family: var(--font-sans);
	font-size: 0.6875rem;
	font-weight: 600;
	margin: 0;
	padding-block-start: 0.25rem;
}

#text-style [data-grid] {
	display: grid;
	gap: 0.375rem;
	grid-template-columns: repeat(6, 1fr);
}

#text-style [data-grid] button {
	align-items: center;
	aspect-ratio: 1;
	border: 1px solid var(--gray-6);
	border-radius: 0.25rem;
	font-family: var(--font-serif);
	font-size: 0.875rem;
	font-weight: 600;
	inline-size: 100%;
	justify-content: center;
}

#text-style [data-grid] button:hover {
	border-color: var(--gray-9);
}

#text-style [data-grid="ink"] button {
	color: var(--ink, var(--gray-12));
}

#text-style [data-grid="highlight"] button {
	background-color: var(--hl, var(--gray-1));
	color: var(--gray-12);
}

[data-hue="gray"] { --hl: var(--gray-5); --ink: var(--gray-11); }
[data-hue="red"] { --hl: var(--red-5); --ink: var(--red-11); }
[data-hue="orange"] { --hl: var(--orange-5); --ink: var(--orange-11); }
[data-hue="amber"] { --hl: var(--amber-5); --ink: var(--amber-11); }
[data-hue="grass"] { --hl: var(--grass-5); --ink: var(--grass-11); }
[data-hue="teal"] { --hl: var(--teal-5); --ink: var(--teal-11); }
[data-hue="sky"] { --hl: var(--sky-5); --ink: var(--sky-11); }
[data-hue="blue"] { --hl: var(--blue-5); --ink: var(--blue-11); }
[data-hue="iris"] { --hl: var(--iris-5); --ink: var(--iris-11); }
[data-hue="purple"] { --hl: var(--purple-5); --ink: var(--purple-11); }
[data-hue="pink"] { --hl: var(--pink-5); --ink: var(--pink-11); }

#shell main {
	background-color: var(--gray-3);
	inset-block-end: 0;
	inset-block-start: var(--shell-top-size);
	inset-inline-end: 0;
	inset-inline-start: var(--shell-rail-size);
	overflow: hidden;
	position: fixed;
}

#canvas {
	background-blend-mode: normal, soft-light;
	background-color: var(--gray-3);
	background-image: url("/images/dot-grid.svg"), url("/images/textures/texture-18.jpg");
	background-repeat: repeat, repeat;
	background-size: auto, 400px;
	cursor: default;
	inset: 0;
	position: absolute;
	touch-action: none;
	user-select: none;
}

/* An image file dragged over the canvas from the desktop — a dashed accent frame inviting the drop
   (it becomes an image widget at the drop point). */
#canvas[data-file-over]::after {
	border: 0.1875rem dashed var(--blue-8);
	content: "";
	inset: 0;
	pointer-events: none;
	position: absolute;
	z-index: 30;
}

#canvas[data-grabbing] {
	cursor: grabbing;
}

#surface {
	inset-block-start: 0;
	inset-inline-start: 0;
	position: absolute;
	transform-origin: 0 0;
	will-change: transform;
}

#items {
	inset-block-start: 0;
	inset-inline-start: 0;
	position: absolute;
}

/* Above the top bar (z-index 30), so a card dragged up to the breadcrumb floats over the chrome and
   you can see it land on a crumb (a drop target that moves it into that ancestor board). Resting
   widgets still pan *under* the torn edge — they live in #canvas, not here; this is only the
   transient drag ghost. */
#drag-layer {
	inset: 0;
	pointer-events: none;
	position: fixed;
	transform-origin: 0 0;
	z-index: 40;
}

#drag-layer [data-widget] {
	pointer-events: auto;
}

#edge-hints {
	inset: 0;
	pointer-events: none;
	position: absolute;
}

#edge-hints [data-edge] {
	align-items: center;
	background-color: var(--gray-1);
	block-size: 1.75rem;
	border: 1px solid var(--gray-6);
	border-radius: 50%;
	box-shadow: 0 1px 2px color-mix(in srgb, var(--gray-10) 12%, transparent);
	color: var(--gray-12);
	cursor: pointer;
	display: flex;
	inline-size: 1.75rem;
	justify-content: center;
	opacity: 0;
	position: absolute;
	transition: opacity 0.2s ease, scale 0.1s ease;
}

#edge-hints [data-edge] svg {
	block-size: 0.875rem;
	inline-size: 0.875rem;
}

#edge-hints [data-edge][data-show] {
	opacity: 1;
	pointer-events: auto;
}

#edge-hints [data-edge]:hover {
	border-color: var(--gray-8);
	scale: 1.1;
}

#edge-hints [data-edge="up"] {
	inset-block-start: 0.5rem;
	inset-inline-start: 50%;
	translate: -50% 0;
}

#edge-hints [data-edge="down"] {
	inset-block-end: 0.5rem;
	inset-inline-start: 50%;
	translate: -50% 0;
}

#edge-hints [data-edge="left"] {
	inset-block-start: 50%;
	inset-inline-start: 0.5rem;
	translate: 0 -50%;
}

#edge-hints [data-edge="right"] {
	inset-block-start: 50%;
	inset-inline-end: 0.5rem;
	translate: 0 -50%;
}

#marquee {
	background-color: color-mix(in srgb, var(--green-6) 25%, transparent);
	border: 1px solid var(--green-8);
	display: none;
	pointer-events: none;
	position: fixed;
	z-index: 15;
}

#marquee[data-active] {
	display: block;
}

/* The floating zoom control: a small pill at the canvas's bottom-right — a percentage readout, a
   Z-key hint, and a reset (✕) over a slider. A translucent panel so the paper shows through; palette
   tokens keep it readable in both light & dark. */
#zoom-control {
	backdrop-filter: blur(8px);
	background-color: color-mix(in srgb, var(--gray-2) 86%, transparent);
	border: 1px solid var(--gray-6);
	box-shadow: 0 2px 8px color-mix(in srgb, var(--gray-10) 14%, transparent);
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
	inline-size: 9.5rem;
	inset-block-end: 0.75rem;
	inset-inline-end: 0.75rem;
	padding: 0.5rem 0.625rem;
	position: absolute;
	z-index: 20;
}

@media (prefers-color-scheme: dark) {
	/* A gray-10-anchored shadow would read as a glow on the dark canvas — re-anchor it on the
	   always-dark gray-1 (the house dark-mode shadow rule). */
	#zoom-control {
		box-shadow: 0 2px 8px color-mix(in srgb, var(--gray-1) 55%, transparent);
	}
}

#zoom-control [data-zoom-slider] {
	-webkit-appearance: none;
	appearance: none;
	background: none;
	cursor: pointer;
	inline-size: 100%;
	margin: 0;
}

#zoom-control [data-zoom-slider]::-webkit-slider-runnable-track {
	background-color: var(--gray-6);
	block-size: 0.25rem;
	border-radius: 0.125rem;
}

#zoom-control [data-zoom-slider]::-moz-range-track {
	background-color: var(--gray-6);
	block-size: 0.25rem;
	border-radius: 0.125rem;
}

#zoom-control [data-zoom-slider]::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	background-color: var(--gray-12);
	block-size: 0.875rem;
	border: 0;
	border-radius: 50%;
	inline-size: 0.875rem;
	margin-block-start: -0.3125rem; /* centre the 14px thumb on the 4px track */
}

#zoom-control [data-zoom-slider]::-moz-range-thumb {
	background-color: var(--gray-12);
	block-size: 0.875rem;
	border: 0;
	border-radius: 50%;
	inline-size: 0.875rem;
}

[data-widget] {
	background-color: var(--bg, var(--gray-1));
	border: 1px solid var(--gray-5);
	box-shadow: 0 0.125rem 0.125rem color-mix(in srgb, var(--gray-8) 16%, transparent);
	cursor: grab;
	display: flex;
	flex-direction: column;
	inset-block-start: 0;
	inset-inline-start: 0;
	min-block-size: 63px;
	overflow: hidden;
	position: absolute;
	transition: opacity 0.15s ease;
}

[data-widget][data-type="todo"] {
	min-block-size: 54px;
}

[data-widget][data-type="sticker"] {
	background: none;
	border: 0;
	box-shadow: none;
	min-block-size: 36px;
	overflow: visible;
}

[data-sticker] {
	align-items: center;
	block-size: 100%;
	color: var(--shape-fill, var(--gray-12));
	display: flex;
	inline-size: 100%;
	justify-content: center;
}

[data-sticker] img,
[data-sticker] svg {
	block-size: 100%;
	inline-size: 100%;
	object-fit: contain;
	pointer-events: none;
}

/* A board is a bare tile + label, not a bordered card — like a sticker. The tile carries the
   colour and the selection ring; the name and count sit beneath. Double-click it to open
   (see the canvas hook's onDoubleClick); its footprint is fixed, so the resize grip is hidden. */
[data-widget][data-type="board"] {
	--board-ink: var(--gray-12);
	--board-tile: var(--bold, var(--gray-4));
	background: none;
	border: 0;
	box-shadow: none;
	overflow: visible;
}

[data-widget][data-type="board"] [data-resize] {
	display: none;
}

[data-board] {
	align-items: center;
	block-size: 100%;
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
	inline-size: 100%;
	justify-content: center;
	user-select: none;
}

/* Name + count as one block, so they stay together and centre as a unit (under the tile on a free
   card, beside it in a stack). */
[data-board-label] {
	align-items: center;
	display: flex;
	flex-direction: column;
}

/* The rounded colour tile. `--board-tile` is its fill (a neutral gray by default, a solid hue
   when coloured); `--board-ink` is the duotone icon's colour. The dots in the glyph are punched
   in `--board-tile` so they read against the header bar on any tile. */
[data-board-tile] {
	align-items: center;
	background-color: var(--board-tile, var(--gray-4));
	block-size: 72px;
	border-radius: 18px;
	box-shadow: 0 0.0625rem 0.1875rem color-mix(in srgb, var(--gray-8) 22%, transparent);
	color: var(--board-ink, var(--gray-12));
	display: flex;
	flex: none;
	justify-content: center;
	inline-size: 72px;
}

[data-board-glyph] {
	align-items: center;
	display: flex;
	justify-content: center;
}

/* The chosen glyph fills a fixed slot in the tile (the set's SVGs are intrinsically 18px). */
[data-board-glyph] svg {
	block-size: 2.5rem;
	inline-size: 2.5rem;
}

/* A coloured board gets a near-white icon so the glyph reads on the solid tile. The tile fill
   itself is `--bold` (the shared step-9 token) — so it always matches the picker swatch. */
[data-widget][data-type="board"]:not([data-color="default"]) {
	--board-ink: #fff;
}

/* Selection rings the tile (rounded), not the card's bounding box — so suppress the default
   rectangular outline and add the ring + a touch more lift on the tile itself. */
[data-widget][data-type="board"][data-selected] {
	outline: none;
}

[data-widget][data-type="board"][data-selected] [data-board-tile] {
	box-shadow:
		0 0 0 0.1875rem var(--gray-12),
		0 0.25rem 0.5rem color-mix(in srgb, var(--gray-8) 28%, transparent);
}

/* A widget dragged over a board's tile drops into that board's sub-canvas — ring the tile in our
   usual dark border + lift it, so it reads as the live drop target (the canvas's answer to the
   stack highlight). Matches the selection ring; the scale-up sets it apart from a plain selection. */
[data-widget][data-type="board"][data-board-over] [data-board-tile] {
	box-shadow:
		0 0 0 0.1875rem var(--gray-12),
		0 0.375rem 0.75rem color-mix(in srgb, var(--gray-8) 32%, transparent);
	scale: 1.05;
}

[data-board-name] {
	/* A transparent border + the rename input's padding, so swapping in the input (same border
	   width + padding) doesn't change the box's height and shift the centred stack. */
	border: 1px solid transparent;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 600;
	line-height: 1.2;
	padding-block: 0.0625rem;
	padding-inline: 0.25rem;
	text-align: center;
}

[data-board-count] {
	color: var(--gray-10);
	font-family: var(--font-sans);
	font-size: 0.6875rem;
	font-weight: 500;
}

/* Renaming edits the name <strong> in place (contenteditable) — so nothing here changes the box.
   The transparent border just turns visible and the field gets a paper background + text caret. */
[data-board-name][data-editing] {
	background-color: var(--gray-1);
	border-color: var(--gray-8);
	border-radius: 0.25rem;
	cursor: text;
	outline: none;
	user-select: text;
}

/* A clock: a square coloured tile (the `--bold` hue) holding a live analog face + a 24h digital
   pill, with a title beneath — like a board, but resizable (the grip stays) and the tile square.
   The face surface + ink are paper/ink palette tokens, so they flip with light/dark mode (paper
   face + dark hands by day, dark face + light hands at night) over whatever the colour slot sets. */
[data-widget][data-type="clock"] {
	/* The tile is the colour at step 10 (`--muted`, light-dark adaptive) — a saturated frame, since
	   the face (not the tile) carries the content, so a pale step-4 tint read too washed out as a
	   thin border. The clock's picker swatches are overridden to step 10 too, so the card matches
	   its swatch. The face is paper and ink/markers are the palette ink, independent of the tile. */
	--clock-tile: var(--muted, var(--gray-10));
	--clock-face: var(--gray-1);
	--clock-ink: var(--gray-12);
	--clock-muted: var(--gray-9);
	background: none;
	border: 0;
	box-shadow: none;
	overflow: visible;
}

/* The default (no-colour) clock is a neutral gray frame, distinct from the gray hue's step-10
   (otherwise the default and gray swatches render identically). */
[data-widget][data-type="clock"][data-color="default"] {
	--clock-tile: var(--gray-6);
}

[data-clock] {
	align-items: center;
	block-size: 100%;
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
	inline-size: 100%;
	/* Pin the square tile to the top (name band hangs below) so the tile's bottom edge is always a
	   fixed 2.25rem above the card bottom — that lets the resize grip ride the tile's corner. */
	justify-content: flex-start;
	/* Positioning context for the on-card "set location" pencil (which can't live in the
	   phx-update="ignore" tile). */
	position: relative;
	user-select: none;
}

/* The on-card "set location" pencil: a bare white icon in the clock tile's top-right corner, like
   the date card's title-bar pencil. The face SVG is transparent in the corners, so the coloured
   tile shows through there — white reads on it (except the light gray default tile; see below).
   Shown only while the clock is selected; it opens the city-search picker beside it. */
[data-clock-edit] {
	align-items: center;
	background: none;
	border: 0;
	color: #fff;
	cursor: pointer;
	display: flex;
	inset-block-start: 0.375rem;
	inset-inline-end: 0.375rem;
	justify-content: center;
	opacity: 0;
	padding: 0;
	pointer-events: none;
	position: absolute;
}

[data-clock-edit] svg {
	block-size: 0.75rem;
	inline-size: 0.75rem;
}

[data-widget][data-type="clock"][data-selected] [data-clock-edit] {
	opacity: 0.85;
	pointer-events: auto;
}

[data-widget][data-type="clock"][data-selected] [data-clock-edit]:hover {
	opacity: 1;
}

/* The default clock's tile is a light gray (gray-6), so white washes out — flip the pencil to a
   dark adaptive gray there (gray-6 is a true gray, so it reads in both modes without pinning). */
[data-widget][data-type="clock"][data-color="default"] [data-clock-edit] {
	color: var(--gray-12);
}

[data-clock-tile] {
	aspect-ratio: 1;
	background-color: var(--clock-tile);
	box-shadow: 0 0.0625rem 0.1875rem color-mix(in srgb, var(--gray-8) 22%, transparent);
	flex: none;
	inline-size: 100%;
	/* Inset the face so the coloured tile reads as a border around it (the face fills the
	   padded box; box-sizing: border-box keeps the tile square). */
	padding: 0.5rem;
	position: relative;
}

[data-clock-face] {
	block-size: 100%;
	display: block;
	inline-size: 100%;
}

[data-clock-rim] {
	fill: var(--clock-face);
	stroke: color-mix(in srgb, var(--gray-12) 9%, transparent);
	stroke-width: 0.75;
}

[data-clock-tick] {
	stroke: var(--clock-muted);
	stroke-linecap: round;
	stroke-width: 1;
}

[data-clock-tick][data-cardinal] {
	stroke: var(--clock-ink);
	stroke-width: 1.75;
}

[data-clock-num] {
	fill: var(--clock-muted);
	font-family: var(--font-sans);
	font-size: 8px;
	font-weight: 600;
	text-anchor: middle;
}

[data-hand-h],
[data-hand-m],
[data-hand-s] {
	stroke-linecap: round;
	transform-box: view-box;
	transform-origin: 50px 50px;
}

[data-hand-h] {
	stroke: var(--clock-ink);
	stroke-width: 3.5;
}

[data-hand-m] {
	stroke: var(--clock-ink);
	stroke-width: 2.25;
}

/* The classic thin red second hand (the bit that makes it feel alive). */
[data-hand-s] {
	stroke: var(--red-9);
	stroke-width: 1;
}

/* The default (no-colour) clock keeps the classic red pivot; a coloured clock's cap is its hue at
   step 8 — a lighter, softer take on the tile so the pivot reads as a small coloured dot. */
[data-clock-cap] { fill: var(--red-9); }
[data-widget][data-type="clock"][data-color="gray"] [data-clock-cap] { fill: var(--gray-8); }
[data-widget][data-type="clock"][data-color="red"] [data-clock-cap] { fill: var(--red-8); }
[data-widget][data-type="clock"][data-color="orange"] [data-clock-cap] { fill: var(--orange-8); }
[data-widget][data-type="clock"][data-color="amber"] [data-clock-cap] { fill: var(--amber-8); }
[data-widget][data-type="clock"][data-color="grass"] [data-clock-cap] { fill: var(--grass-8); }
[data-widget][data-type="clock"][data-color="teal"] [data-clock-cap] { fill: var(--teal-8); }
[data-widget][data-type="clock"][data-color="sky"] [data-clock-cap] { fill: var(--sky-8); }
[data-widget][data-type="clock"][data-color="blue"] [data-clock-cap] { fill: var(--blue-8); }
[data-widget][data-type="clock"][data-color="iris"] [data-clock-cap] { fill: var(--iris-8); }
[data-widget][data-type="clock"][data-color="purple"] [data-clock-cap] { fill: var(--purple-8); }
[data-widget][data-type="clock"][data-color="pink"] [data-clock-cap] { fill: var(--pink-8); }

/* The digital pill — a recessed chip over the lower face; tabular figures so HH:MM doesn't jitter. */
[data-clock-pill] {
	fill: color-mix(in srgb, var(--clock-ink) 12%, var(--clock-face));
}

[data-clock-digital] {
	fill: var(--clock-ink);
	font-family: var(--font-sans);
	font-size: 8px;
	font-variant-numeric: tabular-nums;
	font-weight: 600;
	text-anchor: middle;
}

[data-widget][data-type="clock"][data-selected] {
	outline: none;
}

[data-widget][data-type="clock"][data-selected] [data-clock-tile] {
	box-shadow:
		0 0 0 0.1875rem var(--gray-12),
		0 0.25rem 0.5rem color-mix(in srgb, var(--gray-8) 28%, transparent);
}

/* Lift the resize grip out of the name band and onto the clock tile's bottom-right corner — same
   trick as the date card (square-lock adds a 2.25rem name band; the tile is pinned to the top).
   The grip rides the coloured tile, where a flat gray reads washed-out, so multiply it into the
   tile — it darkens to a deeper shade of whatever colour it's on. */
[data-widget][data-type="clock"] [data-resize] {
	inset-block-end: calc(2.25rem + 1px);
	inset-inline-end: 1px;
	mix-blend-mode: multiply;
}

/* In dark mode multiply would crush the grip toward black on the tile; flip to the opposite blend
   (screen) so it lightens into a brighter shade of the tile colour and stays legible. */
@media (prefers-color-scheme: dark) {
	[data-widget][data-type="clock"] [data-resize] {
		mix-blend-mode: screen;
	}
}

/* The title beneath — identical box-stability trick to the board name (rename edits it in place). */
[data-clock-name] {
	border: 1px solid transparent;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 600;
	line-height: 1.2;
	padding-block: 0.0625rem;
	padding-inline: 0.25rem;
	text-align: center;
}

[data-clock-name][data-editing] {
	background-color: var(--gray-1);
	border-color: var(--gray-8);
	border-radius: 0.25rem;
	cursor: text;
	outline: none;
	user-select: text;
}

/* A date card: a paper tile with a coloured accent (`--date-accent`, the colour at step 9; red-9
   for the default), showing a day page or a month grid, with a title beneath — like the board/clock
   family. Fixed square tile + a title band (the resize grip is hidden). The gray *hue* needs no
   override now — it falls through to `--bold` (gray-9), a real gray option. */
[data-widget][data-type="date"] {
	--date-accent: var(--bold, var(--gray-9));
	background: none;
	border: 0;
	box-shadow: none;
	overflow: visible;
}

/* The default (no-colour) date card's bar is red — the date's signature colour until a hue is
   picked (the bare `--bold` is the pale step-4, too washed out for the bar, hence the override). */
[data-widget][data-type="date"][data-color="default"] {
	--date-accent: var(--red-9);
}

/* Since the default bar is already red, the red *hue* would be a twin of it — so for date cards
   that slot is shown as lime instead (the stored value stays "red"; only the date remaps it). */
[data-widget][data-type="date"][data-color="red"] {
	--date-accent: var(--lime-9);
}

/* lime (the red slot), sky and amber are the bright step-9 hues where white bar text washes out,
   so flip the bar ink (and pencil) to dark on those. color-scheme: light pins gray-12 to its
   near-black value so it stays dark in dark mode too (where the bright bar still needs dark ink). */
[data-widget][data-type="date"]:is([data-color="red"], [data-color="sky"], [data-color="amber"]) :is([data-date-head], [data-date-monthhead], [data-date-edit]) {
	color: var(--gray-12);
	color-scheme: light;
}

[data-date] {
	align-items: center;
	block-size: 100%;
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
	inline-size: 100%;
	/* Pin the square tile to the top (name band hangs below) so the tile's bottom edge is always a
	   fixed 2.25rem above the card bottom — that lets the resize grip ride the tile's corner. */
	justify-content: flex-start;
	user-select: none;
}

/* The tile is a size query-container, so the card's text + grid scale with it as it's resized
   (the widget is square-locked in the hook, so cqw — % of tile width — keeps everything in proportion). */
/* No drop shadow: the tile fills most of the card, so its shadow stranded below the card whenever
   there was no title. A thin border gives the paper edge instead — no shadow to strand. */
[data-date-tile] {
	--date-bar-h: 2rem;
	aspect-ratio: 1;
	background-color: var(--gray-1);
	border: 1px solid var(--gray-5);
	container-type: size;
	flex: none;
	inline-size: 100%;
	overflow: hidden;
	position: relative;
}

/* Selection rings the tile (rounded), not the whole card — the name beneath stays outside the
   box, like the board. Suppress the default rectangular outline; ring the tile itself. */
[data-widget][data-type="date"][data-selected] {
	outline: none;
}

[data-widget][data-type="date"][data-selected] [data-date-tile] {
	box-shadow: 0 0 0 0.1875rem var(--gray-12);
}

/* Lift the resize grip out of the name band and onto the calendar tile's bottom-right corner.
   The square-lock makes the card 2.25rem taller than the square tile (the name band), and the
   tile is pinned to the top, so raising the grip by that band lands it exactly on the tile. */
[data-widget][data-type="date"] [data-resize] {
	inset-block-end: calc(2.25rem + 1px);
	inset-inline-end: 1px;
}

/* The on-card "set the day" pencil: just the bare icon at the tile's top-right, in the coloured
   bar's white ink (the bar's too short for a chip behind it). Shown only while the card is
   selected (like a link's Edit); it opens the calendar picker, which pops beside it. */
[data-date-edit] {
	align-items: center;
	background: none;
	block-size: var(--date-bar-h);
	border: 0;
	color: #fff;
	cursor: pointer;
	display: flex;
	inset-block-start: 0;
	inset-inline-end: 0.4375rem;
	justify-content: center;
	opacity: 0;
	padding: 0;
	pointer-events: none;
	position: absolute;
}

[data-date-edit] svg {
	block-size: 0.75rem;
	inline-size: 0.75rem;
}

[data-widget][data-type="date"][data-selected] [data-date-edit] {
	opacity: 0.85;
	pointer-events: auto;
}

[data-widget][data-type="date"][data-selected] [data-date-edit]:hover {
	opacity: 1;
}

/* --- Day page: a coloured header band over a big day number + month. --- */
[data-date-day] {
	block-size: 100%;
	display: flex;
	flex-direction: column;
}

[data-date-head] {
	align-items: center;
	background-color: var(--date-accent);
	block-size: var(--date-bar-h);
	color: #fff;
	display: flex;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 700;
	justify-content: center;
}

[data-date-main] {
	align-items: center;
	display: flex;
	flex: 1;
	flex-direction: column;
	justify-content: center;
}

[data-date-big] {
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 32cqw;
	font-weight: 700;
	line-height: 1;
}

/* "Today" is text, not a numeral — smaller so it fits. */
[data-date-big][data-today] {
	font-size: 16cqw;
}

[data-date-sub] {
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 9cqw;
	font-weight: 600;
	margin-block-start: 0.5cqw;
}

/* --- Month grid: a coloured header band (like the day page) over the weekday row + 6 weeks;
   the chosen day filled, today ringed. --- */
[data-date-month] {
	block-size: 100%;
	display: flex;
	flex-direction: column;
}

[data-date-monthhead] {
	align-items: center;
	background-color: var(--date-accent);
	block-size: var(--date-bar-h);
	color: #fff;
	display: flex;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 700;
	justify-content: center;
}

[data-date-grid] {
	display: grid;
	flex: 1;
	grid-template-columns: repeat(7, 1fr);
	grid-template-rows: auto repeat(6, 1fr);
	padding: 2.5cqw 3.5cqw 3.5cqw;
}

[data-date-wd] {
	align-items: center;
	color: var(--gray-9);
	display: flex;
	font-family: var(--font-sans);
	font-size: 5.5cqw;
	font-weight: 600;
	justify-content: center;
}

[data-date-cell] {
	align-items: center;
	color: var(--gray-12);
	display: flex;
	font-family: var(--font-sans);
	font-size: 6.6cqw;
	font-weight: 600;
	justify-content: center;
}

[data-date-cell][data-out] {
	color: var(--gray-7);
}

[data-date-cell][data-today]:not([data-on]) {
	border-radius: 0.3rem;
	box-shadow: inset 0 0 0 1.5px var(--gray-8);
	font-weight: 700;
}

[data-date-cell][data-on] {
	background-color: var(--date-accent);
	border-radius: 0.3rem;
	color: #fff;
	font-weight: 700;
}

/* The title beneath — same box-stability trick as the board name (rename edits it in place). */
[data-date-name] {
	border: 1px solid transparent;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 600;
	line-height: 1.2;
	padding-block: 0.0625rem;
	padding-inline: 0.25rem;
	text-align: center;
}

[data-date-name][data-editing] {
	background-color: var(--gray-1);
	border-color: var(--gray-8);
	border-radius: 0.25rem;
	cursor: text;
	outline: none;
	user-select: text;
}

/* A stack: a bordered card with a header (name + item count) over a body that renders its child
   widgets inline, stacked vertically. Unlike a board, the children live right inside the card on the
   same canvas. The grip resizes the width only (the hook ignores the vertical delta). A drag on the
   card moves the whole stack, a drag on a child reorders it. */

/* The height is purely content-driven, so let CSS size it (instant, in the same layout pass as the
   children) rather than a JS measure-and-snap — the latter flashed after a drop, as StackGrow sized
   the card a frame before the children's own grow hooks settled. `auto !important` overrides the
   inline `block-size` (and any StackGrow/growStackOf/fitStack writes), so those become harmless
   model-only bookkeeping (they still keep data-h ≈ the rendered height for the off-screen hints). */
[data-widget][data-type="stack"] {
	block-size: auto !important;
	min-block-size: 144px;
}

/* The stack's own reaction bar is absolute at the bottom, so auto height doesn't count it — reserve
   room beneath the children for it when present. */
[data-widget][data-type="stack"]:has(> [data-reaction-bar]) [data-stack-body] {
	padding-block-end: 2.25rem;
}

/* Horizontal-only resize → a left-right cursor, not the diagonal default. */
[data-widget][data-type="stack"] [data-resize] {
	cursor: ew-resize;
}

/* An empty stack has no widgets to slot between, so a drag hovering it just outlines the placeholder
   well with a plain dark border (no fill, no radius). A populated stack instead shows the insertion
   line below. */
[data-widget][data-type="stack"][data-stack-over] [data-stack-body][data-empty]::before {
	box-shadow: inset 0 0 0 2px var(--gray-12);
}

/* The insertion indicator while dragging a widget into / within a stack: a dark line sitting in the
   gap where the dropped widget would land (above the widget at the drop point, or below the last).
   The hook positions it (inset-block-start) inside the target body and centres it on that line. */
[data-drop-line] {
	background-color: var(--gray-12);
	block-size: 3px;
	inset-inline: 0.75rem;
	pointer-events: none;
	position: absolute;
	translate: 0 -50%;
	z-index: 1;
}

[data-stack] {
	block-size: 100%;
	display: flex;
	flex-direction: column;
	inline-size: 100%;
}

/* The header: the name (serif, centred) over the item count — echoing the board card's label. */
[data-stack-head] {
	align-items: center;
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
	padding-block: 0.75rem 0.625rem;
	padding-inline: 0.75rem;
	user-select: none;
}

[data-stack-name] {
	/* A transparent border + the rename caret's padding, so renaming in place doesn't shift the box. */
	border: 1px solid transparent;
	color: var(--gray-12);
	font-family: var(--font-serif);
	font-size: 1.0625rem;
	font-weight: 600;
	line-height: 1.2;
	padding-block: 0.0625rem;
	padding-inline: 0.25rem;
	text-align: center;
}

[data-stack-name][data-editing] {
	background-color: var(--gray-1);
	border-color: var(--gray-8);
	border-radius: 0.25rem;
	cursor: text;
	outline: none;
	user-select: text;
}

[data-stack-count] {
	color: var(--gray-10);
	font-family: var(--font-sans);
	font-size: 0.6875rem;
	font-weight: 500;
}

/* The body: children stack vertically with gaps. */
[data-stack-body] {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 0.5rem;
	padding-block: 0 0.75rem;
	padding-inline: 0.75rem;
	position: relative; /* the positioning context for the insertion line */
}

/* Empty, the body shows a soft inset placeholder (the "drop widgets here" well). */
[data-stack-body][data-empty]::before {
	background-color: var(--gray-3);
	content: "";
	display: block;
	flex: 1;
	min-block-size: 54px;
}

/* While a stacked widget is being dragged, a placeholder well of its exact height holds its old
   slot, so lifting it out of the flow doesn't collapse the gap and shove the others around. */
[data-stack-placeholder] {
	background-color: var(--gray-3);
	flex: none;
}

/* A child laid out in the stack: full-width in normal flow, not world-positioned. `relative` (not
   static) so its absolute reaction bar still anchors to the child, not the stack card. */
[data-stack-body] > [data-widget][data-stacked] {
	/* Flat inside the stack — no lift shadow; they read as bordered cards, not floating ones.
	   (Lifted into the drag layer for a reorder they leave this selector and regain the drag lift.) */
	box-shadow: none;
	flex: none;
	inline-size: 100%;
	inset: auto;
	position: relative;
}

/* The card lifted into the drag layer positions absolutely (it's placed by `translate`). Scope this
   to the drag layer's *direct* child only — a dragged stack's nested children are descendants here,
   and must keep their in-flow `position: relative`, or they'd all collapse to the same corner and
   vanish. (A stacked child being reordered is itself the direct child, so it's still covered.) */
#drag-layer > [data-widget] {
	position: absolute;
}

/* Board / clock / date children render compactly: their tall, centred free-card layout would waste
   the stack's width, so the tile shrinks and the label sits beside it (a row). Height fits the row. */
[data-stack-body] > [data-widget][data-stacked]:is([data-type="board"], [data-type="clock"], [data-type="date"]) {
	block-size: auto !important;
}

[data-stacked][data-type="board"] [data-board] {
	align-items: center;
	background-color: var(--gray-2);
	flex-direction: row;
	gap: 0.625rem;
	justify-content: flex-start;
	padding-block: 0.5rem;
	padding-inline: 0.5rem;
}

[data-stacked][data-type="board"] [data-board-tile] {
	block-size: 48px;
	/* The free card's 18px radius is far too round on the smaller in-stack tile. */
	border-radius: 0.5rem;
	inline-size: 48px;
}

[data-stacked][data-type="board"] [data-board-glyph] svg {
	block-size: 1.75rem;
	inline-size: 1.75rem;
}

/* Beside the tile the label reads left-aligned, not centred. */
[data-stacked][data-type="board"] [data-board-label] {
	align-items: flex-start;
}

/* Drop the name's centred padding-inline so it lines up flush with the count beneath it. */
[data-stacked][data-type="board"] [data-board-name] {
	padding-inline: 0;
	text-align: start;
}

/* In a stack, clock/date lay out like the board: a smaller square tile on the left, the title
   beside it. The date tile is a size container, so its calendar/day text scales down with it; the
   clock face scales freely. */
[data-stacked]:is([data-type="clock"], [data-type="date"]) {
	--stack-tile: 156px;
}

[data-stacked]:is([data-type="clock"], [data-type="date"]) :is([data-clock], [data-date]) {
	align-items: center;
	flex-direction: row;
	gap: 0.75rem;
	justify-content: flex-start;
	padding: 0.5rem;
}

[data-stacked]:is([data-type="clock"], [data-type="date"]) :is([data-clock-tile], [data-date-tile]) {
	block-size: var(--stack-tile);
	flex: none;
	inline-size: var(--stack-tile);
}

/* The title fills the rest of the row to the right, left-aligned and vertically centred. */
[data-stacked][data-type="clock"] [data-clock-name],
[data-stacked][data-type="date"] [data-date-name] {
	flex: 1;
	margin: 0;
	min-inline-size: 0;
	text-align: start;
}

/* Keep the clock's "set location" pencil on the (now left-hand) tile — its white icon would vanish
   on the stack's paper to the right. (The date's pencil already anchors to its own tile.) */
[data-stacked][data-type="clock"] [data-clock-edit] {
	inset-block-start: 0.875rem;
	inset-inline-end: auto;
	inset-inline-start: calc(0.5rem + var(--stack-tile) - 1.625rem);
}

/* In a stack, board/clock/date are laid-out rows, so selection rings the WHOLE card (like the other
   stacked children) rather than just the tile: restore the default rectangular outline and reset
   each tile to its normal resting shadow (dropping the tile-only ring). */
[data-stacked]:is([data-type="board"], [data-type="clock"], [data-type="date"])[data-selected] {
	outline: 0.1875rem solid var(--gray-12);
	outline-offset: 0;
}

[data-stacked]:is([data-type="board"], [data-type="clock"])[data-selected] :is([data-board-tile], [data-clock-tile]) {
	box-shadow: 0 0.0625rem 0.1875rem color-mix(in srgb, var(--gray-8) 22%, transparent);
}

[data-stacked][data-type="date"][data-selected] [data-date-tile] {
	box-shadow: none;
}

/* The calendar date picker (a neutral popover; the widget's accent doesn't tint it). Server-rendered
   + navigable, positioned beside its trigger by app.js; `data-repin` keeps it put across patches. */
#date-picker {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.625rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	margin: 0;
	padding: 0.625rem;
	position: fixed;
}

#date-picker:popover-open {
	display: block;
	inline-size: 15rem;
}

#date-picker [data-date-picker-head] {
	align-items: center;
	display: flex;
	justify-content: space-between;
	margin-block-end: 0.5rem;
}

#date-picker [data-date-picker-head] button {
	align-items: center;
	background: none;
	border: 0;
	border-radius: 0.375rem;
	color: var(--gray-11);
	cursor: pointer;
	display: flex;
	justify-content: center;
	padding: 0.25rem;
}

#date-picker [data-date-picker-head] button:hover {
	background-color: var(--gray-4);
	color: var(--gray-12);
}

#date-picker [data-date-picker-title] {
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 700;
}

#date-picker [data-date-picker-grid] {
	display: grid;
	gap: 0.0625rem;
	grid-template-columns: repeat(7, 1fr);
}

#date-picker [data-date-wd] {
	color: var(--gray-9);
	font-family: var(--font-sans);
	font-size: 0.6875rem;
	font-weight: 600;
	padding-block: 0.25rem;
	text-align: center;
}

#date-picker [data-date-pick] {
	align-items: center;
	aspect-ratio: 1;
	background: none;
	border: 0;
	border-radius: 0.375rem;
	color: var(--gray-12);
	cursor: pointer;
	display: flex;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	justify-content: center;
}

#date-picker [data-date-pick][data-out] {
	color: var(--gray-7);
}

#date-picker [data-date-pick]:hover {
	background-color: var(--gray-4);
}

#date-picker [data-date-pick][data-today]:not([data-on]) {
	box-shadow: inset 0 0 0 1.5px var(--gray-8);
	font-weight: 700;
}

#date-picker [data-date-pick][data-on] {
	background-color: var(--gray-12);
	color: var(--gray-1);
	font-weight: 700;
}

[data-shape-color="red"] { --shape-fill: var(--red-9); }
[data-shape-color="orange"] { --shape-fill: var(--orange-9); }
[data-shape-color="amber"] { --shape-fill: var(--amber-9); }
[data-shape-color="grass"] { --shape-fill: var(--grass-9); }
[data-shape-color="teal"] { --shape-fill: var(--teal-9); }
[data-shape-color="sky"] { --shape-fill: var(--sky-9); }
[data-shape-color="blue"] { --shape-fill: var(--blue-9); }
[data-shape-color="iris"] { --shape-fill: var(--iris-9); }
[data-shape-color="purple"] { --shape-fill: var(--purple-9); }
[data-shape-color="pink"] { --shape-fill: var(--pink-9); }
[data-shape-color="gray"] { --shape-fill: var(--gray-9); }

[data-reaction-bar] {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
	inset-block-end: 0;
	inset-inline: 0;
	padding-block: 0 0.375rem;
	padding-inline: 0.75rem 1.25rem;
	position: absolute;
}

/* On a Place the card bottom is the address bar, so float the reactions over the top-left of the
   map instead of clipping the address — the chips' own pill background keeps them readable on tiles. */
[data-widget][data-type="place"] [data-reaction-bar] {
	inset-block: 0.375rem auto;
	inset-inline: 0.375rem auto;
	padding: 0;
}

[data-reaction] {
	align-items: center;
	background-color: var(--pill, var(--gray-3));
	border: 1px solid var(--check-dim, var(--gray-6));
	border-radius: 0.875rem;
	cursor: pointer;
	display: flex;
	gap: 0.1875rem;
	padding-block: 0;
	padding-inline: 0 0.5rem;
	position: relative;
}

[data-reaction]:hover {
	border-color: var(--check, var(--gray-8));
}

[data-reaction] img {
	block-size: 1.5rem;
	inline-size: 1.5rem;
}

[data-reaction] span {
	color: var(--muted, var(--gray-11));
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	line-height: 1;
}

[data-reaction][data-mine] {
	border-color: var(--check, var(--gray-8));
}

[data-reaction][data-mine] span {
	color: var(--ink, var(--gray-12));
}

[data-reaction]:hover::after {
	background-color: var(--gray-12);
	border-radius: 0.25rem;
	color: var(--gray-1);
	content: attr(data-reactors);
	font-family: var(--font-sans);
	font-size: 0.6875rem;
	font-weight: 500;
	inset-block-end: calc(100% + 0.25rem);
	inset-inline-start: 0;
	padding-block: 0.125rem;
	padding-inline: 0.375rem;
	position: absolute;
	white-space: nowrap;
	z-index: 5;
}

/* The on-card comment badge — the filled speech bubble itself, with the thread's size set inside its
   round body. Shown only when a widget has comments; clicking it opens the comment popover (it's a
   popovertarget). It sits *inside* the corner (not overhanging) since the card clips its overflow —
   an overhang would be sheared off at the edge. The bubble + count share one grid cell so they stack. */
[data-comment-badge] {
	background: none;
	block-size: 1.375rem;
	border: 0;
	color: var(--gray-12);
	cursor: pointer;
	display: grid;
	inline-size: 1.375rem;
	inset-block-start: 0.375rem;
	inset-inline-end: 0.375rem;
	padding: 0;
	place-items: center;
	position: absolute;
	z-index: 6;
}

[data-comment-badge] svg {
	block-size: 100%;
	display: block;
	grid-area: 1 / 1;
	inline-size: 100%;
}

[data-comment-badge] span {
	color: white;
	font-family: var(--font-mono);
	font-size: 0.4375rem;
	/* 700 is Spline Sans Mono's heaviest cut (the variable face tops out there). */
	font-weight: 700;
	grid-area: 1 / 1;
	line-height: 1;
	/* The bubble's round body is centred on the box centre (the tail only protrudes bottom-left),
	   so place-items: center already lands the count in the circle — no nudge needed. */
}

/* --bold is the solid step-9 fill (a board's tile, and its swatch in the picker); default is the
   neutral gray-4 tile. --bg stays the step-4 card tint other widgets use. */
[data-color="default"] { --bg: var(--gray-1); --bg2: var(--gray-2); --line: var(--gray-5); --bold: var(--gray-4); --ink: var(--gray-12); --muted: var(--gray-10); --check: var(--gray-8); --check-dim: var(--gray-7); --pill: var(--gray-3); --accent: var(--gray-11); }
[data-color="gray"] { --bg: var(--gray-3); --bg2: var(--gray-4); --line: var(--gray-6); --bold: var(--gray-9); --ink: var(--gray-12); --muted: var(--gray-10); --check: var(--gray-8); --check-dim: var(--gray-7); --pill: var(--gray-3); --accent: var(--gray-11); }
[data-color="red"] { --bg: var(--red-3); --bg2: var(--red-4); --line: var(--red-6); --bold: var(--red-9); --ink: var(--red-12); --muted: var(--red-10); --check: var(--red-8); --check-dim: var(--red-7); --pill: var(--red-3); --accent: var(--red-11); }
[data-color="orange"] { --bg: var(--orange-3); --bg2: var(--orange-4); --line: var(--orange-6); --bold: var(--orange-9); --ink: var(--orange-12); --muted: var(--orange-10); --check: var(--orange-8); --check-dim: var(--orange-7); --pill: var(--orange-3); --accent: var(--orange-11); }
[data-color="amber"] { --bg: var(--amber-3); --bg2: var(--amber-4); --line: var(--amber-6); --bold: var(--amber-9); --ink: var(--amber-12); --muted: var(--amber-10); --check: var(--amber-8); --check-dim: var(--amber-7); --pill: var(--amber-3); --accent: var(--amber-11); }
[data-color="grass"] { --bg: var(--grass-3); --bg2: var(--grass-4); --line: var(--grass-6); --bold: var(--grass-9); --ink: var(--grass-12); --muted: var(--grass-10); --check: var(--grass-8); --check-dim: var(--grass-7); --pill: var(--grass-3); --accent: var(--grass-11); }
[data-color="teal"] { --bg: var(--teal-3); --bg2: var(--teal-4); --line: var(--teal-6); --bold: var(--teal-9); --ink: var(--teal-12); --muted: var(--teal-10); --check: var(--teal-8); --check-dim: var(--teal-7); --pill: var(--teal-3); --accent: var(--teal-11); }
[data-color="sky"] { --bg: var(--sky-3); --bg2: var(--sky-4); --line: var(--sky-6); --bold: var(--sky-9); --ink: var(--sky-12); --muted: var(--sky-10); --check: var(--sky-8); --check-dim: var(--sky-7); --pill: var(--sky-3); --accent: var(--sky-11); }
[data-color="blue"] { --bg: var(--blue-3); --bg2: var(--blue-4); --line: var(--blue-6); --bold: var(--blue-9); --ink: var(--blue-12); --muted: var(--blue-10); --check: var(--blue-8); --check-dim: var(--blue-7); --pill: var(--blue-3); --accent: var(--blue-11); }
[data-color="iris"] { --bg: var(--iris-3); --bg2: var(--iris-4); --line: var(--iris-6); --bold: var(--iris-9); --ink: var(--iris-12); --muted: var(--iris-10); --check: var(--iris-8); --check-dim: var(--iris-7); --pill: var(--iris-3); --accent: var(--iris-11); }
[data-color="purple"] { --bg: var(--purple-3); --bg2: var(--purple-4); --line: var(--purple-6); --bold: var(--purple-9); --ink: var(--purple-12); --muted: var(--purple-10); --check: var(--purple-8); --check-dim: var(--purple-7); --pill: var(--purple-3); --accent: var(--purple-11); }
[data-color="pink"] { --bg: var(--pink-3); --bg2: var(--pink-4); --line: var(--pink-6); --bold: var(--pink-9); --ink: var(--pink-12); --muted: var(--pink-10); --check: var(--pink-8); --check-dim: var(--pink-7); --pill: var(--pink-3); --accent: var(--pink-11); }

[data-strip="none"] { --strip: transparent; }
[data-strip="gray"] { --strip: var(--gray-9); }
[data-strip="red"] { --strip: var(--red-9); }
[data-strip="orange"] { --strip: var(--orange-9); }
[data-strip="amber"] { --strip: var(--amber-9); }
[data-strip="grass"] { --strip: var(--grass-9); }
[data-strip="teal"] { --strip: var(--teal-9); }
[data-strip="sky"] { --strip: var(--sky-9); }
[data-strip="blue"] { --strip: var(--blue-9); }
[data-strip="iris"] { --strip: var(--iris-9); }
[data-strip="purple"] { --strip: var(--purple-9); }
[data-strip="pink"] { --strip: var(--pink-9); }

[data-widget]:not([data-strip="none"])::before {
	background-color: var(--strip);
	block-size: 0.375rem;
	content: "";
	inset-block-start: 0;
	inset-inline: 0;
	pointer-events: none;
	position: absolute;
	z-index: 1;
}

[data-widget][data-dragging] {
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 28%, transparent);
	cursor: grabbing;
}

/* Board/clock/date are bare tiles with a floating title beneath, so the generic drag-lift shadow
   above wraps the whole container — title included — which reads oddly. Keep the container flat
   and ride the lift on the inner tile instead (below), so only the tile appears to pick up. A
   sticker is a bare graphic with no tile, so it just drops the lift entirely. */
[data-widget][data-type="board"][data-dragging],
[data-widget][data-type="clock"][data-dragging],
[data-widget][data-type="date"][data-dragging],
[data-widget][data-type="sticker"][data-dragging] {
	box-shadow: none;
}

[data-widget][data-type="board"][data-dragging] [data-board-tile],
[data-widget][data-type="clock"][data-dragging] [data-clock-tile],
[data-widget][data-type="date"][data-dragging] [data-date-tile] {
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 28%, transparent);
}

[data-widget][data-editing] {
	cursor: auto;
}

[data-widget][data-selected] {
	outline: 0.1875rem solid var(--gray-12);
	outline-offset: 0;
}

[data-widget][data-over-target] {
	opacity: 0.4;
}

[data-widget] [data-resize] {
	align-items: center;
	block-size: 0.875rem;
	color: var(--gray-8);
	cursor: nwse-resize;
	display: flex;
	inline-size: 0.875rem;
	inset-block-end: 0;
	inset-inline-end: 0;
	justify-content: center;
	opacity: 0;
	position: absolute;
}

[data-widget]:not([data-type="sticker"]):hover [data-resize],
[data-widget][data-selected] [data-resize] {
	opacity: 1;
}

[data-widget] [data-rotate] {
	align-items: center;
	background-color: var(--gray-12);
	block-size: 1.25rem;
	border-radius: 50%;
	color: var(--gray-1);
	cursor: grab;
	display: flex;
	inline-size: 1.25rem;
	inset-block-start: -1.875rem;
	inset-inline-start: 50%;
	justify-content: center;
	opacity: 0;
	position: absolute;
	translate: -50% 0;
}

[data-widget][data-selected] [data-rotate] {
	opacity: 1;
}

[data-widget][data-rotate-below] [data-rotate] {
	inset-block-end: -1.875rem;
	inset-block-start: auto;
}

[data-widget][data-rotating] [data-rotate] {
	cursor: grabbing;
}

[data-widget] [data-content] {
	color: var(--ink, var(--gray-12));
	cursor: inherit;
	flex: none;
	font-family: var(--font-serif);
	font-size: 1.25rem;
	font-weight: 300;
	line-height: 1.35;
	min-inline-size: 0;
	overflow-wrap: anywhere;
	padding-block: 17px;
	padding-inline: 1rem;
	pointer-events: none;
}

[data-widget][data-editing] [data-content] {
	cursor: text;
	pointer-events: auto;
}

[data-widget][data-align="center"] [data-content] {
	text-align: center;
}

[data-content] .ProseMirror:focus {
	outline: none;
}

[data-content] .ProseMirror p.is-editor-empty:first-child::before {
	block-size: 0;
	color: var(--gray-7);
	content: attr(data-placeholder);
	float: inline-start;
	pointer-events: none;
}

[data-content]:empty:not([phx-update])::before {
	color: var(--gray-7);
	content: "Write something…";
	pointer-events: none;
}

[data-content] :where(p, h1, h2, h3, h4, blockquote, pre, ul, ol, [data-callout]) {
	margin: 0;
}

[data-content] > * + *,
[data-content] .ProseMirror > * + * {
	margin-block-start: 9px;
}

[data-content] :where(ul, ol) {
	padding-inline-start: 1.25em;
}

[data-content] p {
	min-block-size: 27px;
}

[data-content] :where(strong, b) {
	font-weight: 700;
}

[data-content] :where(h1, h2) {
	font-weight: 600;
}

[data-content] h1 {
	font-size: 1.4em;
	line-height: 36px;
}

[data-content] h2 {
	font-size: 1.1em;
	line-height: 27px;
}

[data-content] small {
	font-size: 0.8em;
}

[data-content] :where(code, pre) {
	font-family: "Spline Sans Mono", monospace;
}

[data-content] pre {
	background-color: var(--gray-3);
	border-radius: 0.375rem;
	font-size: 0.85em;
	line-height: 27px;
	padding-block: 9px;
	padding-inline: 0.75em;
}

[data-content] blockquote {
	border-inline-start: 3px solid var(--gray-6);
	color: var(--gray-11);
	font-style: italic;
	padding-inline-start: 0.75em;
}

[data-content] [data-callout] {
	background-color: var(--amber-3);
	border-radius: 0.375rem;
	font-family: var(--font-sans);
	font-size: 0.75em;
	font-weight: 550;
	line-height: 27px;
	padding-block: 9px;
	padding-inline: 2.35em 0.75em;
	position: relative;
}

[data-content] [data-callout]::before {
	background: url("/images/openmoji/26A0.svg") center / contain no-repeat;
	block-size: 1.5rem;
	content: "";
	inline-size: 1.5rem;
	inset-block-start: 0.7rem;
	inset-inline-start: 0.5rem;
	position: absolute;
}

[data-content] mark {
	border-radius: 0.2em;
	padding-inline: 0.1em;
}

[data-content] a {
	color: var(--blue-11);
	cursor: pointer;
	pointer-events: auto;
	text-decoration: underline;
}

[data-todo] {
	display: flex;
	flex: none;
	flex-direction: column;
	gap: 0.5rem;
	padding-block: 0.875rem;
	padding-inline: 0.75rem;
}

[data-todo-list] {
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

[data-widget-title] {
	color: var(--ink, var(--gray-12));
	cursor: inherit;
	font-family: var(--font-serif);
	font-size: 1.125rem;
	font-weight: 600;
	line-height: 1.4;
	min-inline-size: 0;
	overflow-wrap: anywhere;
}

[data-widget-title][data-empty]:not([data-editing]) {
	display: none;
}

[data-widget-title] input {
	background: none;
	border: 0;
	color: inherit;
	cursor: text;
	font: inherit;
	inline-size: 100%;
	margin: 0;
	outline: none;
	padding: 0;
}

[data-widget-title] input::placeholder {
	color: var(--muted, var(--gray-10));
}

[data-todo-list] li {
	align-items: flex-start;
	display: flex;
	flex-shrink: 0;
	gap: 0.5rem;
	min-block-size: 1.5rem;
}

[data-todo-check] {
	align-items: center;
	background: none;
	block-size: 1rem;
	border: 1.5px solid var(--check, var(--gray-8));
	border-radius: 0.25rem;
	box-sizing: border-box;
	color: var(--gray-1);
	cursor: pointer;
	display: flex;
	flex: none;
	inline-size: 1rem;
	justify-content: center;
	margin-block-start: 0.1875rem;
	padding: 0;
}

[data-todo-check] svg {
	opacity: 0;
}

[data-todo-list] li[data-done] [data-todo-check] {
	background-color: var(--gray-12);
	border-color: var(--gray-12);
}

[data-todo-list] li[data-done] [data-todo-check] svg {
	opacity: 1;
}

[data-todo-list] [data-task] {
	color: var(--ink, var(--gray-12));
	cursor: inherit;
	flex: 1;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 400;
	line-height: 1.4;
	min-inline-size: 0;
	overflow-wrap: anywhere;
}

[data-task] :where(strong, b) {
	font-weight: 700;
}

[data-task] .ProseMirror {
	cursor: text;
}

[data-task] .ProseMirror:focus {
	outline: none;
}

[data-task] p {
	margin: 0;
}

[data-todo-list] li[data-empty]:last-child [data-task]:not([phx-update])::before {
	color: var(--check, var(--gray-8));
	content: "Add a task…";
}

[data-task] .ProseMirror p.is-editor-empty:first-child::before {
	block-size: 0;
	color: var(--check, var(--gray-8));
	content: "Add a task…";
	float: inline-start;
	pointer-events: none;
}

/* Struck-through text in the card's own family — flat gray-9 read dirty on a tinted background
   (worst on amber), and the step-9 solid too bright. Half-transparent step-11 (`--accent`, gray-11
   on a default card) keeps the hue but recedes, on every colour including default. */
[data-todo-list] li[data-done] [data-task] {
	color: color-mix(in srgb, var(--accent, var(--gray-11)) 50%, transparent);
	text-decoration: line-through;
}

[data-task] a {
	color: var(--blue-11);
	text-decoration: underline;
}

[data-task] mark {
	border-radius: 0.2em;
	padding-inline: 0.1em;
}

[data-todo-list] li[data-empty] [data-todo-check] {
	border-color: var(--check-dim, var(--gray-7));
}

aside[aria-label="Tools"]:not([data-selection="todo"]):not([data-selection="calc"]) menu[data-options="widget"] li:has(> button[data-option="title"]) {
	display: none;
}

aside[aria-label="Tools"]:not([data-selection="link"]) menu[data-options="widget"] li:has(> button[data-option="rename"]),
aside[aria-label="Tools"]:not([data-selection="link"]) menu[data-options="widget"] li:has(> button[data-option="caption"]),
aside[aria-label="Tools"]:not([data-link-status="ok"]) menu[data-options="widget"] li:has(> button[data-option="rename"]),
aside[aria-label="Tools"]:not([data-link-status="ok"]) menu[data-options="widget"] li:has(> button[data-option="caption"]) {
	display: none;
}

/* Boards are bare tiles — no Reactions; their Rename button (mirrors a link's) shows only for them. */
aside[aria-label="Tools"][data-selection="board"] menu[data-options="widget"] li:has(> button[aria-label="Reactions"]),
aside[aria-label="Tools"]:not([data-selection="board"]) menu[data-options="widget"] li:has(> button[data-option="rename-board"]),
aside[aria-label="Tools"]:not([data-selection="board"]) menu[data-options="widget"] li:has(> button[popovertarget="board-icon-picker"]) {
	display: none;
}

/* A board has only a tile colour, so its colour picker drops the top-strip tab and grid
   (the hook forces the Background tab) — leaving just the colour swatches. */
aside[aria-label="Tools"][data-selection="board"] #color-picker [role="tablist"],
aside[aria-label="Tools"][data-selection="board"] #color-picker [data-grid="strip"] {
	display: none;
}

/* Clocks are bare coloured tiles too — no Reactions; Location + Rename show only for them, and
   (like boards) the colour picker drops its top-strip tab/grid. */
aside[aria-label="Tools"][data-selection="clock"] menu[data-options="widget"] li:has(> button[aria-label="Reactions"]),
aside[aria-label="Tools"]:not([data-selection="clock"]) menu[data-options="widget"] li:has(> button[data-option="rename-clock"]),
aside[aria-label="Tools"][data-selection="clock"] #color-picker [role="tablist"],
aside[aria-label="Tools"][data-selection="clock"] #color-picker [data-grid="strip"] {
	display: none;
}

/* Date cards: no Reactions; Date / View / Countdown / Rename show only for them; the colour picker
   drops its top-strip tab/grid (the accent is a single colour). */
aside[aria-label="Tools"][data-selection="date"] menu[data-options="widget"] li:has(> button[aria-label="Reactions"]),
aside[aria-label="Tools"]:not([data-selection="date"]) menu[data-options="widget"] li:has(> button[data-option="rename-date"]),
aside[aria-label="Tools"]:not([data-selection="date"]) menu[data-options="widget"] li:has(> button[data-option^="date-view-"]),
aside[aria-label="Tools"][data-selection="date"] #color-picker [role="tablist"],
aside[aria-label="Tools"][data-selection="date"] #color-picker [data-grid="strip"] {
	display: none;
}

/* The stack's Rename (mirrors a board's) shows only when a stack is selected. A stack keeps its
   Colour and Reactions (it's a card, not a bare tile), so those aren't hidden. */
aside[aria-label="Tools"]:not([data-selection="stack"]) menu[data-options="widget"] li:has(> button[data-option="rename-stack"]) {
	display: none;
}

/* A Place is a bare map tile: the static-map image covers the card, so a background colour + top
   strip never show — drop the Colour option. (Reactions stay; they're repositioned over the map.) */
aside[aria-label="Tools"][data-selection="place"] menu[data-options="widget"] li:has(> button[popovertarget="color-picker"]) {
	display: none;
}

/* The active (current) view button reads as selected — a faint tint inside a 2px dark outline,
   matching the Title/Caption "on" state. A dedicated, high-specificity rule so it beats the base
   tile background (which otherwise ties on specificity and wins by source order). */
aside[aria-label="Tools"][data-selection="date"] menu[data-options="widget"] button[data-option^="date-view-"][data-active] > span {
	background-color: var(--gray-3);
	border-color: var(--gray-12);
	border-width: 2px;
	color: var(--gray-12);
}

/* The clock location picker: a search box over a scrollable list of city results (server-rendered,
   so it's not phx-update="ignore"). Positioned beside its trigger by the generic placer in app.js. */
[data-location-picker] {
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.5rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	margin: 0;
	padding: 0.5rem;
	position: fixed;
}

[data-location-picker]:popover-open {
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
	inline-size: 16rem;
}

/* The clock's current city, shown above the search so it's identifiable even after a rename. */
[data-location-picker] [data-location-current] {
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	margin: 0;
	padding-inline: 0.25rem;
}

[data-location-picker] [data-location-current] strong {
	color: var(--gray-12);
	font-weight: 600;
}

[data-location-picker] [data-location-search] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	outline: none;
	padding-block: 0.375rem;
	padding-inline: 0.625rem;
}

[data-location-picker] [data-location-search]:focus {
	border-color: var(--gray-8);
}

[data-location-picker] [data-location-search]::placeholder {
	color: var(--gray-9);
}

[data-location-picker] [data-location-results] {
	display: flex;
	flex-direction: column;
	list-style: none;
	margin: 0;
	max-block-size: 18rem;
	overflow-y: auto;
	padding: 0;
}

[data-location-picker] [data-location-hint] {
	color: var(--gray-9);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	padding-block: 0.625rem;
	text-align: center;
}

[data-location-picker] [data-location-result] {
	background: none;
	border: 0;
	border-radius: 0.375rem;
	cursor: pointer;
	display: flex;
	flex-direction: column;
	gap: 0.0625rem;
	inline-size: 100%;
	padding-block: 0.375rem;
	padding-inline: 0.5rem;
	text-align: start;
}

[data-location-picker] [data-location-result]:hover {
	background-color: var(--gray-4);
}

[data-location-picker] [data-location-result] strong {
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
}

[data-location-picker] [data-location-result] span {
	color: var(--gray-10);
	font-family: var(--font-sans);
	font-size: 0.6875rem;
}

/* The comment-thread popover (shared by every widget). The thread scrolls above a sticky
   compose row; both read on the same paper-gray surface as the other pickers. */
[data-comment-picker] {
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.5rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	margin: 0;
	padding: 0.5rem;
	position: fixed;
}

[data-comment-picker]:popover-open {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	inline-size: 20rem;
}

[data-comment-picker] [data-comment-thread] {
	display: flex;
	flex-direction: column;
	gap: 0.625rem;
	max-block-size: 18rem;
	overflow-y: auto;
}

/* Each comment: a circular avatar beside an author/time header over the body text. */
[data-comment-picker] [data-comment] {
	display: grid;
	gap: 0.5rem;
	grid-template-columns: auto 1fr;
}

[data-comment-picker] [data-comment-avatar] {
	align-items: center;
	background-color: var(--blue-9);
	block-size: 1.75rem;
	border-radius: 50%;
	color: white;
	display: inline-flex;
	flex: none;
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	inline-size: 1.75rem;
	justify-content: center;
}

[data-comment-picker] [data-comment-bubble] header {
	align-items: baseline;
	display: flex;
	gap: 0.375rem;
}

[data-comment-picker] [data-comment-bubble] strong {
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 700;
}

[data-comment-picker] [data-comment-bubble] time {
	color: var(--gray-10);
	font-family: var(--font-sans);
	font-size: 0.6875rem;
}

/* Edit / delete pushed to the row's end, revealed when you hover (or focus within) your own
   comment — so the thread stays clean until you reach for them. */
[data-comment-picker] [data-comment-actions] {
	display: flex;
	gap: 0.125rem;
	margin-inline-start: auto;
	opacity: 0;
	transition: opacity 0.1s;
}

[data-comment-picker] [data-comment]:hover [data-comment-actions],
[data-comment-picker] [data-comment-actions]:focus-within {
	opacity: 1;
}

[data-comment-picker] [data-comment-actions] button {
	align-items: center;
	background: none;
	border: 0;
	border-radius: 0.25rem;
	color: var(--gray-10);
	cursor: pointer;
	display: flex;
	padding: 0.125rem;
}

[data-comment-picker] [data-comment-actions] button:hover {
	background-color: var(--gray-4);
	color: var(--gray-12);
}

/* A comment's body is rich HTML (the same marks/blocks a note can hold), so give it compact prose. */
[data-comment-picker] [data-comment-body] {
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	line-height: 1.4;
	overflow-wrap: anywhere;
}

[data-comment-picker] [data-comment-body] > * {
	margin: 0;
}

[data-comment-picker] [data-comment-body] > * + * {
	margin-block-start: 0.375rem;
}

[data-comment-picker] [data-comment-body] :where(ul, ol) {
	padding-inline-start: 1.25rem;
}

/* While editing a comment in place, the body node hosts the Tiptap editor — frame it so it reads as
   an input (and drop the editor's own focus ring). */
[data-comment-picker] [data-comment-body] .ProseMirror {
	outline: none;
}

[data-comment-picker] [data-comment-body]:has(.ProseMirror) {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-8);
	border-radius: 0.375rem;
	margin-block-start: 0.125rem;
	padding-block: 0.25rem;
	padding-inline: 0.5rem;
}

/* While a comment is being edited in place, the bottom compose row is just noise — hide it. The
   body editor's .ProseMirror lives under [data-comment-body]; the compose one doesn't, so this
   matches only an in-place edit, never normal composing. */
[data-comment-picker]:has([data-comment-body] .ProseMirror) [data-comment-compose] {
	display: none;
}

/* Save / Cancel for an in-place edit: hidden until that comment's body hosts the editor. */
[data-comment-picker] [data-comment-edit-actions] {
	display: none;
}

[data-comment-picker] [data-comment]:has([data-comment-body] .ProseMirror) [data-comment-edit-actions] {
	display: flex;
	gap: 0.375rem;
	justify-content: flex-end;
	margin-block-start: 0.375rem;
}

[data-comment-picker] [data-comment-edit-actions] button {
	background: none;
	border: 0;
	border-radius: 0.25rem;
	cursor: pointer;
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	padding-block: 0.1875rem;
	padding-inline: 0.5rem;
}

/* Qualified with the container so these beat the generic `… button { background: none }` rule
   above (which is one element more specific than a bare [data-comment-save]). */
[data-comment-picker] [data-comment-edit-actions] [data-comment-cancel] {
	color: var(--gray-11);
}

[data-comment-picker] [data-comment-edit-actions] [data-comment-cancel]:hover {
	background-color: var(--gray-4);
}

[data-comment-picker] [data-comment-edit-actions] [data-comment-save] {
	background-color: var(--blue-9);
	color: white;
}

[data-comment-picker] [data-comment-edit-actions] [data-comment-save]:hover {
	background-color: var(--blue-10);
}

/* Before the first comment the compose row stands alone — collapse the empty thread and drop the
   row's divider rule + top padding, so it doesn't float under a phantom line. */
[data-comment-picker]:not(:has([data-comment])) [data-comment-thread] {
	display: none;
}

[data-comment-picker]:not(:has([data-comment])) [data-comment-compose] {
	border-block-start: 0;
	padding-block-start: 0;
}

/* The compose row: avatar, the growing rich-text editor, and Send — aligned to the top so the row
   reads right once the editor wraps to several lines. */
[data-comment-picker] [data-comment-compose] {
	align-items: flex-start;
	border-block-start: 1px solid var(--gray-6);
	display: flex;
	gap: 0.5rem;
	padding-block-start: 0.5rem;
}

/* The Tiptap editor host (a contenteditable, not an <input>). It grows with its content. A
   min-height keeps it one line tall even when empty — editing a comment in place unmounts the
   compose editor, and a truly-empty host would otherwise collapse to a thin sliver. */
[data-comment-picker] [data-comment-input] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	flex: 1;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	max-block-size: 9rem;
	min-block-size: 1.9375rem;
	min-inline-size: 0;
	overflow-y: auto;
	padding-block: 0.375rem;
	padding-inline: 0.625rem;
}

[data-comment-picker] [data-comment-input] .ProseMirror {
	outline: none;
}

[data-comment-picker] [data-comment-input] .ProseMirror > * {
	margin: 0;
}

[data-comment-picker] [data-comment-input] .ProseMirror > * + * {
	margin-block-start: 0.375rem;
}

[data-comment-picker] [data-comment-input] .ProseMirror :where(ul, ol) {
	padding-inline-start: 1.25rem;
}

[data-comment-picker]:focus-within [data-comment-input] {
	border-color: var(--gray-8);
}

/* The empty-state placeholder (Tiptap's Placeholder extension marks the empty first line). */
[data-comment-picker] [data-comment-input] .ProseMirror p.is-editor-empty:first-child::before {
	color: var(--gray-9);
	content: attr(data-placeholder);
	float: inline-start;
	height: 0;
	pointer-events: none;
}

[data-comment-picker] [data-comment-send] {
	background: none;
	border: 0;
	color: var(--blue-11);
	cursor: pointer;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	padding-block: 0.375rem;
	padding-inline: 0.25rem;
}

[data-comment-picker] [data-comment-send]:disabled {
	color: var(--gray-9);
	cursor: default;
}

aside[aria-label="Tools"]:not([data-selection="sticker"]) menu[data-options="widget"] li:has(> button[data-sticker-emoji]),
aside[aria-label="Tools"]:not([data-selection="sticker"]) menu[data-options="widget"] li:has(> button[data-sticker-shape]),
aside[aria-label="Tools"]:not([data-selection="sticker"]) menu[data-options="widget"] li:has(> button[data-sticker-doodle]),
aside[aria-label="Tools"]:not([data-selection="sticker"]) menu[data-options="widget"] li:has(> button[data-sticker-painting]),
aside[aria-label="Tools"][data-selection="sticker"] menu[data-options="widget"] li:has(> button[popovertarget="color-picker"]),
aside[aria-label="Tools"][data-selection="sticker"] menu[data-options="widget"] li:has(> button[popovertarget="emoji-picker"]:not([data-sticker-emoji])) {
	display: none;
}

/* Comment mirrors Reactions: it's a leaf-card option, so the bare tiles (board / clock / date)
   and the bare-graphic sticker drop it, just as they drop Reactions above. */
aside[aria-label="Tools"][data-selection="board"] menu[data-options="widget"] li:has(> button[aria-label="Comment"]),
aside[aria-label="Tools"][data-selection="clock"] menu[data-options="widget"] li:has(> button[aria-label="Comment"]),
aside[aria-label="Tools"][data-selection="date"] menu[data-options="widget"] li:has(> button[aria-label="Comment"]),
aside[aria-label="Tools"][data-selection="sticker"] menu[data-options="widget"] li:has(> button[aria-label="Comment"]) {
	display: none;
}

aside[aria-label="Tools"] button[data-option="title"][data-active] > span,
aside[aria-label="Tools"] button[data-option="caption"][data-active] > span {
	background-color: var(--gray-3);
	border-color: var(--gray-12);
	border-width: 2px;
	color: var(--gray-12);
}

aside[aria-label="Tools"] menu[data-options="widget"] button[data-option="rename"] > span,
aside[aria-label="Tools"] menu[data-options="widget"] button[data-option="rename-board"] > span,
aside[aria-label="Tools"] menu[data-options="widget"] button[data-option="rename-stack"] > span,
aside[aria-label="Tools"] menu[data-options="widget"] button[popovertarget="board-icon-picker"] > span {
	background-color: var(--gray-3);
	border-color: var(--gray-8);
}

aside[aria-label="Tools"] menu[data-options="widget"] button[data-option="rename"]:hover > span,
aside[aria-label="Tools"] menu[data-options="widget"] button[data-option="rename-board"]:hover > span,
aside[aria-label="Tools"] menu[data-options="widget"] button[data-option="rename-stack"]:hover > span,
aside[aria-label="Tools"] menu[data-options="widget"] button[popovertarget="board-icon-picker"]:hover > span {
	background-color: var(--gray-4);
	border-color: var(--gray-8);
}

aside[aria-label="Tools"][data-editing="todo"] menu[data-options="text"] li:has(> button[data-cmd="strike"]),
aside[aria-label="Tools"][data-editing="todo"] menu[data-options="text"] li:has(> button[data-cmd="bulletList"]),
aside[aria-label="Tools"][data-editing="todo"] menu[data-options="text"] li:has(> button[data-cmd="orderedList"]),
aside[aria-label="Tools"][data-editing="todo"] menu[data-options="text"] li:has(> button[data-option="align"]) {
	display: none;
}

aside[aria-label="Tools"][data-editing="todo"] #text-style [data-styles] {
	display: none;
}

aside[aria-label="Tools"][data-editing="caption"] menu[data-options="text"] li:has(> button[data-cmd="bulletList"]),
aside[aria-label="Tools"][data-editing="caption"] menu[data-options="text"] li:has(> button[data-cmd="orderedList"]),
aside[aria-label="Tools"][data-editing="caption"] menu[data-options="text"] li:has(> button[data-option="align"]) {
	display: none;
}

aside[aria-label="Tools"][data-editing="caption"] #text-style [data-styles] {
	display: none;
}

/* Composing a comment uses the full text toolbar EXCEPT lists (comments don't need them) and Align
   (that's widget-content alignment — it pushes align_item for the selected card — not comment text). */
aside[aria-label="Tools"][data-editing="comment"] menu[data-options="text"] li:has(> button[data-cmd="bulletList"]),
aside[aria-label="Tools"][data-editing="comment"] menu[data-options="text"] li:has(> button[data-cmd="orderedList"]),
aside[aria-label="Tools"][data-editing="comment"] menu[data-options="text"] li:has(> button[data-option="align"]) {
	display: none;
}

[data-widget][data-type="link"] {
	min-block-size: 54px;
}

[data-link] {
	display: flex;
	flex: none;
	flex-direction: column;
	position: relative;
}

[data-link]:not([data-status="ok"]) ~ [data-reaction-bar] {
	display: none;
}

[data-widget][data-type="link"]:not(:has([data-link-card])) {
	justify-content: center;
}

[data-link-form] {
	align-items: center;
	display: flex;
	gap: 0.5rem;
	padding-block: 1rem;
	padding-inline: 0.625rem;
}

[data-link-form] > svg {
	color: var(--muted, var(--gray-10));
	flex: none;
}

[data-link-form] input {
	background: none;
	border: 0;
	color: var(--ink, var(--gray-12));
	cursor: text;
	flex: 1;
	font-family: var(--font-sans);
	font-size: 0.9375rem;
	margin: 0;
	min-inline-size: 0;
	outline: none;
	padding: 0;
}

[data-link-form] input::placeholder {
	color: var(--muted, var(--gray-10));
}

[data-link-loading] {
	align-items: center;
	color: var(--muted, var(--gray-10));
	display: flex;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	gap: 0.5rem;
	padding-block: 0.75rem;
	padding-inline: 0.875rem;
}

[data-link-loading] [data-link-url] {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

[data-link-spinner] {
	animation: link-spin 0.8s steps(8) infinite;
	block-size: 0.75rem;
	color: var(--ink, var(--gray-11));
	flex: none;
	inline-size: 0.75rem;
}

@keyframes link-spin {
	to {
		transform: rotate(1turn);
	}
}

/* An image widget: the card is sized to the photo's aspect, so the photo fills it edge to edge
   (object-fit: cover just trims sub-pixel grid-snap rounding). Before upload (or on error) an
   "add an image" placeholder fills the card instead, and a spinner shows while it uploads/processes. */
[data-image-widget] {
	block-size: 100%;
	inline-size: 100%;
}

[data-image] {
	block-size: 100%;
	display: block;
	inline-size: 100%;
	object-fit: cover;
	pointer-events: none;
	user-select: none;
}

/* The empty/error placeholder: the "add an image" button over a small "…or paste a URL" field. */
[data-image-empty] {
	align-items: center;
	block-size: 100%;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	inline-size: 100%;
	justify-content: center;
	padding: 0.75rem;
}

[data-image-pick] {
	align-items: center;
	background: none;
	border: 0;
	color: var(--gray-10);
	cursor: pointer;
	display: flex;
	flex-direction: column;
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 500;
	gap: 0.25rem;
	padding: 0;
	text-align: center;
}

[data-image-pick]:hover {
	color: var(--gray-12);
}

[data-image-url-form] {
	inline-size: 100%;
	max-inline-size: 15rem;
}

[data-image-url-form] input[type="text"] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	inline-size: 100%;
	padding-block: 0.25rem;
	padding-inline: 0.5rem;
}

[data-image-url-form] input[type="text"]:focus {
	border-color: var(--gray-8);
	outline: none;
}

[data-image-url-form] input[type="text"]::placeholder {
	color: var(--gray-9);
}

/* A place widget: once resolved, a (keyless) OpenStreetMap embed fills the card with a label + an
   "Open in Maps" link in a bar beneath it. The map iframe is non-interactive (so the card still drags
   by grabbing the map); only the bar's link takes pointer events. Before that, a pin + input field. */
[data-place] {
	block-size: 100%;
	display: flex;
	flex-direction: column;
	inline-size: 100%;
}

[data-place-map-wrap] {
	block-size: 100%;
	display: flex;
	flex-direction: column;
	inline-size: 100%;
	min-block-size: 0;
}

/* The map area holds the image (and the no-map retry button). */
[data-place-map-area] {
	align-items: center;
	display: flex;
	flex: 1;
	justify-content: center;
	min-block-size: 0;
	overflow: hidden;
	position: relative;
}

/* The map image is fetched sized to the card, so it fills the area without stretching and Google's
   marker stays ~native size. Non-interactive (the card drags by grabbing it); "Open in Maps" opens. */
[data-place-map] {
	block-size: 100%;
	display: block;
	inline-size: 100%;
	object-fit: cover;
	pointer-events: none;
	user-select: none;
}

[data-place-nomap] {
	align-items: center;
	background: none;
	border: 0;
	color: var(--gray-10);
	cursor: pointer;
	display: flex;
	flex: 1;
	font-family: var(--font-sans);
	font-size: 0.75rem;
	inline-size: 100%;
	justify-content: center;
	padding: 0.5rem;
	text-align: center;
}

[data-place-nomap]:hover {
	color: var(--gray-12);
}

[data-place-bar] {
	align-items: center;
	background-color: var(--gray-1);
	border-block-start: 1px solid var(--gray-5);
	color: var(--gray-11);
	display: flex;
	flex: none;
	gap: 0.375rem;
	padding-block: 0.25rem;
	padding-inline: 0.5rem;
}

[data-place-label] {
	color: var(--gray-12);
	flex: 1;
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 500;
	min-inline-size: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

[data-place-open] {
	align-items: center;
	color: var(--gray-10);
	cursor: pointer;
	display: flex;
	flex: none;
}

[data-place-open]:hover {
	color: var(--gray-12);
}

[data-place-loading] {
	align-items: center;
	block-size: 100%;
	display: flex;
	inline-size: 100%;
	justify-content: center;
}

[data-place-form] {
	align-items: center;
	block-size: 100%;
	color: var(--gray-10);
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	inline-size: 100%;
	justify-content: center;
	padding: 0.75rem;
	text-align: center;
}

[data-place-input] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	inline-size: 100%;
	max-inline-size: 15rem;
	padding-block: 0.25rem;
	padding-inline: 0.5rem;
}

[data-place-input]:focus {
	border-color: var(--gray-8);
	outline: none;
}

[data-place-input]::placeholder {
	color: var(--gray-9);
}

[data-place-errortext] {
	color: var(--tomato-10);
	font-family: var(--font-sans);
	font-size: 0.6875rem;
}

[data-calc-widget] {
	block-size: 100%;
	display: flex;
	flex-direction: column;
	inline-size: 100%;
}

/* The optional title sits above the sheet (shown only when set — the generic [data-widget-title]
   rule hides it while empty), divided from it by a rule matching the gutter's border. */
[data-calc-widget] > [data-widget-title] {
	border-block-end: 1px solid var(--line, var(--gray-5));
	flex: none;
	padding-block: 0.5rem 0.375rem;
	padding-inline: 0.625rem;
}

/* A calc(ulations) sheet: a text editor (left) beside a results gutter (right). The editor is a
   transparent textarea layered over a coloured highlight div — they share identical metrics so the
   caret tracks the painted text. The .CalcSheet hook paints both layers + the gutter. */
[data-calc] {
	display: flex;
	flex: 1;
	inline-size: 100%;
	min-block-size: 0;
}

/* The editor is a contenteditable: the `.CalcSheet` hook re-paints highlighted spans into it on
   every keystroke (preserving the caret), so the text IS the highlight — no overlay. */
[data-calc-text] {
	box-sizing: border-box;
	caret-color: var(--gray-12);
	color: var(--gray-12);
	flex: 1;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 500;
	line-height: 1.5rem;
	min-inline-size: 0;
	outline: none;
	overflow: auto;
	padding-block: 0.5rem;
	padding-inline: 0.625rem;
	white-space: pre;
	/* Inert until the card's selected, so an unselected calc card still drags from its left pane. */
	pointer-events: none;
}

[data-widget][data-selected] [data-calc-text] {
	cursor: text;
	pointer-events: auto;
}

[data-calc-text]::selection {
	background-color: var(--blue-5);
}

[data-calc-text] [data-num] {
	color: var(--green-11);
	font-weight: 600;
}

[data-calc-text] [data-cur] {
	color: var(--pink-11);
}

[data-calc-text] [data-unit] {
	color: var(--orange-11);
}

/* A reference: an atomic value-pill ([data-calc-ref], shows the referenced result) when the caret is
   elsewhere, or the editable @token ([data-calc-ref-edit]) when the caret is inside it. */
[data-calc-text] [data-calc-ref],
[data-calc-text] [data-calc-ref-edit] {
	background-color: var(--blue-3);
	border-radius: 0.25rem;
	color: var(--blue-11);
	font-weight: 600;
	padding-block: 0.0625rem;
	padding-inline: 0.1875rem;
}

[data-calc-text] [data-calc-ref] {
	user-select: none;
}

/* A gutter result you can click to insert a reference to it. The row stays full width (so the total's
   rule spans it); the hover "button" is the inner span — a rounded fill hugging the text with a bit
   of horizontal padding (offset by a negative margin so the text doesn't shift). */
[data-calc-results] [data-calc-out] {
	border-radius: 0.3125rem;
	cursor: pointer;
	margin-inline: -0.375rem;
	padding-inline: 0.375rem;
	/* Inert until the editor's focused — so clicks fall through to drag the card unless you're
	   editing; then each result is a clickable "insert reference" button. */
	pointer-events: none;
}

[data-calc]:focus-within [data-calc-out] {
	pointer-events: auto;
}

/* Hover is on the button itself — which is pointer-events:none unless the editor's focused, so it
   only lights up while editing (not when the card is idle). */
[data-calc-results] [data-calc-out]:hover {
	background-color: var(--gray-3);
}

/* A "#" comment line: the # marker reads grey and its result is muted (still computed, just left out
   of the total) — the rest of the input keeps its normal colours. */
[data-calc-text] [data-calc-hash] {
	color: var(--gray-10);
}

[data-calc-results] [data-calc-line][data-comment] {
	color: var(--gray-11);
}

[data-calc-results] {
	/* A shade of the card's colour (one step darker than the body's --bg), falling back to gray. */
	background-color: var(--bg2, var(--gray-2));
	border-inline-start: 1px solid var(--line, var(--gray-5));
	box-sizing: border-box;
	color: var(--gray-12);
	flex: none;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 500;
	inline-size: 38%;
	line-height: 1.5rem;
	overflow: hidden;
	padding-block: 0.5rem;
	padding-inline: 0.625rem;
}

[data-calc-results] [data-calc-line] {
	/* overflow stays visible so the hover button's slight overhang isn't clipped (the gutter's own
	   padding keeps it off the edge); long results clip at the gutter instead of ellipsing. */
	position: relative;
	white-space: nowrap;
}

/* A total/sum line reads as the grand total: bold, with a rule drawn over it. The rule is a
   ::before (not a border) so it adds no height — the gutter stays row-aligned with the editor. */
[data-calc-results] [data-calc-line][data-calc-total] {
	font-weight: 700;
}

[data-calc-results] [data-calc-line][data-calc-total]::before {
	background-color: var(--gray-6);
	block-size: 1px;
	content: "";
	inset-block-start: 0;
	inset-inline: 0;
	position: absolute;
}

/* The shared loading spinner (place). steps(8): the 45°-spaced spokes tick from one position
   to the next, so the opacity fade reads as rotation (a continuous spin would just blur the fade). */
[data-spinner] {
	animation: link-spin 0.8s steps(8) infinite;
	block-size: 1.125rem;
	color: var(--gray-10);
	inline-size: 1.125rem;
}

/* The audio widget: a compact player — square cover art, title/artist, a play/pause button, a
   waveform scrubber, and the time. Fixed height (a horizontal bar); the grip resizes width only. */
[data-audio-widget] {
	block-size: 100%;
	inline-size: 100%;
}

/* The player fills the whole square; the art sits behind, the controls overlay on top. */
[data-audio-player] {
	block-size: 100%;
	inline-size: 100%;
	position: relative;
}

/* The hidden <audio> the hook drives — never shown (the custom controls stand in for it). */
[data-audio-el] {
	display: none;
}

/* The album cover fills the square behind the overlay. */
[data-audio-art] {
	block-size: 100%;
	display: block;
	inline-size: 100%;
	object-fit: cover;
}

/* No embedded art: a tinted square with a big muted note glyph centred behind the overlay. */
[data-audio-widget][data-cover="false"] [data-audio-player] {
	background-image: linear-gradient(135deg, var(--gray-4), var(--gray-6));
}

[data-audio-cover-empty] {
	color: var(--gray-8);
	inset: 0;
	margin: auto;
	block-size: 38%;
	inline-size: 38%;
	position: absolute;
}

/* The overlay: title + controls pinned to the bottom over a dark scrim so they read on any cover
   (these are over album art, so the light-on-dark colours are fixed, not palette-driven). */
[data-audio-overlay] {
	background: linear-gradient(
		to top,
		color-mix(in srgb, #000 78%, transparent),
		color-mix(in srgb, #000 36%, transparent) 55%,
		transparent
	);
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: 0.4375rem;
	inset-block-end: 0;
	inset-inline: 0;
	padding: 1.75rem 0.75rem 0.75rem;
	position: absolute;
}

[data-audio-meta] {
	display: flex;
	flex-direction: column;
	min-inline-size: 0;
}

[data-audio-title] {
	color: #fff;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 700;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

[data-audio-artist] {
	color: color-mix(in srgb, #fff 82%, transparent);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

[data-audio-controls] {
	align-items: center;
	display: flex;
	gap: 0.5rem;
}

/* Play/pause: a filled white disc with a dark icon (the hook toggles [data-playing] to swap icons). */
[data-audio-play] {
	align-items: center;
	background-color: #fff;
	block-size: 1.875rem;
	border: 0;
	border-radius: 50%;
	color: #1c1f21;
	cursor: pointer;
	display: flex;
	flex: none;
	inline-size: 1.875rem;
	justify-content: center;
	padding: 0;
}

[data-audio-play] svg {
	block-size: 1rem;
	inline-size: 1rem;
}

[data-audio-icon="pause"] {
	display: none;
}

[data-audio-widget][data-playing] [data-audio-icon="play"] {
	display: none;
}

[data-audio-widget][data-playing] [data-audio-icon="pause"] {
	display: block;
}

/* The waveform doubles as the scrubber: a row of bars (track) with a played overlay clipped to
   --progress (0..1, set by the hook). Both layers share the same bars, so they line up exactly. */
[data-audio-wave] {
	align-self: stretch;
	block-size: 1.625rem;
	cursor: pointer;
	flex: 1;
	min-inline-size: 0;
	position: relative;
}

[data-audio-wave-track],
[data-audio-wave-played] {
	inset: 0;
	position: absolute;
}

[data-audio-wave-track] {
	color: color-mix(in srgb, #fff 40%, transparent);
}

[data-audio-wave-played] {
	clip-path: inset(0 calc((1 - var(--progress, 0)) * 100%) 0 0);
	color: #fff;
}

/* The SVG stretches to fill its layer; its rects take the layer's colour (track vs played). */
[data-audio-wave-svg] {
	block-size: 100%;
	display: block;
	inline-size: 100%;
}

[data-audio-wave-svg] rect {
	fill: currentColor;
}

[data-audio-time] {
	color: color-mix(in srgb, #fff 88%, transparent);
	flex: none;
	font-family: var(--font-sans);
	font-size: 0.6875rem;
	font-variant-numeric: tabular-nums;
	font-weight: 600;
	white-space: nowrap;
}

/* Shared media loading state (image + audio): a phase caption (Uploading…/Processing… N%) over a
   real progress bar — the bar's fill rides --pct (0..100), updated by the global media:progress
   listener in app.js. */
[data-media-loading] {
	align-items: center;
	block-size: 100%;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	inline-size: 100%;
	justify-content: center;
	padding-inline: 1.25rem;
}

[data-media-phase] {
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-variant-numeric: tabular-nums;
	font-weight: 600;
}

[data-media-progress] {
	background-color: var(--gray-5);
	block-size: 0.375rem;
	border-radius: 0.1875rem;
	inline-size: 100%;
	max-inline-size: 16rem;
	overflow: hidden;
}

[data-media-bar] {
	background-color: var(--gray-12);
	block-size: 100%;
	border-radius: inherit;
	inline-size: calc(var(--pct, 0) * 1%);
	transition: inline-size 0.2s ease;
}

/* Before the first tick (no job yet) the bar slides as an indeterminate cue. */
[data-media-progress][data-indeterminate] [data-media-bar] {
	animation: media-indeterminate 1.1s ease-in-out infinite;
	inline-size: 40%;
}

@keyframes media-indeterminate {
	0% { margin-inline-start: -40%; }
	100% { margin-inline-start: 100%; }
}

[data-audio-empty] {
	align-items: center;
	block-size: 100%;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	inline-size: 100%;
	justify-content: center;
	padding: 0.75rem;
}

[data-audio-pick] {
	align-items: center;
	background: none;
	border: 0;
	color: var(--gray-10);
	cursor: pointer;
	display: flex;
	flex-direction: column;
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 500;
	gap: 0.25rem;
	padding: 0;
	text-align: center;
}

[data-audio-pick]:hover {
	color: var(--gray-12);
}

[data-audio-url-form] {
	inline-size: 100%;
	max-inline-size: 15rem;
}

[data-audio-url-form] input[type="text"] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	inline-size: 100%;
	padding-block: 0.25rem;
	padding-inline: 0.5rem;
}

[data-audio-url-form] input[type="text"]:focus {
	border-color: var(--gray-8);
	outline: none;
}

[data-audio-url-form] input[type="text"]::placeholder {
	color: var(--gray-9);
}

/* The weather widget: a plain card (like a note) — the condition icon carries the colour. Dark
   palette text; the big temperature, the icon + label, then today's high/low stacked above the city. */
[data-weather] {
	block-size: 100%;
	box-sizing: border-box;
	color: var(--gray-12);
	inline-size: 100%;
	position: relative;
}

[data-weather-card] {
	block-size: 100%;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	inline-size: 100%;
	padding: 0.875rem;
}

[data-weather-head] {
	align-items: center;
	display: flex;
	gap: 0.375rem;
}

[data-weather-icon] {
	align-items: center;
	color: var(--gray-11);
	display: flex;
	flex: none;
	justify-content: center;
}

[data-weather-icon] svg {
	block-size: 1.375rem;
	inline-size: 1.375rem;
}

[data-weather-cond] {
	font-family: var(--font-sans);
	font-size: 0.9375rem;
	font-weight: 700;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* The big current temperature fills the middle. */
[data-weather-temp] {
	flex: 1;
	font-family: var(--font-serif, var(--font-sans));
	font-size: 3.25rem;
	font-weight: 600;
	line-height: 1.1;
	padding-block-start: 0.25rem;
}

/* High/low stacked above the city name (a left-aligned column). */
[data-weather-foot] {
	display: flex;
	flex-direction: column;
	gap: 0.0625rem;
	min-inline-size: 0;
}

[data-weather-name] {
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

[data-weather-hilo] {
	color: var(--gray-10);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-variant-numeric: tabular-nums;
	font-weight: 600;
}

/* City name + pencil sit on one line; the pencil shows only while the card is selected. */
[data-weather-place] {
	align-items: center;
	display: flex;
	gap: 0.25rem;
	min-inline-size: 0;
}

[data-weather-edit] {
	align-items: center;
	background: none;
	border: 0;
	color: var(--gray-10);
	cursor: pointer;
	display: none;
	flex: none;
	justify-content: center;
	padding: 0;
}

[data-widget][data-selected] [data-weather-edit] {
	display: flex;
}

[data-weather-edit]:hover {
	color: var(--gray-12);
}

[data-weather-loading] {
	align-items: center;
	block-size: 100%;
	display: flex;
	inline-size: 100%;
	justify-content: center;
}


[data-weather-empty] {
	align-items: center;
	block-size: 100%;
	box-sizing: border-box;
	display: flex;
	inline-size: 100%;
	justify-content: center;
	padding: 1rem;
}

[data-weather-set] {
	align-items: center;
	background: none;
	border: 0;
	color: var(--gray-11);
	cursor: pointer;
	display: flex;
	flex-direction: column;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	gap: 0.375rem;
	text-align: center;
}

[data-weather-set]:hover {
	color: var(--gray-12);
}

/* The flight widget: a wide plain card — flight number + on-time status, a state line, the route with
   a progress bar + plane marker, and the times. Dark palette text (honours the soft `color` tint). */
[data-flight] {
	block-size: 100%;
	box-sizing: border-box;
	color: var(--gray-12);
	inline-size: 100%;
	position: relative;
}

[data-flight-card] {
	block-size: 100%;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	inline-size: 100%;
	justify-content: center;
	padding: 0.875rem 1rem;
}

[data-flight-head] {
	align-items: center;
	display: flex;
	gap: 0.375rem;
}

[data-flight-no] {
	align-items: center;
	display: flex;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 700;
	gap: 0.375rem;
	min-inline-size: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

[data-flight-no] [data-flight-plane-svg] {
	block-size: 1rem;
	color: var(--accent, var(--gray-11));
	flex: none;
	inline-size: 1rem;
}

[data-flight-status] {
	flex: none;
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	/* Pushed to the far right; the edit pencil rides just after the flight number. */
	margin-inline-start: auto;
}

[data-flight-status][data-ontime="ontime"] {
	color: var(--grass-11);
}

[data-flight-status][data-ontime="delayed"] {
	color: var(--amber-11);
}

[data-flight-eta] {
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	text-align: center;
	text-transform: uppercase;
}

[data-flight-route] {
	align-items: center;
	display: flex;
	gap: 0.75rem;
}

[data-flight-iata] {
	font-family: var(--font-sans);
	font-size: 1.125rem;
	font-weight: 700;
	/* All-caps: collapse the line box to the glyphs so their optical centre lines up with the bar
	   (align-items centres on the line box, which otherwise sits a touch below the letters). */
	line-height: 1;
}

/* The progress track (gray line), the elapsed portion (accent), and the plane marker at --progress. */
[data-flight-bar] {
	block-size: 1.25rem;
	flex: 1;
	/* Nudge down a hair: capital letters sit slightly above their em-box centre, so the bar (aligned
	   to that centre) otherwise reads a touch high against the codes. */
	inset-block-start: 2px;
	min-inline-size: 0;
	position: relative;
}

[data-flight-bar]::before,
[data-flight-bar]::after {
	block-size: 2px;
	content: "";
	inset-block-start: calc(50% - 1px);
	inset-inline-start: 0;
	position: absolute;
}

[data-flight-bar]::before {
	background-color: var(--gray-6);
	inline-size: 100%;
}

[data-flight-bar]::after {
	background-color: var(--blue-9);
	border-radius: 1px;
	inline-size: calc(var(--progress, 0) * 100%);
}

[data-flight-marker] {
	align-items: center;
	color: var(--ink, var(--gray-12));
	display: flex;
	inset-block-start: 50%;
	/* Inset the travel by half the plane's width (it's 1rem) so it stays inside the bar at 0%/100%
	   instead of overhanging onto the airport codes. */
	inset-inline-start: calc(0.5rem + var(--progress, 0) * (100% - 1rem));
	justify-content: center;
	position: absolute;
	/* The plane glyph faces nose-up; rotate it 90° clockwise so it points right along the route. */
	transform: translate(-50%, -50%) rotate(90deg);
	/* Above the bar's ::after fill (which is a later sibling and would otherwise paint over it). */
	z-index: 1;
}

[data-flight-marker] [data-flight-plane-svg] {
	block-size: 1rem;
	inline-size: 1rem;
}

[data-flight-times] {
	color: var(--gray-10);
	display: flex;
	font-family: var(--font-sans);
	font-size: 0.75rem;
	font-variant-numeric: tabular-nums;
	font-weight: 600;
	justify-content: space-between;
}

/* The pencil (change/refresh the flight) sits just right of the flight number, only while selected. */
[data-flight-edit] {
	align-items: center;
	background: none;
	border: 0;
	color: var(--gray-10);
	cursor: pointer;
	display: none;
	justify-content: center;
	padding: 0;
}

[data-widget][data-selected] [data-flight-edit] {
	display: flex;
}

[data-flight-edit]:hover {
	color: var(--gray-12);
}

[data-flight-loading] {
	align-items: center;
	block-size: 100%;
	display: flex;
	inline-size: 100%;
	justify-content: center;
}

[data-flight-empty] {
	align-items: center;
	block-size: 100%;
	box-sizing: border-box;
	display: flex;
	inline-size: 100%;
	justify-content: center;
	padding: 1rem;
}

[data-flight-set] {
	align-items: center;
	background: none;
	border: 0;
	color: var(--gray-11);
	cursor: pointer;
	display: flex;
	flex-direction: column;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	gap: 0.375rem;
	text-align: center;
}

[data-flight-set] [data-flight-set-icon] {
	block-size: 1.5rem;
	inline-size: 1.5rem;
}

[data-flight-set]:hover {
	color: var(--gray-12);
}

/* The flight-number + date input popover (shared by every flight card). */
[data-flight-picker] {
	background-color: var(--gray-3);
	border: 1px solid var(--gray-6);
	border-radius: 0.5rem;
	box-shadow: 0 0.5rem 1.5rem color-mix(in srgb, var(--gray-10) 20%, transparent);
	inset: auto;
	margin: 0;
	padding: 0.5rem;
	position: fixed;
}

[data-flight-picker] form {
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
	inline-size: 14rem;
}

[data-flight-picker] [data-flight-date],
[data-flight-picker] [data-flight-from],
[data-flight-picker] [data-flight-input] {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.375rem;
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	outline: none;
	padding-block: 0.375rem;
	padding-inline: 0.625rem;
}

[data-flight-picker] [data-flight-from],
[data-flight-picker] [data-flight-input] {
	text-transform: uppercase;
}

[data-flight-picker] [data-flight-date]:focus,
[data-flight-picker] [data-flight-from]:focus,
[data-flight-picker] [data-flight-input]:focus {
	border-color: var(--gray-8);
}

[data-flight-picker] [data-flight-from]::placeholder,
[data-flight-picker] [data-flight-input]::placeholder {
	color: var(--gray-9);
	text-transform: none;
}

[data-flight-picker] [data-flight-go] {
	background-color: var(--gray-12);
	border: 0;
	border-radius: 0.375rem;
	color: var(--gray-1);
	cursor: pointer;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 600;
	padding-block: 0.4375rem;
}

[data-link-card] {
	display: flex;
	flex-direction: column;
}

[data-link-image] {
	aspect-ratio: 1.91 / 1;
	display: block;
	inline-size: 100%;
	object-fit: cover;
}

[data-link-text] {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	padding-block: 0.75rem;
	padding-inline: 0.875rem;
}

[data-link-source] {
	align-items: center;
	color: var(--muted, var(--gray-10));
	display: flex;
	font-family: var(--font-sans);
	font-size: 0.6875rem;
	font-weight: 500;
	gap: 0.375rem;
}

[data-link-source] span {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

[data-link-favicon] {
	block-size: 1rem;
	border-radius: 0.1875rem;
	flex: none;
	inline-size: 1rem;
	object-fit: contain;
}

[data-link-title] {
	color: var(--blue-11);
	cursor: pointer;
	display: -webkit-box;
	font-family: var(--font-sans);
	font-size: 0.9375rem;
	font-weight: 600;
	inline-size: fit-content;
	line-height: 1.35;
	max-inline-size: 100%;
	text-decoration: none;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	overflow: hidden;
}

[data-link-title]:hover {
	text-decoration: underline;
}

[data-link-fieldedit] {
	background: none;
	border: 0;
	color: var(--ink, var(--gray-12));
	cursor: text;
	font-family: var(--font-sans);
	inline-size: 100%;
	margin: 0;
	outline: none;
	padding: 0;
	resize: none;
}

input[data-link-fieldedit] {
	font-size: 0.9375rem;
	font-weight: 600;
	line-height: 1.35;
}

textarea[data-link-fieldedit] {
	font-size: 0.8125rem;
	font-weight: 450;
	line-height: 1.4;
}

[data-link-desc] {
	color: var(--ink, var(--gray-12));
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	font-weight: 500;
	line-height: 1.4;
}

[data-link-desc]:empty {
	display: none;
}

[data-link-desc] :where(p) {
	margin: 0;
}

[data-link-desc] a {
	color: var(--blue-11);
	text-decoration: underline;
}

[data-link-desc] mark {
	border-radius: 0.2em;
	padding-inline: 0.1em;
}

[data-link-desc] .ProseMirror {
	cursor: text;
}

[data-link-desc] .ProseMirror:focus {
	outline: none;
}

[data-link-desc] .ProseMirror p.is-editor-empty:first-child::before {
	block-size: 0;
	color: var(--gray-9);
	content: attr(data-placeholder);
	float: inline-start;
	pointer-events: none;
}

[data-link-edit] {
	align-items: center;
	background: none;
	border: 0;
	color: var(--gray-11);
	cursor: pointer;
	display: none;
	/* Centre the 12px pencil on the favicon/domain row: text padding (0.75rem) + half the 1rem
	   favicon (0.5rem) = 1.25rem centre, minus half the button (0.375rem). */
	inset-block-start: 0.875rem;
	inset-inline-end: 0.5rem;
	justify-content: center;
	padding: 0;
	position: absolute;
}

[data-widget][data-selected] [data-link-edit] {
	display: flex;
}

[data-link-edit]:hover {
	color: var(--gray-12);
}

[data-link-error] {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	padding-block: 0.75rem;
	padding-inline: 0.875rem;
}

[data-link-error] [data-link-url] {
	color: var(--ink, var(--gray-12));
	font-family: var(--font-sans);
	font-size: 0.875rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

[data-link-error] [data-link-note] {
	color: var(--muted, var(--gray-10));
	font-family: var(--font-sans);
	font-size: 0.75rem;
}

[data-link-error] button {
	align-self: flex-start;
	background: none;
	border: 0;
	color: var(--blue-11);
	cursor: pointer;
	font-family: var(--font-sans);
	font-size: 0.8125rem;
	margin-block-start: 0.125rem;
	padding: 0;
	text-decoration: underline;
}

@media (prefers-color-scheme: dark) {
	#canvas {
		background-blend-mode: normal, normal, soft-light;
		background-image: url("/images/dot-grid-dark.svg"),
			linear-gradient(
				color-mix(in srgb, var(--gray-3) 70%, transparent),
				color-mix(in srgb, var(--gray-3) 70%, transparent)
			),
			url("/images/textures/texture-18.jpg");
		background-repeat: repeat, repeat, repeat;
		background-size: auto, auto, 400px;
	}
}

#shell > header details {
	position: relative;
}

#shell > header summary {
	align-items: center;
	block-size: 1.75rem;
	color: var(--gray-10);
	cursor: pointer;
	display: flex;
	inline-size: 1.75rem;
	justify-content: center;
	list-style: none;
}

#shell > header summary::-webkit-details-marker {
	display: none;
}

#shell > header summary:hover {
	color: var(--gray-12);
}

#shell > header details > div {
	background-color: var(--gray-1);
	border: 1px solid var(--gray-6);
	border-radius: 0.75rem;
	box-shadow: 0 10px 30px color-mix(in srgb, var(--gray-12) 14%, transparent);
	inset-block-start: calc(100% + 0.5rem);
	inset-inline-end: 0;
	min-inline-size: 17rem;
	padding: 1.25rem;
	position: absolute;
	z-index: 60;
}

@media (prefers-color-scheme: dark) {
	#shell > header details > div {
		box-shadow: 0 10px 30px color-mix(in srgb, var(--gray-1) 65%, transparent);
	}
}

#shell > header details > div > div {
	align-items: center;
	display: flex;
	gap: 1rem;
	justify-content: space-between;
}

#shell > header details dl {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	min-inline-size: 0;
}

#shell > header details dt {
	block-size: 1px;
	clip-path: inset(50%);
	inline-size: 1px;
	overflow: hidden;
	position: absolute;
	white-space: nowrap;
}

#shell > header details dd:first-of-type {
	color: var(--gray-12);
	font-family: var(--font-sans);
	font-size: 1rem;
	font-weight: 700;
}

#shell > header details dd:last-of-type {
	color: var(--gray-11);
	font-family: var(--font-sans);
	font-size: 0.8125rem;
}

#shell > header details abbr {
	align-items: center;
	background-color: var(--blue-9);
	block-size: 3rem;
	border-radius: 50%;
	color: var(--gray-1);
	display: flex;
	flex-shrink: 0;
	font-family: var(--font-sans);
	font-size: 1rem;
	font-weight: 700;
	inline-size: 3rem;
	justify-content: center;
	text-decoration: none;
}

#shell > header details a {
	color: var(--tomato-11);
	display: inline-block;
	font-family: var(--font-sans);
	font-size: 0.875rem;
	font-weight: 600;
	margin-block-start: 1rem;
	text-decoration: none;
}

#shell > header details a:hover {
	text-decoration: underline;
}

#flash-group {
	align-items: flex-end;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	inset-block-start: 2rem;
	inset-inline-end: 2rem;
	pointer-events: none;
	position: fixed;
	z-index: 50;
}

#flash-group p {
	background-image: url("/images/splotch.webp");
	background-position: center;
	background-repeat: no-repeat;
	background-size: 100% 100%;
	color: var(--gray-12);
	color-scheme: dark;
	cursor: pointer;
	font-family: var(--font-sans);
	font-size: 1.125rem;
	font-weight: 600;
	max-inline-size: min(90vi, 28rem);
	padding-block: 2rem;
	padding-inline: 3rem;
	pointer-events: auto;
	text-align: center;
	transform: rotate(6deg);
}

@media (max-width: 40rem) {
	#flash-group {
		align-items: center;
		inset-inline: 0;
	}

	#flash-group p {
		transform: none;
	}
}
