/* Per-app theme tokens (the app's dark/light palette via light-dark()),
   moved here so the shared css/general.css can be app-agnostic. */
/* Theme tokens via CSS light-dark(): each token is declared once as
   light-dark(<light>, <dark>) and resolves off the element's `color-scheme`.
   "system" leaves color-scheme: light dark (follows the OS); the data-theme
   overrides below force one or the other. The teal brand hue comes from
   variables.css; light uses the darker teal for contrast on white.
   Keep the light/dark --bg in sync with THEME_COLOR in js/theme.js. */
:root {
	color-scheme: light dark;

	--bg:           light-dark(#f4f7f6, #0e0e12);
	--bg-grad-top:  light-dark(#d6f0ec, #0e2a28);
	--surface:      light-dark(#ffffff, #16161d);
	--surface-2:    light-dark(#eef3f1, #1f1f29);
	--surface-3:    light-dark(#e1e9e6, #2a2a36);
	/* Text fields read as a lighter well than the page behind them — see the
	   modal override, where the page is already --surface and the relationship
	   has to flip to stay visible. */
	--input-bg:     light-dark(#ffffff, #24242f);
	--text:         light-dark(#0f1715, #f4f4f6);
	--text-dim:     light-dark(#586862, #a0a0ad);
	--text-faint:   light-dark(#8a958f, #6c6c79);
	--color-primary-on-surface:     light-dark(var(--color-primary-700), var(--color-primary-400));
	--color-primary-grad:  linear-gradient(135deg,
		light-dark(var(--color-primary-dark), var(--color-primary)) 0%,
		light-dark(var(--color-primary), var(--color-primary-400)) 100%);
	--border:       light-dark(#dbe5e1, #2a2a36);
	--danger:       light-dark(#dc2626, #ef4444);
	--nav-bg:       light-dark(rgba(244, 247, 246, 0.9), rgba(14, 14, 18, 0.92));
	--player-h:     76px;
	--nav-h:        62px;
}

/* ─── Page headers ──────────────────────────────────────────────────────── */
.page-title {
	font: var(--font-h3);
	margin: var(--space-2xs) 0 var(--space-m);
}
.section-title {
	font: var(--font-h5);
	margin: var(--space-l) 0 var(--space-s);
	display: flex;
	align-items: center;
	justify-content: space-between;
}
.top-bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-s);
	margin-bottom: var(--space-m);
}
.top-bar .brand {
	font: var(--font-h4);
	display: flex;
	align-items: center;
	gap: var(--space-xs);
}
/* Icons are inline SVG (js/icons.js) carrying class="icon". Sizing is by
   font-size — the svg is 1em square — so the `.icon { font-size: … }` rules
   throughout this file (and root-app.css / buttons.css) set icon sizes, and
   color comes through `fill: currentColor`. 24px is the default. There is no
   icon font: this class used to be `.ms` (Material Symbols), which read as a
   font hook long after the font was gone. */
svg.icon {
	width: 1em;
	height: 1em;
	font-size: 24px;
	fill: currentColor;
	vertical-align: -0.15em;
	flex-shrink: 0;
}

.top-bar .brand .icon { color: var(--color-primary); font-size: 26px; }

.icon-btn {
	background: var(--surface-2);
	border: 1px solid var(--border);
	color: var(--text);
	width: 40px; height: 40px;
	border-radius: 50%;
	display: grid; place-items: center;
	cursor: pointer;
}
.icon-btn:hover { background: var(--surface-3); }
.icon-btn .icon { font-size: 22px; }
/* Toggle-style icon button (aria-pressed), e.g. the editor's auto-bold switch. */
.icon-btn.on {
	background: var(--color-primary);
	border-color: var(--color-primary);
	color: #fff;
}

.link-btn {
	background: none;
	border: none;
	color: var(--text-dim);
	font: var(--font-body-medium-semibold);
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
	cursor: pointer;
	padding: var(--space-2xs) 0;
}
.link-btn:hover { color: var(--text); }
.link-btn .icon { font-size: 20px; }
.danger-text { color: var(--danger); }
.danger-text:hover { color: var(--danger); }

.play-btn {
	background: var(--color-primary-grad);
	color: #fff;
	border: none;
	border-radius: 999px;
	padding: var(--space-s) var(--space-l);
	font: var(--font-body-medium-bold);
	display: inline-flex;
	align-items: center;
	gap: var(--space-xs);
	cursor: pointer;
	white-space: nowrap;
}
.play-btn:active { transform: scale(0.97); }
.play-btn:disabled { background: var(--surface-3); color: var(--text-faint); cursor: not-allowed; }
.ghost-btn {
	background: var(--surface-2);
	border: 1px solid var(--border);
	color: var(--text);
	border-radius: 999px;
	padding: var(--space-s) var(--space-m);
	font: var(--font-body-medium-medium);
	display: inline-flex;
	align-items: center;
	gap: var(--space-xs);
	cursor: pointer;
}
.ghost-btn:hover { background: var(--surface-3); }

.row-icon {
	background: none;
	border: none;
	color: var(--text-faint);
	display: grid;
	place-items: center;
	padding: var(--space-2xs);
	cursor: pointer;
	border-radius: 50%;
	flex-shrink: 0;

	&:hover { color: var(--text); background: var(--surface-3); }
	&:disabled { opacity: 0.3; cursor: default; background: none; }
	& .icon { font-size: 20px; }
}

/* ─── Filter chips ──────────────────────────────────────────────────────── */
.chip-row {
	display: flex;
	gap: var(--space-xs);
	overflow-x: auto;
	padding-bottom: var(--space-xs);
	margin-bottom: var(--space-s);
	-webkit-overflow-scrolling: touch;
}
.chip {
	background: var(--surface-2);
	border: 1px solid var(--border);
	color: var(--text-dim);
	border-radius: 999px;
	padding: var(--space-xs) var(--space-m);
	font: var(--font-body-small-semibold);
	cursor: pointer;
	white-space: nowrap;
	flex-shrink: 0;
}
.chip:hover { background: var(--surface-3); }
.chip.on { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }
.chip {
	display: inline-grid;
	grid-auto-flow: column;
	align-items: center;
	gap: var(--space-xs);
}
.chip-dot {
	width: 10px; height: 10px;
	border-radius: 50%;
	border: 1px solid rgba(255, 255, 255, 0.25);
}
.chip.on .chip-dot { border-color: rgba(255, 255, 255, 0.6); }
.chip-count {
	min-width: 1.25em;
	padding-inline: 0.35em;
	border-radius: 999px;
	background: var(--surface-3);
	color: var(--text-dim);
	font: var(--font-body-small-bold);
	text-align: center;
}
.chip.on .chip-count { background: rgba(255, 255, 255, 0.25); color: #fff; }
.chip-add { padding: var(--space-xs) var(--space-s); }
.chip-add .icon { font-size: 18px; display: block; }

/* ─── Top-bar list menu ─────────────────────────────────────────────────── */
.top-bar-end { display: grid; grid-auto-flow: column; align-items: center; gap: var(--space-s); }
.list-menu-wrap { position: relative; }
.menu-backdrop { position: fixed; inset: 0; z-index: 15; }
.list-menu {
	position: absolute;
	inset-inline-end: 0;
	top: calc(100% + var(--space-xs));
	z-index: 20;
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: 12px;
	box-shadow: var(--shadow-card, 0 8px 24px rgba(0, 0, 0, 0.4));
	padding: var(--space-xs);
	min-width: 200px;
	display: grid;

	& button {
		background: none;
		border: none;
		color: var(--text);
		font: var(--font-body-medium-semibold);
		display: grid;
		grid-auto-flow: column;
		justify-content: start;
		align-items: center;
		gap: var(--space-s);
		padding: var(--space-s) var(--space-s);
		border-radius: 8px;
		cursor: pointer;
		text-align: start;
		white-space: nowrap;

		&:hover { background: var(--surface-3); }
		&:disabled { opacity: 0.4; cursor: default; background: none; }
		& .icon { font-size: 20px; }
	}
}

/* ─── List editor modal ─────────────────────────────────────────────────── */
.modal-backdrop {
	position: fixed;
	inset: 0;
	z-index: 50;
	background: rgba(0, 0, 0, 0.5);
	display: grid;
	place-items: center;
	padding: var(--space-l);
}
.list-editor, .todo-editor, .image-drop {
	width: min(420px, 100%);
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: var(--radius-modal, 20px);
	padding: var(--space-l);
	/* Grid auto-rows size to content, so the name field keeps its natural
	   single-line height instead of stretching like a flex column would. */
	display: grid;
	gap: var(--space-m);

	& h3 { font: var(--font-h5); margin: 0; }
	& p { margin: 0; }
	& .color-row { border-top: none; padding-top: 0; margin-top: 0; }

	/* On a --surface modal a white field would vanish; step it down instead. */
	--input-bg: var(--surface-2);
}
/* Labelled field rows in the to-do editor: caption above a full-width control. */
.todo-editor .field {
	display: grid;
	gap: var(--space-xs);

	& > span { font: var(--font-body-small-semibold); color: var(--text-dim); }
	& .todo-date, & .todo-recur, & .todo-notes-input { width: 100%; }

	/* The chip list already sits in the field's grid gap. */
	& .attach-list { margin-top: 0; }
	/* A button in a grid stretches; this one is content-sized. */
	& .attach-add { justify-self: start; }
}
/* The editor is the drop target for files, so the veil is positioned against it. */
.todo-editor {
	position: relative;

	&.dragging { outline: 2px dashed var(--color-primary); outline-offset: -4px; }
}
.attach-hint { font: var(--font-body-small-regular); }
/* Free-text detail on a to-do: same chrome as .todo-input, but it grows. */
.todo-notes-input {
	min-width: 0;
	background: var(--input-bg);
	border: 1px solid var(--border);
	color: var(--text);
	border-radius: 12px;
	padding: var(--space-s) var(--space-m);
	font: var(--font-body-medium-regular);
	resize: vertical;

	&:focus { outline: none; border-color: var(--color-primary); }
}
.modal-actions {
	display: grid;
	grid-auto-flow: column;
	justify-content: end;
	align-items: center;
	gap: var(--space-s);
}

/* ─── Add to-do ─────────────────────────────────────────────────────────── */
/* Grid (not flex): the global `form` rule forces flex-direction: column, which
   would turn .todo-input's flex-basis into a 200px-tall field. */
/* Two rows: the text input spans the top; due date, repeat, and Add sit below
   so four controls never crowd a single phone-width line. */
.todo-add {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: var(--space-xs);
	margin-bottom: var(--space-m);
}
.todo-input { grid-column: 1 / -1; }
.todo-input {
	min-width: 0;
	background: var(--input-bg);
	border: 1px solid var(--border);
	color: var(--text);
	border-radius: 12px;
	padding: var(--space-s) var(--space-m);
	font: var(--font-body-large-regular);
}
.todo-date, .todo-recur {
	min-width: 0;
	background: var(--input-bg);
	border: 1px solid var(--border);
	color: var(--text);
	border-radius: 12px;
	padding: var(--space-s) var(--space-s);
	font: var(--font-body-medium-regular);
	color-scheme: inherit; /* native pickers follow the active theme */
}
.todo-input:focus, .todo-date:focus, .todo-recur:focus { outline: none; border-color: var(--color-primary); }

/* ─── To-do list ────────────────────────────────────────────────────────── */
.todo-list { display: flex; flex-direction: column; gap: var(--space-xs); }
.todo-row {
	display: flex;
	align-items: center;
	gap: var(--space-s);
	padding: var(--space-s) var(--space-s);
	border-radius: 12px;
	background: var(--surface);
	border: 1px solid var(--border);
}
.todo-row.dragging {
	border-color: var(--color-primary);
	box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}
.todo-row .drag-handle {
	flex-shrink: 0;
	display: grid;
	place-items: center;
	color: var(--text-faint);
	cursor: grab;
	touch-action: none;

	&:active { cursor: grabbing; }
	& .icon { font-size: 22px; }
}
.todo-check {
	background: none;
	border: none;
	padding: 0;
	color: var(--text-faint);
	cursor: pointer;
	display: grid;
	place-items: center;
	flex-shrink: 0;

	& .icon { font-size: 26px; }
}
.todo-row.done .todo-check { color: var(--color-primary); }
.todo-main {
	flex: 1;
	min-width: 0;
	cursor: pointer;

	&:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: 6px; }
}
.todo-text { font: var(--font-body-large-medium); }
.todo-row.done .todo-text { color: var(--text-dim); text-decoration: line-through; }
/* Row preview of the notes: two lines, then ellipsis. */
.todo-notes {
	font: var(--font-body-small-regular);
	color: var(--text-dim);
	margin-top: var(--space-3xs);
	white-space: pre-wrap;
	overflow: hidden;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 2;
	line-clamp: 2;
}
.todo-row.done .todo-notes { text-decoration: line-through; }
.todo-meta { display: flex; align-items: center; gap: var(--space-xs); margin-top: var(--space-2xs); flex-wrap: wrap; }
.todo-tag {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
	font: var(--font-body-xsmall-bold);
	color: var(--color-primary-on-surface);
	background: color-mix(in oklch, var(--color-primary) 18%, transparent);
	border-radius: 999px;
	padding: var(--space-3xs) var(--space-xs);

	& .icon { font-size: 14px; }
}
.todo-due {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2xs);
	font: var(--font-body-small-regular);
	color: var(--text-dim);
}
.todo-due .icon { font-size: 15px; }
.todo-due.overdue { color: var(--danger); }

/* ─── Time log ──────────────────────────────────────────────────────────── */
/* Grid, like .todo-add and for the same reason: the global `form` rule forces
   flex-direction: column, which would stretch the inputs. The description spans
   the top row; tag / date / from / to share the row below (wrapping to two per
   line on a phone), and the actions sit on their own row so nothing crowds. */
.tl-add {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
	align-items: center;
	gap: var(--space-xs);
	margin-bottom: var(--space-m);

	& .todo-input { grid-column: 1 / -1; }
}
.tl-actions {
	grid-column: 1 / -1;
	display: grid;
	grid-auto-flow: column;
	justify-content: end;
	align-items: center;
	gap: var(--space-s);
}
.tl-pending { font: var(--font-body-small-semibold); }

/* Running entry — the one started but not stopped (state/store.js runningTimeLog). */
.tl-running {
	display: grid;
	grid-template-columns: auto 1fr auto;
	align-items: center;
	gap: var(--space-s);
	padding: var(--space-s) var(--space-m);
	margin-bottom: var(--space-m);
	border-radius: 14px;
	border: 1px solid var(--color-primary);
	background: color-mix(in oklch, var(--color-primary) 12%, transparent);
}
.tl-running-dot {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--color-primary);
	animation: tl-pulse 1.6s ease-in-out infinite;
}
@keyframes tl-pulse { 50% { opacity: 0.25; } }
.tl-running-main { min-width: 0; }
.tl-running-text { font: var(--font-body-large-medium); }
.tl-running-meta { font: var(--font-body-small-regular); color: var(--text-dim); }

.tl-list { display: grid; gap: var(--space-xs); }
.tl-row {
	display: grid;
	grid-template-columns: minmax(96px, auto) 1fr auto;
	align-items: center;
	gap: var(--space-s);
	padding: var(--space-s);
	border-radius: 12px;
	background: var(--surface);
	border: 1px solid var(--border);

	&.running { border-color: var(--color-primary); }
}
.tl-time {
	display: grid;
	gap: var(--space-3xs);
	justify-items: start;
}
.tl-range { font: var(--font-body-small-regular); color: var(--text-dim); white-space: nowrap; }
.tl-duration { font: var(--font-body-medium-bold); color: var(--color-primary-on-surface); }
.tl-main {
	min-width: 0;
	cursor: pointer;

	&:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: 6px; }
}
.tl-text { font: var(--font-body-large-medium); overflow-wrap: anywhere; }
.tl-meta { display: flex; align-items: center; gap: var(--space-xs); margin-top: var(--space-2xs); flex-wrap: wrap; }
.tl-row-actions { display: grid; grid-auto-flow: column; align-items: center; }
.tl-hint { font: var(--font-body-small-regular); }

/* ─── Notes grid ────────────────────────────────────────────────────────── */
.notes-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
	gap: var(--space-m);
}
.note-card {
	position: relative;
	display: block;
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: var(--radius-card, 16px);
	padding: var(--space-m) var(--space-m) var(--space-s);
	min-height: 96px;
	cursor: pointer;
	transition: transform 0.12s, border-color 0.12s;
	overflow: hidden;
}
.note-card:active { transform: scale(0.98); }
.note-card:hover { border-color: var(--color-primary); }
.note-title { font: var(--font-body-large-bold); margin-bottom: var(--space-xs); padding-inline-end: var(--space-xl); }
.note-body {
	font: var(--font-body-medium-regular);
	color: var(--text-dim);
	line-height: 1.5;
	display: -webkit-box;
	-webkit-line-clamp: 6;
	line-clamp: 6;
	-webkit-box-orient: vertical;
	overflow: hidden;
	white-space: pre-wrap;
}
.note-thumb {
	display: block;
	width: 100%;
	max-height: 160px;
	object-fit: cover;
	border-radius: 10px;
	margin: var(--space-3xs) 0 var(--space-xs);
}
.note-date {
	font: var(--font-body-xsmall-regular);
	color: var(--text-faint);
	margin-top: var(--space-s);
	display: flex;
	align-items: center;
	gap: var(--space-2xs);
}
/* Attachment count, pushed to the far end of the date row. */
.note-attach {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	margin-inline-start: auto;

	& svg.icon { font-size: 14px; }
}
.note-pin {
	position: absolute;
	top: var(--space-xs); inset-inline-end: var(--space-xs);
	background: none;
	border: none;
	color: var(--text-faint);
	cursor: pointer;
	padding: var(--space-2xs);
	border-radius: 50%;
	display: grid; place-items: center;

	& .icon { font-size: 18px; }
	&:hover { color: var(--text); background: rgba(0, 0, 0, 0.2); }
	&.on { color: var(--color-primary-on-surface); }
}

/* ─── Trash ─────────────────────────────────────────────────────────────── */
.trash-note { margin: 0 0 var(--space-m); font: var(--font-body-small-regular); }

/* A trashed note is not a link — nothing opens from in here — so the card is a
   plain block carrying its own two actions instead. */
.trash-card {
	cursor: default;

	&:hover { border-color: var(--border); }
	&:active { transform: none; }

	& .note-body { -webkit-line-clamp: 3; line-clamp: 3; }
}
.trash-actions {
	display: grid;
	grid-auto-flow: column;
	justify-content: end;
	gap: var(--space-xs);
	margin-top: var(--space-s);

	& button { width: 34px; height: 34px; }
	& .icon { font-size: 18px; }
}

/* ─── Note color themes (cards + editor) ────────────────────────────────── */
/* Tints are theme-aware: pale in light mode (so dark --text stays legible),
   deep in dark mode (so light --text stays legible). See general.css. */
.color-default { --note-tint: var(--surface-2); }
.color-yellow  { --note-tint: light-dark(#f7eeba, #3a3414); }
.color-green   { --note-tint: light-dark(#cdebd9, #14321f); }
.color-blue    { --note-tint: light-dark(#cfe2f3, #14283a); }
.color-pink    { --note-tint: light-dark(#f4d4e3, #3a1428); }
.color-purple  { --note-tint: light-dark(#e3d3f3, #281438); }
.note-card.color-default { background: var(--surface-2); }
.note-card:not(.color-default) { background: var(--note-tint); }

/* ─── Note editor ───────────────────────────────────────────────────────── */
.editor {
	position: relative; /* anchors the drag-and-drop veil */
	background: var(--note-tint, var(--surface-2));
	border: 1px solid var(--border);
	border-radius: var(--radius-card, 16px);
	padding: var(--space-m);
	min-height: 70dvh;
	display: flex;
	flex-direction: column;
	transition: background 0.2s;
}
.editor-bar {
	display: flex;
	align-items: center;
	gap: var(--space-s);
	margin-bottom: var(--space-xs);
}
.editor-status { flex: 1; font: var(--font-body-small-regular); }
.editor-actions { display: flex; gap: var(--space-xs); }
.editor-title {
	background: none;
	border: none;
	color: var(--text);
	font: var(--font-h4);
	padding: var(--space-xs) var(--space-3xs);
	outline: none;
}
.editor-title::placeholder { color: var(--text-faint); }
/* The formatting toolbar sits between the title and the body. A bare row, not a
   boxed bar: the note is a tinted sheet of paper, and a bordered control strip
   across it would read as a separate widget sitting on top. */
.editor format-toolbar {
	margin-block: var(--space-2xs);
	padding-inline: var(--space-3xs);
}

/* The bar's typing switch wears the markers it governs. Monospace so the pair of
   asterisks reads as literal characters rather than a bit of decoration. */
.formatting-btn .fmt-markers {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 0.95rem;
	line-height: 1;
}

.editor-body {
	flex: 1;
	/* Arabic and English in one note. dir="auto" on the element picks a direction
	   from the first strong character in the whole body — which is the wrong unit
	   for a note, where the shopping list under an English heading may itself be
	   Arabic. `plaintext` resolves it per paragraph instead, and text-align: start
	   follows that paragraph's own direction rather than the element's, so each
	   line hangs off the edge it reads from. The attribute stays for the cases
	   plaintext does not cover: the caret's placement in an empty body, and the
	   direction the placeholder is drawn in. */
	unicode-bidi: plaintext;
	text-align: start;
	background: none;
	border: none;
	color: var(--text);
	font: var(--font-body-large-regular);
	line-height: 1.6;
	padding: var(--space-xs) var(--space-3xs);
	outline: none;
	min-height: 40dvh;
	white-space: pre-wrap;
	overflow-wrap: anywhere;

	& img {
		max-width: 100%;
		height: auto;
		border-radius: var(--radius-card, 16px);
		margin: var(--space-xs) 0;
	}

	/* A list is part of the note, not a quotation from it: the browser's 40px
	   indent pushes it into its own column, away from the heading it belongs
	   under. Just enough padding to hold the marker, so the bullet starts where
	   the plain lines above it start and the item's text is what is indented —
	   a wrapped line then hangs under its own first line, not under the bullet.
	   Logical padding, so an Arabic list indents from the right by itself. */
	/* Lists sit in the same column as the rest of the note — the marker starts
	   where the plain lines above it start — and the item's text is what carries
	   the indent, so a wrapped line hangs under its own first line.

	   The markers are drawn here rather than by list-style, because a native
	   outside marker is placed against the item box in a way no padding can pull
	   into line, and it lands off the far edge of the note entirely when the item
	   is RTL inside a list that is not (a <ul dir="auto"> always resolves to ltr
	   — see markLineDirections() in views/note-detail.js). A ::before pinned to
	   the item's own inline-start follows that item's direction instead, so an
	   Arabic bullet sits on the right and an English one on the left, each flush
	   with the text above it. The list markup is untouched: what is stored,
	   exported and pasted elsewhere is still a real <ul>/<ol>. This also drops the
	   browser's 40px indent, which ate a third of a phone's width. */
	& ul, & ol {
		list-style: none;
		margin-block: var(--space-2xs);
		padding-inline-start: 0;
	}
	& ol { counter-reset: note-item; }
	& ol > li { counter-increment: note-item; }

	& li {
		position: relative;
		padding-inline-start: 1em;

		&::before {
			position: absolute;
			inset-inline-start: 0;
			color: var(--text-dim);
		}
	}
	/* A number is wider than a bullet, so the same 1em would leave "10." touching
	   its text. The marker still starts at the item's edge either way — only the
	   text moves. */
	& ol > li { padding-inline-start: 1.6em; }

	/* The bullet is furniture, not text, so it is drawn in the UI font rather than
	   the note's: Cairo's • is a small square, which reads as a different kind of
	   list rather than as the same bullet. The numbers stay in the note's font —
	   they are content, and they sit in the reading line. */
	& ul > li::before {
		content: "•";
		font-family: system-ui, sans-serif;
	}
	& ol > li::before { content: counter(note-item) "."; }
	/* contenteditable has no native placeholder — fake one while truly empty. */
	&:empty::before {
		content: attr(data-placeholder);
		color: var(--text-faint);
		pointer-events: none;
	}
}
/* Code chips, in the editor and in the Settings legend that documents them — one
   rule for both, so the legend shows what you actually get. */
.editor-body code,
.shortcut-gives code {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 0.9em;
	background: var(--surface-2);
	border-radius: var(--radius-small);
	padding: 0.1em 0.35em;
}

/* ─── Drag-and-drop attach target ────────────────────────────────────────── */
.editor.dragging { outline: 2px dashed var(--color-primary); outline-offset: -4px; }
.drop-veil {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: grid;
	place-content: center;
	justify-items: center;
	gap: var(--space-xs);
	border-radius: var(--radius-card, 16px);
	background: color-mix(in srgb, var(--surface-2) 88%, transparent);
	color: var(--color-primary);
	font: var(--font-body-large-bold);
	/* Must not intercept the drag — it sits over the very element listening. */
	pointer-events: none;

	& svg.icon { font-size: 2rem; }
}

/* ─── Attachment chips (a note's files and a to-do's alike) ──────────────── */
.attach-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-2xs);
	margin-top: var(--space-s);
	padding: 0;
	list-style: none;
}
.attach-chip {
	display: flex;
	align-items: center;
	gap: var(--space-xs);
	padding: var(--space-2xs) var(--space-xs);
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: var(--radius-card, 16px);

	& > svg.icon { flex: none; color: var(--text-faint); }
}
.attach-name {
	flex: 1;
	min-width: 0;
	color: var(--text);
	text-decoration: none;

	&:hover { text-decoration: underline; }
}
.attach-size { flex: none; font: var(--font-body-xsmall-regular); }

.color-row {
	display: flex;
	gap: var(--space-s);
	padding-top: var(--space-s);
	margin-top: var(--space-xs);
	border-top: 1px solid var(--border);
}
.swatch {
	width: 28px; height: 28px;
	border-radius: 50%;
	border: 2px solid var(--border);
	cursor: pointer;
	padding: 0;
}
.swatch.on { border-color: var(--text); transform: scale(1.1); }
.swatch-default { background: var(--surface-3); }
.swatch-yellow  { background: #b8a23a; }
.swatch-green   { background: #2f9e63; }
.swatch-blue    { background: #3a86c8; }
.swatch-pink    { background: #c8497e; }
.swatch-purple  { background: #8a52c8; }

/* ─── Empty state ───────────────────────────────────────────────────────── */
.empty {
	text-align: center;
	color: var(--text-dim);
	padding: 60px var(--space-l);
}
.empty .icon { font-size: 54px; color: var(--surface-3); margin-bottom: var(--space-s); }
.empty p { margin: var(--space-2xs) 0; }

/* ─── Search ────────────────────────────────────────────────────────────── */
.search-input {
	width: 100%;
	background: var(--input-bg);
	border: 1px solid var(--border);
	color: var(--text);
	border-radius: 12px;
	padding: var(--space-s) var(--space-m);
	font: var(--font-body-large-regular);
	margin-bottom: var(--space-m);
}
.search-input:focus { outline: none; border-color: var(--color-primary); }

/* ─── Settings ──────────────────────────────────────────────────────────── */
.settings-stats {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--space-s);
	margin-bottom: var(--space-l);
}
.stat {
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: var(--radius-card, 16px);
	padding: var(--space-l) var(--space-s);
	text-align: center;
}
.stat-num { font: var(--font-h3); color: var(--color-primary-on-surface); }
.stat-label { font: var(--font-body-small-regular); color: var(--text-dim); margin-top: var(--space-3xs); }
.settings-list { display: flex; flex-direction: column; gap: var(--space-xs); }
.settings-item {
	display: flex;
	align-items: center;
	gap: var(--space-s);
	width: 100%;
	background: var(--surface-2);
	border: 1px solid var(--border);
	color: var(--text);
	border-radius: 12px;
	padding: var(--space-m);
	font: var(--font-body-large-medium);
	cursor: pointer;
}
.settings-item:hover { background: var(--surface-3); }
.settings-item:disabled { opacity: 0.6; cursor: default; }
.settings-item .icon { font-size: 22px; color: var(--text-dim); }
/* Trailing state label (e.g. the On/Off on the reminders toggle). */
.settings-state {
	margin-inline-start: auto;
	font: var(--font-body-medium-bold);
	color: var(--color-primary-on-surface);
}
.settings-item[aria-checked="false"] .settings-state { color: var(--text-faint); }
.settings-hint { margin: var(--space-xs) var(--space-2xs) 0; font: var(--font-body-small-regular); }

/* Formatting legend: what you type on the left, what it becomes on the right. One
   card of rows rather than a row of cards — it is a reference, not a control. */
.shortcut-list {
	display: grid;
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: var(--space-2xs) var(--space-m);
}
.shortcut-row {
	display: grid;
	/* Named, absolute columns: the trigger never drifts to the result's side. */
	grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
	align-items: center;
	gap: var(--space-s);
	padding: var(--space-s) 0;

	& + & { border-top: 1px solid var(--border); }

	& .shortcut-arrow { color: var(--text-faint); }
}
.shortcut-type {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 0.9em;
	color: var(--text-dim);
	overflow-wrap: anywhere;
}
.shortcut-gives {
	font: var(--font-body-large-regular);
	color: var(--text);
	justify-self: end;
	text-align: end;
	overflow-wrap: anywhere;
}
.settings-foot {
	margin-top: var(--space-xl);
	text-align: center;
	font: var(--font-body-small-regular);

	/* Which shell snapshot this device booted from — see js/version.js. */
	.settings-version {
		display: block;
		margin-top: var(--space-2xs);
		color: var(--text-faint);
		font-variant-numeric: tabular-nums;
	}
}

/* ─── Segmented control (theme toggle) ──────────────────────────────────── */
.seg {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 1fr;
	gap: var(--space-2xs);
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: var(--space-2xs);
	margin-bottom: var(--space-m);

	& button {
		border: none;
		background: none;
		color: var(--text-dim);
		font: var(--font-body-small-semibold);
		padding: var(--space-xs);
		border-radius: 9px;
		cursor: pointer;
		display: grid;
		grid-auto-flow: column;
		align-items: center;
		justify-content: center;
		gap: var(--space-2xs);

		& .icon { font-size: 18px; }
		&.on { background: var(--color-primary); color: #fff; }
	}
}

/* ─── Auth page ─────────────────────────────────────────────────────────── */
.auth-page { min-height: 100dvh; display: grid; place-items: center; padding: var(--space-l); }
.auth-card {
	width: 100%;
	max-width: 380px;
	text-align: center;
	background: var(--surface);
	border: 1px solid var(--border);
	border-radius: 20px;
	padding: var(--space-2xl) var(--space-xl);
}
.auth-logo {
	width: 72px; height: 72px;
	border-radius: 20px;
	background: var(--color-primary-grad);
	display: grid; place-items: center;
	margin: 0 auto var(--space-l);
	color: #fff;
}
.auth-logo .icon { font-size: 40px; }
.auth-title { font: var(--font-h3); margin: 0 0 var(--space-xs); }
.auth-subtitle { color: var(--text-dim); margin: 0 0 var(--space-xl); font: var(--font-body-medium-regular); }
.auth-actions { display: flex; flex-direction: column; gap: var(--space-s); }
.auth-hint {
	color: var(--text-dim);
	font: var(--font-body-small-regular);
	margin: 0 0 var(--space-l);
	line-height: 1.5;

	/* Losing local-only notes is the one consequence worth colouring for. */
	&.auth-hint--warn {
		color: var(--danger);
		background: color-mix(in oklch, var(--danger) 8%, transparent);
		border-radius: 12px;
		padding: var(--space-s);
		text-align: start;
	}
}
.auth-error { color: var(--danger); font: var(--font-body-small-medium); margin-top: var(--space-m); }

/* ─── Account recovery (Settings → Your account) ──────────────────────────── */
/* Shown only while an account has no passkey and no linked device, i.e. while
   the session token on this device is the only way back to the notes. */
.settings-warn {
	margin: 0 var(--space-2xs) var(--space-s);
	padding: var(--space-s) var(--space-m);
	border-radius: 12px;
	background: color-mix(in oklch, var(--danger) 8%, transparent);
	border: 1px solid color-mix(in oklch, var(--danger) 25%, transparent);
	color: var(--danger);
	font: var(--font-body-small-regular);
	line-height: 1.5;
}

/* ─── Pairing QR dialog ───────────────────────────────────────────────────── */
.qr-backdrop {
	position: fixed;
	inset: 0;
	z-index: 80;
	display: grid;
	place-items: center;
	padding: var(--space-l);
	background: rgb(0 0 0 / 0.55);
}
.qr-card {
	inline-size: min(340px, 100%);
	display: grid;
	gap: var(--space-m);
	justify-items: center;
	text-align: center;
	padding: var(--space-xl);
	border-radius: 20px;
	background: var(--surface);
	border: 1px solid var(--border);
}
.qr-title { font: var(--font-h4, var(--font-h3)); margin: 0; }
.qr-code {
	inline-size: min(240px, 60vmin);
	aspect-ratio: 1;
	padding: var(--space-s);
	border-radius: 12px;

	/* A scanner needs real contrast and a light quiet zone, so this block keeps
	   its own colours in both themes rather than inheriting the surface. */
	background: #fff;
	color: #000;

	& svg { inline-size: 100%; block-size: 100%; display: block; }
}
.qr-actions { display: grid; grid-auto-flow: column; gap: var(--space-s); }

/* The new key's secret, shown once. Wide, monospaced and selectable — if the
   clipboard is unavailable the user has to be able to read and copy it by eye. */
.api-key-secret {
	inline-size: 100%;
	padding: var(--space-s);
	border-radius: 10px;
	background: var(--surface-2);
	border: 1px solid var(--border);
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 0.85em;
	text-align: start;
	overflow-wrap: anywhere;
	user-select: all;
}

/* One row per issued key. Named columns so the revoke button stays pinned to the
   end no matter how long the name runs. */
.api-key-list {
	display: grid;
	gap: var(--space-xs);
	margin-top: var(--space-xs);
}
.api-key-row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	grid-template-rows: auto auto;
	align-items: center;
	gap: var(--space-3xs) var(--space-s);
	padding: var(--space-s) var(--space-m);
	background: var(--surface-2);
	border: 1px solid var(--border);
	border-radius: 12px;

	& .api-key-name {
		grid-row: 1;
		grid-column: 1;
		font: var(--font-body-medium-bold);
		overflow-wrap: anywhere;
	}
	/* Second row, spanning the label columns: identity above, detail below. */
	& .api-key-hint,
	& .api-key-used {
		grid-row: 2;
		font: var(--font-body-small-regular);
		color: var(--text-dim);
	}
	& .api-key-hint {
		grid-column: 1;
		font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	}
	& .api-key-used { grid-column: 2; justify-self: end; }
	& .btn {
		grid-row: 1;
		grid-column: 2;
		justify-self: end;
	}
}

@media (max-width: 400px) {
	.notes-grid { grid-template-columns: repeat(2, 1fr); gap: var(--space-s); }
}

/* ─── Pull-to-refresh (notes) ─────────────────────────────────────────────── */
.ptr-indicator {
	position: fixed;
	top: 0;
	left: 50%;
	z-index: 60;
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	margin-top: -48px;               /* parked just above the viewport */
	border-radius: 50%;
	background: var(--surface-2);
	border: 1px solid var(--border);
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
	opacity: 0;
	transform: translateX(-50%);
	transition: transform 0.2s ease, opacity 0.2s ease;
	pointer-events: none;

	&.dragging { transition: none; }  /* track the finger 1:1 while pulling */

	& .ptr-spinner {
		width: 20px;
		height: 20px;
		border-radius: 50%;
		border: 2px solid var(--surface-3);
		border-top-color: var(--text-faint);
	}

	&.ready .ptr-spinner { border-top-color: var(--color-primary); }
	&.busy  .ptr-spinner { border-top-color: var(--color-primary); animation: spin 0.8s linear infinite; }
}
