/* AUTO-SYNCED by design/tokens/build_tokens.py — DO NOT EDIT THIS COPY.
   Canonical source: design/components/components.css. Edit there, then
   re-run the generator (and bump ?v=N on the <link> in base.html). */

/* ═══════════════════════════════════════════════════════════════════════════
   eduNotes — CANONICAL COMPONENT LIBRARY (Stage 2)
   ───────────────────────────────────────────────────────────────────────────
   Built entirely from the design tokens in static/css/tokens.css (generated
   from design/tokens/tokens.yaml). NO raw colour/spacing/radius literals here —
   everything resolves through var(--token). This file is the source of truth
   for web component styling; Stage 4 swaps it in to replace styles.css per page.

   Codifies docs/components.md (§1–13) + DESIGN.md, with the parity-audit fixes
   baked in (§4 modal chrome, page-header accent bar, shared empty state,
   sentence-case modal titles, "·" separators).

   Light + dark both supported via html[data-theme="dark"] (from tokens.css).
   Conventions: classes are .c-<component>; state via .is-<state> or :hover etc.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Reset / base for component contexts ──────────────────────────────────── */
.c-scope, .c-scope *, .c-scope *::before, .c-scope *::after { box-sizing: border-box; }
.c-scope {
	font-family: var(--font-ui);
	color: var(--text-body);
	-webkit-font-smoothing: antialiased;

	/* Control heights — every interactive control snaps to one of these so
	   buttons/inputs sitting next to each other are always the same height. */
	--ctl-h: 36px;        /* standard button + input */
	--ctl-h-sm: 30px;     /* small / toolbar density */
	--ctl-h-lg: 44px;     /* modal footer (tap target) */
}

/* Keyboard focus — one visible ring for every interactive control. Uses
   :focus-visible so it only shows for keyboard users, not mouse clicks. */
.c-scope :focus-visible {
	outline: 2px solid var(--secondary);
	outline-offset: 2px;
	border-radius: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   §1 · CARD & PANEL  (three surface levels — level set by nesting, not content)
   ═══════════════════════════════════════════════════════════════════════════ */

/* Top-level card: sits on the page surface → 12px + shadow, never a border. */
.c-card {
	background: var(--surface-card);
	border-radius: var(--radius-lg);          /* 12px */
	box-shadow: var(--shadow-card);
	padding: var(--space-lg) var(--space-xl);  /* 16px 20px */
}

/* Nested card: sits inside another card → 10px + border, never a shadow. */
.c-card-nested {
	background: var(--surface-card);
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);          /* 10px */
	padding: var(--space-md) var(--space-lg);
}

/* Row / list item: divider only. Last row drops the border. */
.c-row {
	display: flex;
	align-items: center;
	gap: var(--space-md);
	padding: var(--space-md) var(--space-lg);
	border-bottom: 1px solid var(--border-subtle);
}
.c-row:last-child { border-bottom: 0; }
.c-row:hover { background: var(--surface-hover); }

/* To-do row: checkbox + title + right-aligned meta (due date + subject tag).
   Used on the Dashboard To-Do card and the /todos page. The active/overdue
   states + the subject tag colour are data, set inline. .is-done strikes the
   title. .c-todo-row--clickable adds a hover affordance (the /todos rows open
   the edit modal). */
.c-todo-list { display: flex; flex-direction: column; }
.c-todo-row {
	display: flex;
	align-items: center;
	gap: var(--space-sm);
	padding: 7px 0;
	border-bottom: 1px solid var(--border-subtle);
}
.c-todo-row:last-child { border-bottom: 0; }
.c-todo-row--clickable { cursor: pointer; border-radius: 6px; }
.c-todo-row--clickable:hover { background: var(--surface-active); }
/* Title + meta share a flex block between the checkbox and the caret. Wide = one
   row (title grows, meta sits right). The .c-todo-row--stacked modifier (narrow
   frames + the Dashboard panel) makes it a two-row column: title (left) over meta
   (right) — so a long title is never crowded by the due date + subject tag. */
.c-todo-row__main { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-sm); }
.c-todo-row--stacked .c-todo-row__main { flex-direction: column; align-items: stretch; gap: 3px; }
.c-todo-row--stacked .c-todo-row__title { flex: 0 0 auto; }
.c-todo-row--stacked .c-todo-row__meta { align-self: flex-end; }
.c-todo-row__check {
	width: 18px;
	height: 18px;
	flex: 0 0 18px;
	padding: 0;
	border-radius: 50%;
	border: 1.5px solid var(--pale);
	background: transparent;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: background 0.12s, border-color 0.12s;
}
.c-todo-row__check.is-checked { background: var(--primary); border-color: var(--primary); }
.c-todo-row__check .c-icon { width: 11px; height: 11px; color: #fff; }
.c-todo-row__title {
	flex: 1;
	min-width: 0;
	font-size: 13px;
	color: var(--text-body);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.c-todo-row.is-done .c-todo-row__title { text-decoration: line-through; color: var(--text-muted); }
.c-todo-row__meta { display: flex; align-items: center; gap: var(--space-sm); flex-shrink: 0; }
/* "has notes" hint + disclosure caret. The selectors are doubled
   (.c-todo-row …) to out-specify the generic `.c-icon { width:1em }` rule that
   sits later in this file — otherwise the SVGs fall back to 1em and the carets
   stop sharing a vertical line. */
.c-todo-row .c-todo-row__notehint { width: 12px; height: 12px; color: var(--text-muted); }
.c-todo-row__due { font-size: 10px; font-weight: 500; color: var(--text-muted); white-space: nowrap; }
.c-todo-row__due.is-overdue { color: #EF4444; font-weight: 600; }
/* Disclosure caret — present only when the row is expandable (the /todos page).
   Rotation is owned by the expandable wrapper (.td-todo.is-expanded). */
.c-todo-row .c-todo-row__caret { width: 14px; height: 14px; flex: 0 0 14px; color: var(--text-muted); transition: transform var(--motion-chevron); }
.c-todo-row__tag {
	font-size: 10px;
	font-weight: 600;
	padding: 2px 7px;
	border-radius: var(--radius-pill);
	white-space: nowrap;
}
html[data-theme="dark"] .c-todo-row__due.is-overdue { color: #F87171; }

/* ═══════════════════════════════════════════════════════════════════════════
   §11 · PAGE HEADER  (accent bar + title/subtitle + trailing actions)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-page-header {
	display: flex;
	align-items: flex-start;
	gap: var(--space-md);
	margin-bottom: var(--space-xl);
}
.c-page-header__accent {
	flex: 0 0 auto;
	width: 4px;
	align-self: stretch;
	min-height: 38px;
	border-radius: 2px;
	background: var(--primary);               /* override inline with subject colour */
}
.c-page-header__text { flex: 1 1 auto; min-width: 0; }
.c-page-header__title {
	font-size: 24px;
	font-weight: 700;
	color: var(--text-body);
	letter-spacing: -0.02em;
	line-height: 1.15;
}
.c-page-header__subtitle {
	font-size: var(--fs-small);               /* 14px */
	color: var(--text-muted);
	margin-top: 2px;
}
.c-page-header__actions { display: flex; align-items: center; gap: var(--space-sm); }

/* Generic h1/h2 (analytical, blue) — reserve --text-heading for true headings. */
.c-h1 { font-size: var(--fs-h1); font-weight: 600; color: var(--text-heading); letter-spacing: -0.02em; }
.c-h2 { font-size: var(--fs-h2); font-weight: 600; color: var(--text-heading); letter-spacing: -0.01em; }

/* ═══════════════════════════════════════════════════════════════════════════
   §3 · BUTTONS  (primary / ghost / danger / small)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	height: var(--ctl-h);                     /* fixed height → uniform with peers */
	padding: 0 1rem;
	font-family: var(--font-ui);
	font-size: var(--fs-small);               /* 14px */
	font-weight: 500;
	line-height: 1;
	border-radius: var(--radius-sm);          /* 8px */
	border: 1.5px solid transparent;          /* keeps bordered + fill variants the same box */
	cursor: pointer;
	transition: background var(--motion-fast), color var(--motion-fast), opacity var(--motion-fast);
	white-space: nowrap;
}
.c-btn-sm { height: var(--ctl-h-sm); padding: 0 0.85rem; font-size: 0.8rem; }

/* Primary — filled. Fill STAYS --primary in dark mode (key indicator). */
.c-btn-primary { background: var(--primary); color: #fff; }
.c-btn-primary:hover { background: var(--secondary); }

/* Ghost — outline that fills on hover. Border+text swap to secondary in dark. */
.c-btn-ghost { background: transparent; color: var(--dusty); border-color: transparent; }
.c-btn-ghost:hover { background: var(--surface-hover); color: var(--primary); }

/* Study-action ghost (History / Flashcards / Written Recall) — peer actions,
   identical styling, primary border. Swaps to secondary in dark (accent swap). */
.c-btn-study {
	background: transparent;
	color: var(--primary);
	border: 1.5px solid var(--primary);
	border-radius: var(--radius-sm);
	padding: 0 14px;                          /* height comes from .c-btn → matches primary */
	font-size: 12.5px;
	font-weight: 600;
}
.c-btn-study:hover { background: var(--primary); color: #fff; }

/* Danger */
.c-btn-danger { background: var(--plum); color: #fff; }
.c-btn-danger:hover { opacity: 0.85; }

.c-btn:disabled, .c-btn.is-disabled { opacity: 0.4; cursor: default; pointer-events: none; }

html[data-theme="dark"] .c-btn-ghost { color: #5B8FC4; }
html[data-theme="dark"] .c-btn-ghost:hover { background: rgba(255,255,255,0.08); color: var(--dusty); }
html[data-theme="dark"] .c-btn-study { color: var(--secondary); border-color: var(--secondary); }
html[data-theme="dark"] .c-btn-study:hover { background: var(--secondary); color: var(--text-body); }

/* ═══════════════════════════════════════════════════════════════════════════
   INPUTS & FIELDS  (general form controls; modal-specific variants in §4)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-field { display: flex; flex-direction: column; gap: 6px; }
.c-label { font-size: 13px; font-weight: 500; color: var(--text-muted); }
.c-input, .c-select, .c-textarea {
	font-family: var(--font-ui);
	font-size: var(--fs-small);
	color: var(--text-body);
	background: var(--surface-card);
	border: 1px solid var(--border-normal);
	border-radius: var(--radius-sm);
	padding: 0.5rem 0.7rem;
	width: 100%;
}
.c-input, .c-select { height: var(--ctl-h); padding: 0 0.7rem; }   /* align with buttons */
.c-textarea { resize: vertical; min-height: 80px; }
.c-input:focus, .c-select:focus, .c-textarea:focus {
	outline: none;
	border-color: var(--secondary);
	box-shadow: 0 0 0 2px rgba(0,71,171,0.1);
}
.c-input::placeholder, .c-textarea::placeholder { color: var(--text-muted); }
html[data-theme="dark"] .c-input, html[data-theme="dark"] .c-select, html[data-theme="dark"] .c-textarea {
	background: var(--surface-page);
}

/* Password field — a .c-input with an inline show/hide eye toggle. Promoted from
   the live auth pages (wave 12): a reusable widget, not an auth-only concern (any
   future password/secret field reuses it). The input reserves right padding for the
   button; the toggle swaps the #i-eye / #i-eye-off sprite icon (set class="c-icon"
   on the <use>'s <svg> so the fill applies — the recurring sprite gotcha). */
.c-pw-field { position: relative; }
.c-pw-field .c-input { padding-right: 2.4rem; }
.c-pw-field__toggle {
	position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
	display: flex; align-items: center; justify-content: center;
	width: 28px; height: 28px;
	background: none; border: 0; cursor: pointer;
	color: var(--text-muted); border-radius: var(--radius-sm);
	transition: color 0.1s, background 0.1s;
}
.c-pw-field__toggle:hover { color: var(--primary); background: var(--surface-hover); }
.c-pw-field__toggle svg { width: 16px; height: 16px; }
html[data-theme="dark"] .c-pw-field__toggle:hover { color: var(--text-body); background: rgba(255,255,255,0.08); }

/* Search field (sidebar / toolbar) */
.c-search {
	display: flex; align-items: center; gap: 8px;
	height: 36px; padding: 0 10px;
	background: var(--surface-card);
	border: 1px solid var(--border-normal);
	border-radius: 10px;
}
.c-search input { border: 0; background: transparent; outline: none; font-size: 13px; color: var(--text-body); flex: 1; }
.c-search svg, .c-search .c-search__icon { color: var(--text-muted); width: 14px; height: 14px; }
html[data-theme="dark"] .c-search { background: var(--surface-page); border-color: var(--border-subtle); }

/* Custom select — replaces the native <select> everywhere (matches the app's
   custom-select: a styled trigger + a cs-panel-style options list). */
.c-dropdown { position: relative; display: inline-block; }
.c-dropdown__trigger {
	display: inline-flex; align-items: center; justify-content: space-between; gap: 8px;
	height: var(--ctl-h); padding: 0 0.7rem; min-width: 150px; width: 100%;
	background: var(--surface-card); border: 1px solid var(--border-normal);
	border-radius: var(--radius-sm); font-size: var(--fs-small); color: var(--text-body); cursor: pointer;
}
.c-dropdown__trigger:focus, .c-dropdown.is-open .c-dropdown__trigger {
	outline: none; border-color: var(--secondary); box-shadow: 0 0 0 2px rgba(0,71,171,0.1);
}
.c-dropdown__chevron { color: var(--text-muted); font-size: 10px; }
.c-dropdown__panel {
	position: absolute; top: calc(100% + 4px); left: 0; min-width: 100%;
	background: var(--surface-card); border: 1px solid var(--border-normal); border-radius: 6px;
	box-shadow: 0 4px 14px rgba(0,0,0,0.12); padding: 0.25rem 0; max-height: 280px; overflow-y: auto; z-index: 50;
}
.c-dropdown__item { padding: 0.3rem 0.75rem; font-size: 0.85rem; cursor: pointer; color: var(--text-body); }
.c-dropdown__item:hover, .c-dropdown__item.is-active { background: var(--ice); color: var(--primary); }
html[data-theme="dark"] .c-dropdown__trigger { background: var(--surface-page); }
html[data-theme="dark"] .c-dropdown__panel { background: var(--surface-card); border-color: var(--border-subtle); }
html[data-theme="dark"] .c-dropdown__item:hover, html[data-theme="dark"] .c-dropdown__item.is-active { background: var(--surface-active); color: var(--secondary); }

/* Shared icon sizing (inline SVG via <use>) */
.c-icon { width: 1em; height: 1em; display: inline-block; fill: currentColor; flex: 0 0 auto; vertical-align: -0.125em; }

/* ═══════════════════════════════════════════════════════════════════════════
   §4 · MODAL  (the one custom modal — same design on web + all native platforms)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-modal-overlay {
	position: fixed; inset: 0; z-index: 1000;   /* covers the viewport in-app; gallery demos override to absolute */
	background: rgba(0,0,0,0.35);
	display: flex; align-items: center; justify-content: center;
	padding: var(--space-xl);
}
.c-modal {
	background: var(--surface-card);
	border-radius: var(--radius-modal);       /* 20px */
	box-shadow: 0 8px 40px rgba(0,0,0,0.18), 0 2px 8px rgba(0,0,0,0.08);
	width: 520px; max-width: 100%;
	display: flex; flex-direction: column;
	overflow: hidden;
}
.c-modal--simple { width: 360px; }
.c-modal--medium { width: 520px; }
.c-modal--wide   { width: 680px; }

.c-modal__header {
	display: flex; align-items: center;
	padding: var(--space-lg) var(--space-xl) var(--space-md);
}
.c-modal__header-spacer { width: 28px; flex: 0 0 28px; }
.c-modal__title { flex: 1; text-align: center; font-size: 17px; font-weight: 600; color: var(--text-body); }
.c-modal__close {
	width: 28px; height: 28px; flex: 0 0 28px;
	border: 0; border-radius: 50%;
	background: var(--fill-input); color: var(--text-muted);
	cursor: pointer; display: flex; align-items: center; justify-content: center;
	font-size: 15px;
}
.c-modal__close:hover { color: var(--text-body); }
html[data-theme="dark"] .c-modal__close { background: var(--border-subtle); }

.c-modal__body { padding: var(--space-lg) var(--space-xl) var(--space-xs); overflow-y: auto; }
.c-modal__footer {
	display: flex; flex-direction: column; gap: var(--space-sm);
	padding: var(--space-sm) var(--space-xl) var(--space-xl);
}
.c-modal__footer .c-btn { width: 100%; }
/* Footer primary uses 12px radius + 15px per §4 */
.c-modal__footer .c-btn-primary,
.c-modal__footer .c-btn-danger,
.c-modal__footer .c-btn-cancel { height: var(--ctl-h-lg); padding: 0 1rem; border-radius: var(--radius-lg); font-size: 15px; font-weight: 600; }
.c-btn-cancel { background: var(--fill-input); color: var(--text-body); border: 0; cursor: pointer; }
.c-btn-cancel:hover { filter: brightness(0.97); }
html[data-theme="dark"] .c-btn-cancel { background: var(--border-subtle); }

/* Modal field (label above, filled rounded input) */
.c-modal-field { margin-bottom: var(--space-lg); }
.c-modal-field__label { display: block; font-size: 13px; font-weight: 500; color: var(--text-muted); margin-bottom: 6px; }
.c-modal-field__input {
	width: 100%; font-size: 15px; font-family: var(--font-ui);
	background: var(--fill-input); border: 0; border-radius: var(--radius-md);
	padding: 0.55rem 0.7rem; color: var(--text-body);
}
.c-modal-field__input:focus { outline: none; box-shadow: 0 0 0 2px rgba(0,71,171,0.15); }
html[data-theme="dark"] .c-modal-field__input { background: var(--surface-page); }

/* ── Confirm-delete (type-the-target-to-confirm danger block) ───────────────
   Shared: the Admin user-detail modal (inline, button inside) + the Account
   delete modal (in a .c-modal body, button in the footer). Just a prompt line +
   a .c-input; the danger confirm button is placed by the consumer. */
.c-confirm-delete { display: flex; flex-direction: column; gap: 8px; }
.c-confirm-delete__prompt { font-size: 13px; color: var(--text-muted); line-height: 1.5; }
.c-confirm-delete__prompt strong { color: var(--text-body); }
.c-confirm-delete .c-btn { align-self: flex-start; }   /* inline-button consumers (admin) */

/* Step indicator (multi-step modals) */
.c-steps { display: flex; align-items: center; justify-content: center; gap: 0; margin-bottom: var(--space-lg); }
.c-step { display: flex; align-items: center; gap: 8px; }
.c-step__dot {
	width: 24px; height: 24px; border-radius: 50%;
	display: flex; align-items: center; justify-content: center;
	font-size: 12px; font-weight: 600;
	background: var(--border-subtle); color: var(--text-muted);
}
.c-step.is-active .c-step__dot { background: var(--primary); color: #fff; }
.c-step.is-done .c-step__dot { background: var(--primary); color: #fff; }
.c-step__label { font-size: 12px; color: var(--text-muted); }
.c-step.is-active .c-step__label { color: var(--text-body); font-weight: 600; }
.c-step__line { width: 36px; height: 1.5px; background: var(--border-subtle); margin: 0 8px; }

/* Segmented pill control (event-type selector) */
.c-segment { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.c-segment__btn {
	font-size: 13px; font-weight: 500;
	padding: 6px 14px; border-radius: var(--radius-pill);
	background: transparent; color: var(--text-muted);
	border: 1.5px solid var(--border-normal); cursor: pointer;
}
.c-segment__btn.is-active { background: var(--primary); color: #fff; border-color: var(--primary); }

/* ═══════════════════════════════════════════════════════════════════════════
   §2 · TWO-LEVEL ACCORDION  (subject → folder/series → rows)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-accordion { background: var(--surface-card); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); overflow: hidden; }
.c-accordion__head {
	display: flex; align-items: center; gap: var(--space-md);
	padding: 14px 16px; cursor: pointer;
}
.c-accordion__dot { width: 12px; height: 12px; border-radius: 50%; flex: 0 0 12px; background: var(--primary); }
.c-accordion__name { font-weight: 700; font-size: var(--fs-small); flex: 1; }
.c-accordion__meta { font-size: var(--fs-meta); color: var(--text-muted); }
.c-accordion__chevron { color: var(--text-muted); transition: transform var(--motion-chevron); }
.c-accordion.is-open .c-accordion__chevron { transform: rotate(90deg); }

.c-accordion__nested {
	margin: 0 16px 14px;
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-md);
	overflow: hidden;
}
.c-accordion__nested-head {
	display: flex; align-items: center; gap: 10px;
	padding: 12px 14px; cursor: pointer;
}
.c-accordion__nested-head .c-accordion__dot { width: 10px; height: 10px; flex-basis: 10px; }
.c-accordion__items { border-top: 1px solid var(--border-subtle); }
.c-accordion__item { display: flex; align-items: center; gap: var(--space-md); padding: 0 16px; height: 50px; border-bottom: 1px solid var(--border-subtle); }
.c-accordion__item:last-child { border-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   §12 · PAGE CONTENT CARD  (one non-collapsible grouping surface + toolbar)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-content-card { background: var(--surface-card); border-radius: var(--radius-lg); box-shadow: var(--shadow-card); overflow: hidden; }
.c-content-card__toolbar {
	display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
	padding: 10px 12px;
	border-bottom: 1px solid var(--border-subtle);
}
.c-content-card__body { padding: 10px 12px 12px; }

/* ═══════════════════════════════════════════════════════════════════════════
   §13 · STAT STRIP  (dashboard — 4 equal cards)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-stat-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-md); }
/* Compact override — driven explicitly by narrow mockup frames (iOS / web-mobile),
   where CSS media queries can't see the simulated device width. Real app still
   gets the @720px media-query collapse below. */
.c-stat-strip--2col { grid-template-columns: repeat(2, 1fr); }
.c-stat-card {
	display: flex; align-items: center; gap: var(--space-md);
	background: var(--surface-card); border-radius: var(--radius-lg);
	box-shadow: var(--shadow-card); padding: 14px 16px;
}
.c-stat-card__icon {
	width: 36px; height: 36px; flex: 0 0 36px;
	border-radius: var(--radius-sm);
	display: flex; align-items: center; justify-content: center;
	color: var(--secondary);
	background: var(--ice);                    /* flat grey #383838 in dark — below */
}
.c-stat-card__value { font-size: 24px; font-weight: 700; letter-spacing: -0.03em; color: var(--text-body); line-height: 1; }
.c-stat-card__label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); margin-top: 3px; }
/* Plain variant — no icon, compact value-over-label (Account stats strip; any
   place wanting a bare label/value stat). --sm value for text values (dates). */
.c-stat-card--plain { padding: 14px 16px; }
.c-stat-card__value--sm { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.3; }
html[data-theme="dark"] .c-stat-card__icon { background: #383838; }     /* not a darkened ice */
@media (max-width: 720px) { .c-stat-strip { grid-template-columns: repeat(2, 1fr); } }

/* ═══════════════════════════════════════════════════════════════════════════
   §7 · SECTION LABEL
   ═══════════════════════════════════════════════════════════════════════════ */
.c-section-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: var(--space-sm); }
.c-section-label--muted { color: var(--text-muted); }     /* grouping: UNFILED, PAPERS */
.c-section-label--blue  { color: var(--primary); }       /* analytical: TOPIC BREAKDOWN — primary for AA at small size */

/* ═══════════════════════════════════════════════════════════════════════════
   §5 · PROXIMITY BAR
   ═══════════════════════════════════════════════════════════════════════════ */
.c-proximity { position: relative; width: 100%; height: 6px; border-radius: 3px; background: var(--border-subtle); overflow: hidden; }
.c-proximity__fill { height: 100%; border-radius: 3px; background: var(--secondary); }  /* grade colour set inline for scores */
/* Grade-boundary ticks: thin verticals at boundary %, positioned inline via left. */
.c-proximity__tick { position: absolute; top: 0; bottom: 0; width: 1px; background: rgba(0,0,0,0.22); }
html[data-theme="dark"] .c-proximity__tick { background: rgba(255,255,255,0.28); }

/* ═══════════════════════════════════════════════════════════════════════════
   §8 · GRADE CHIP  + §9 COUNT BADGE  + subject dots
   Grade colours mirror tokens.yaml `grades` / GradeHelpers.swift. Dark mode:
   bar colour as text on bar-at-22%. We expose per-grade vars to keep it tokenised.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-grade {
	--g-bg: #E5E7EB; --g-text: #374151; --g-bar: #9CA3AF;   /* U/Fail default */
	display: inline-flex; align-items: center; justify-content: center;
	font-weight: 700; background: var(--g-bg); color: var(--g-text);
}
.c-grade--square { width: 30px; height: 30px; border-radius: var(--radius-sm); font-size: 13px; }
.c-grade--pill { border-radius: var(--radius-pill); padding: 3px 10px; font-size: 12px; }

/* Grade palette lives on the bare .g-* classes (not compound .c-grade.g-*) so
   other grade-coloured viz — topic-breakdown bar fills, score-trend dots — can
   reuse the same --g-bar token by adding a g-* class. Chips carry BOTH .c-grade
   and .g-X, so this is transparent to them. Single source for grade colour. */
.g-9  { --g-bg:#BBF7D0; --g-text:#14532D; --g-bar:#10B981; }
.g-8  { --g-bg:#D9F99D; --g-text:#365314; --g-bar:#84CC16; }
.g-7  { --g-bg:#ECFCCB; --g-text:#3F6212; --g-bar:#A3E635; }
.g-b  { --g-bg:#FEF08A; --g-text:#854D0E; --g-bar:#EAB308; }
.g-6  { --g-bg:#FED7AA; --g-text:#7C2D12; --g-bar:#F97316; }
.g-5  { --g-bg:#FDBA74; --g-text:#92400E; --g-bar:#FB923C; }
.g-4  { --g-bg:#FCA5A5; --g-text:#991B1B; --g-bar:#EF4444; }
.g-low{ --g-bg:#FECACA; --g-text:#991B1B; --g-bar:#F87171; }
.g-u  { --g-bg:#E5E7EB; --g-text:#374151; --g-bar:#9CA3AF; }
/* Dark: use the bar colour as text on bar@22% (set per chip via color-mix). */
html[data-theme="dark"] .c-grade {
	background: color-mix(in srgb, var(--g-bar) 22%, transparent);
	color: var(--g-bar);
}

.c-badge { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-md); }
.c-badge--fc { background: var(--ice); color: var(--primary); }
.c-badge--rq { background: #f3e8ff; color: #6b21a8; }
.c-count { font-size: var(--fs-meta); color: var(--text-muted); }

.c-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
/* subject palette: set background inline; reference list in the gallery */

/* ═══════════════════════════════════════════════════════════════════════════
   §6 · EMPTY STATE
   ═══════════════════════════════════════════════════════════════════════════ */
.c-empty { text-align: center; padding: 40px 20px; max-width: 320px; margin: 0 auto; }
.c-empty__icon { font-size: 40px; color: var(--pale); line-height: 1; }
.c-empty__title { font-size: 15px; font-weight: 600; color: var(--text-body); margin-top: var(--space-md); }
.c-empty__subtitle { font-size: 13px; color: var(--text-muted); max-width: 260px; margin: 6px auto 0; line-height: 1.5; }
.c-empty .c-btn { margin-top: var(--space-md); }
html[data-theme="dark"] .c-empty__icon { color: #48484A; }       /* pale has no dark variant */
html[data-theme="dark"] .c-empty__title { color: #D1D1D6; }
html[data-theme="dark"] .c-empty__subtitle { color: #636366; }

/* ═══════════════════════════════════════════════════════════════════════════
   §10 · CONTEXT MENU (kebab)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-kebab {
	width: 28px; height: 28px; border: 0; border-radius: 50%;
	background: transparent; color: var(--text-muted); cursor: pointer;
	display: inline-flex; align-items: center; justify-content: center;
}
.c-kebab:hover { background: var(--surface-hover); }
.c-menu {
	background: var(--surface-card);
	border: 1px solid var(--border-subtle);
	border-radius: 6px;
	box-shadow: var(--shadow-elevated);
	padding: 4px 0; min-width: 160px;
}
.c-menu__item { font-size: 13px; padding: 7px 14px; cursor: pointer; color: var(--text-body); }
.c-menu__item:hover { background: var(--surface-hover); }
.c-menu__item--danger { color: var(--plum); }
.c-menu__item--danger:hover { background: #fff0f4; }
html[data-theme="dark"] .c-menu__item--danger:hover { background: rgba(148,40,90,0.18); }

/* ═══════════════════════════════════════════════════════════════════════════
   §14 · SUBJECT TILE  (the /subjects grid item — colour-accented card)
   A top-level card that carries one subject's identity. The subject colour is a
   4px LEFT RULE (echoes .c-page-header__accent on single-subject pages, so the
   same cue means the same thing everywhere). Set it inline:
       style="--tile-accent: #94285A"
   Layout (the grid + per-frame density) lives in the page's page.css.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-subject-tile {
	position: relative;
	display: flex; flex-direction: column;
	min-height: 124px;
	background: var(--surface-card);
	border-radius: var(--radius-lg);                       /* 12px */
	border-left: 4px solid var(--tile-accent, var(--primary));
	box-shadow: var(--shadow-card);
	padding: var(--space-lg) var(--space-xl) var(--space-md);
	cursor: pointer; text-decoration: none; color: inherit;
	transition: box-shadow var(--motion-fast);
}
.c-subject-tile:hover { box-shadow: var(--shadow-elevated); }
.c-subject-tile__name {
	font-size: 16px; font-weight: 600; color: var(--text-body);
	line-height: 1.3; padding-right: 26px;                 /* clear the kebab */
}
.c-subject-tile__meta { font-size: var(--fs-meta); color: var(--text-muted); margin-top: 3px; }
.c-subject-tile__actions {
	display: flex; gap: var(--space-sm);
	margin-top: auto; padding-top: var(--space-md);        /* min-height floors the tile so this pins to the bottom */
	border-top: 1px solid var(--border-subtle);
}
.c-subject-tile__actions .c-btn { flex: 1; }
/* Kebab — hover-revealed on pointer platforms; pinned top-right. Touch
   platforms (iPad) reveal it via a .win-ipad override in the page's page.css. */
.c-subject-tile__kebab {
	position: absolute; top: 8px; right: 8px;
	opacity: 0; transition: opacity var(--motion-fast);
}
.c-subject-tile:hover .c-subject-tile__kebab,
.c-subject-tile__kebab.is-open { opacity: 1; }
/* Kebab dropdown floats from the kebab (the tile is the positioned ancestor). */
.c-subject-tile__menu { position: absolute; top: 38px; right: 8px; z-index: 20; }

/* ═══════════════════════════════════════════════════════════════════════════
   §15 · SWATCH PICKER  (colour chooser — subject modal; reusable)
   A row of colour circles + a "custom" affordance. The selected swatch gets a
   ring in --text-body (dark-mode-safe). Used in the New/Rename Subject modal;
   reusable for any colour-tagged entity (e.g. dashboard subject/exam colours).
   ═══════════════════════════════════════════════════════════════════════════ */
.c-swatch-picker { display: flex; flex-wrap: wrap; gap: var(--space-sm); align-items: center; }
.c-swatch-picker__swatch {
	width: 28px; height: 28px; border-radius: 50%;
	border: 3px solid transparent; padding: 0; cursor: pointer; flex: 0 0 auto;
	transition: transform var(--motion-fast), border-color var(--motion-fast);
}
.c-swatch-picker__swatch:hover { transform: scale(1.12); }
.c-swatch-picker__swatch.is-selected { border-color: var(--text-body); transform: scale(1.08); }
/* Custom-colour affordance (live: <input type="color">; mockup: a dashed circle). */
.c-swatch-picker__custom {
	width: 28px; height: 28px; border-radius: 50%;
	border: 2px dashed var(--border-normal); background: transparent;
	padding: 0; cursor: pointer; flex: 0 0 auto;
	display: flex; align-items: center; justify-content: center;
	color: var(--text-muted); font-size: 16px; line-height: 1;
}
.c-swatch-picker__custom:hover { border-color: var(--secondary); color: var(--primary); }

/* ═══════════════════════════════════════════════════════════════════════════
   TABLE
   ═══════════════════════════════════════════════════════════════════════════ */
.c-table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.c-table th {
	text-align: left; font-size: 11px; font-weight: 700; text-transform: uppercase;
	letter-spacing: 0.04em; color: var(--text-muted);
	padding: 8px 12px; border-bottom: 1px solid var(--border-subtle);
}
.c-table td { padding: 10px 12px; border-bottom: 1px solid var(--border-subtle); color: var(--text-body); }
.c-table tr:last-child td { border-bottom: 0; }
.c-table tbody tr:hover { background: var(--surface-hover); }

/* ═══════════════════════════════════════════════════════════════════════════
   STUDY-SESSION CARDS  + RATING / SELF-MARK BUTTONS
   ═══════════════════════════════════════════════════════════════════════════ */
.c-study-card {
	background: var(--surface-card); border-radius: var(--radius-lg);
	box-shadow: var(--shadow-card); padding: var(--space-xxl);
	max-width: 620px; margin: 0 auto; text-align: left;   /* matches the left-aligned card faces in the session mockups */
}
.c-study-card__label { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--primary); }
.c-study-card__label--back { color: #30B060; }
.c-study-card__term { font-family: var(--font-serif); font-size: 1.4rem; font-weight: 700; color: var(--text-body); margin-top: var(--space-md); }
.c-study-card__body { font-family: var(--font-serif); font-size: 1rem; color: var(--text-body); margin-top: var(--space-md); }
html[data-theme="dark"] .c-study-card__label--back { color: #4ADE80; }

.c-rating { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-md); max-width: 620px; margin: var(--space-lg) auto 0; }
.c-rating__btn { border: 0; border-radius: var(--radius-md); font-size: 0.9rem; font-weight: 600; padding: 0.6rem 0; cursor: pointer; transition: opacity var(--motion-fast); }
.c-rating__btn:hover { opacity: 0.88; }
.c-rating__btn:active { transform: scale(0.97); }
.c-rating__btn--wrong   { background: #FEE2E2; color: #B91C1C; }
.c-rating__btn--partial { background: #FEF9C3; color: #854D0E; }
.c-rating__btn--correct { background: #DCFCE7; color: #166634; }

/* ═══════════════════════════════════════════════════════════════════════════
   PROGRESS TOP-BAR  (study-session header — back · progress · % · Finish)
   ───────────────────────────────────────────────────────────────────────────
   Shared by the flashcard + written-recall sessions. This is CHROME — it
   follows the theme. Stays ONE compact nowrap row on narrow widths: only the
   track flexes; the back link, %, and Finish never wrap or shrink. The flashcard
   session drops the optional __label ("Card x of y") — redundant with the x/y
   nav above the card — but the class is retained for sessions that want it.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-progress-bar {
	flex-shrink: 0;
	display: flex; align-items: center; gap: 14px;
	padding: 9px 20px;
	background: var(--surface-nav);
	border-bottom: 1px solid var(--border-subtle);
	font-size: 0.82rem; color: var(--text-muted);
}
.c-progress-bar__back {
	flex: 0 0 auto; white-space: nowrap;
	font-size: 0.8rem; color: var(--secondary); text-decoration: none;
}
.c-progress-bar__back:hover { color: var(--primary); }
.c-progress-bar__label { flex: 0 0 auto; white-space: nowrap; }
.c-progress-bar__track {
	flex: 1; min-width: 40px; height: 6px;
	background: var(--powder); border-radius: var(--radius-pill); overflow: hidden;
}
.c-progress-bar__fill {
	display: block; height: 100%; width: 0;
	background: var(--primary); border-radius: var(--radius-pill);
	transition: width var(--motion-base);
}
.c-progress-bar__pct { flex: 0 0 auto; white-space: nowrap; font-size: 0.78rem; }
.c-progress-bar__finish {
	flex: 0 0 auto; white-space: nowrap;
	font-size: 0.8rem; font-weight: 600; line-height: 1;
	padding: 6px 14px; border-radius: var(--radius-md);
	border: 1.5px solid var(--border-normal); background: var(--surface-card);
	color: var(--text-muted); cursor: pointer; font-family: inherit;
	transition: border-color var(--motion-fast), color var(--motion-fast);
}
.c-progress-bar__finish:hover { border-color: var(--secondary); color: var(--primary); }

/* ═══════════════════════════════════════════════════════════════════════════
   ROUGH NOTES  (study-session scratch pad — collapsible, with $…$ KaTeX preview)
   ───────────────────────────────────────────────────────────────────────────
   Shared by the flashcard + written-recall sessions. The panel is an editable
   field, NOT rendered note content — so (Daniel, 2026-05-31) it stays a WHITE
   surface with dark text in BOTH themes, with only a subtle themed border. The
   live page does a debounced $…$ KaTeX preview into __preview (build-time wires
   it; the mockup just shows the markup + a sample rendered preview).
   ═══════════════════════════════════════════════════════════════════════════ */
.c-rough-notes {
	width: 100%;
	background: #fff;
	border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-card);
	overflow: hidden;
}
html[data-theme="dark"] .c-rough-notes { background: #fff; border-color: #3A3A3C; box-shadow: none; }
.c-rough-notes__head {
	display: flex; align-items: center; justify-content: space-between;
	padding: 8px 10px 8px 14px;
	border-bottom: 1px solid var(--border-subtle);
}
html[data-theme="dark"] .c-rough-notes__head { border-bottom-color: #d0d0d5; }
.c-rough-notes__label {
	font-size: 0.72rem; font-weight: 600; text-transform: uppercase;
	letter-spacing: 0.06em; color: #6B6B70;
}
.c-rough-notes__textarea {
	display: block; width: 100%; box-sizing: border-box;
	min-height: 104px; padding: 12px 14px;
	border: 0; outline: none; resize: vertical;
	font-family: inherit; font-size: 0.9rem; line-height: 1.5;
	color: #000; background: #fff;
}
.c-rough-notes__textarea::placeholder { color: #9A9AA0; }
/* The textarea sits flush inside a bordered card; the browser default focus
   ring / box-shadow breaks that seam. Kill any focus highlight (shared with
   written-recall, which reuses this component). */
.c-rough-notes__textarea:focus { outline: none; box-shadow: none; border-color: transparent; }
.c-rough-notes__preview { border-top: 1px solid var(--border-subtle); }
.c-rough-notes__preview-label {
	font-size: 0.65rem; font-weight: 600; text-transform: uppercase;
	letter-spacing: 0.06em; color: #6B6B70; padding: 8px 14px 2px;
}
.c-rough-notes__preview-body {
	font-family: var(--font-serif); font-size: 0.88rem; line-height: 1.6;
	color: #000; padding: 0 14px 10px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   ANSWER INPUT  (written-recall — the primary typed-answer surface)
   ───────────────────────────────────────────────────────────────────────────
   The core new surface of the written-recall session: a "YOUR ANSWER" label, a
   textarea, a char count, a live $…$ KaTeX preview, a Submit button and a key
   hint. It is an EDITABLE surface, not rendered note content — so (the
   .c-rough-notes rule, NOT the white-paper exception) it stays a WHITE card with
   dark text in BOTH themes, with only a subtle themed border. Distinct from
   .c-rough-notes: this is the primary working surface and carries submit + hint,
   not a scratch pad. The $…$ preview is wired at build time; the mockup shows the
   markup + a sample rendered preview.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-answer-input {
	width: 100%; box-sizing: border-box;
	background: #fff; border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg); box-shadow: var(--shadow-card);
	padding: 18px 20px;
}
html[data-theme="dark"] .c-answer-input { background: #fff; border-color: #3A3A3C; box-shadow: none; }
.c-answer-input__label {
	font-size: 9.5px; font-weight: 700; text-transform: uppercase;
	letter-spacing: 0.08em; color: #6B6B70; margin-bottom: 10px;
}
.c-answer-input__textarea {
	display: block; width: 100%; box-sizing: border-box;
	min-height: 168px; padding: 12px 14px;
	border: 1.5px solid #D6DEEC; border-radius: var(--radius-md);
	outline: none; resize: vertical;
	font-family: inherit; font-size: 0.95rem; line-height: 1.65;
	color: #000; background: #fff;
	transition: border-color var(--motion-fast), box-shadow var(--motion-fast);
}
.c-answer-input__textarea::placeholder { color: #9A9AA0; }
.c-answer-input__textarea:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(0,71,171,0.10); }
.c-answer-input__count { text-align: right; font-size: 0.72rem; color: #9A9AA0; margin-top: 6px; }
.c-answer-input__preview { border-top: 1px solid #E2E5EC; margin-top: 10px; padding-top: 10px; }
.c-answer-input__preview-label {
	font-size: 0.65rem; font-weight: 600; text-transform: uppercase;
	letter-spacing: 0.06em; color: #6B6B70; margin-bottom: 4px;
}
.c-answer-input__preview-body { font-family: var(--font-serif); font-size: 0.92rem; line-height: 1.6; color: #000; }
.c-answer-input__submit {
	display: block; width: 100%; margin-top: 12px;
	padding: 12px; border: none; border-radius: var(--radius-md);
	background: var(--primary); color: #fff;
	font-family: inherit; font-size: 0.95rem; font-weight: 600; cursor: pointer;
	transition: background var(--motion-fast);
}
.c-answer-input__submit:hover { background: #0055d4; }
.c-answer-input__submit:disabled { opacity: 0.4; cursor: default; }
.c-answer-input__hint { text-align: center; font-size: 0.68rem; color: #9A9AA0; margin-top: 8px; }

/* ═══════════════════════════════════════════════════════════════════════════
   RESULT BANNER  (written-recall — the correct / partial / wrong score banner)
   ───────────────────────────────────────────────────────────────────────────
   The full-width score banner at the top of the AI-graded result. NB: named
   `-banner`, NOT `-chip` — `.c-result-chip` already exists as the small inline
   summary/history pill (see the .c-sum-* family below); reusing that name made the
   pill's `radius-pill` + tiny padding override this. Pastel semantic surface (same
   palette as .c-rating); colours read on either theme, so no dark override.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-result-banner {
	display: flex; align-items: center; gap: 14px;
	border-radius: var(--radius-lg);   /* same radius as the other session cards */
	padding: 17px 18px;                /* extra top/bottom breathing room around the text */
}
.c-result-banner__symbol { font-size: 1.4rem; line-height: 1; flex-shrink: 0; }
.c-result-banner__labels { display: flex; flex-direction: column; }
.c-result-banner__type { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; }
.c-result-banner__word { font-size: 1.05rem; font-weight: 700; }
.c-result-banner--correct { background: #DCFCE7; border: 1.5px solid #86EFAC; }
.c-result-banner--partial { background: #FEF9C3; border: 1.5px solid #FDE047; }
.c-result-banner--wrong   { background: #FEE2E2; border: 1.5px solid #FECACA; }
.c-result-banner--correct .c-result-banner__symbol,
.c-result-banner--correct .c-result-banner__type,
.c-result-banner--correct .c-result-banner__word { color: #166534; }
.c-result-banner--partial .c-result-banner__symbol,
.c-result-banner--partial .c-result-banner__type,
.c-result-banner--partial .c-result-banner__word { color: #854D0E; }
.c-result-banner--wrong .c-result-banner__symbol,
.c-result-banner--wrong .c-result-banner__type,
.c-result-banner--wrong .c-result-banner__word { color: #B91C1C; }

/* ═══════════════════════════════════════════════════════════════════════════
   COLLAPSE CARD  (written-recall — collapsible YOUR ANSWER / AI FEEDBACK)
   ───────────────────────────────────────────────────────────────────────────
   An OUTPUT surface (your submitted answer / the AI's prose) → WHITE with dark
   text in BOTH themes, same rule as .c-answer-input. Header toggles .is-open
   (chevron rotates, divider appears). Build-time wires the collapse.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-collapse-card {
	width: 100%; box-sizing: border-box;
	background: #fff; border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg); box-shadow: var(--shadow-card); overflow: hidden;
}
html[data-theme="dark"] .c-collapse-card { background: #fff; border-color: #3A3A3C; box-shadow: none; }
.c-collapse-card__head {
	display: flex; align-items: center; justify-content: space-between;
	padding: 11px 16px; cursor: pointer; user-select: none;
	border-bottom: 1px solid transparent;
}
.c-collapse-card__head.is-open { border-bottom-color: #E2E5EC; }
.c-collapse-card__title { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #6B6B70; }
.c-collapse-card__chevron { font-size: 0.7rem; color: #9A9AA0; transition: transform var(--motion-chevron); }
.c-collapse-card__head.is-open .c-collapse-card__chevron { transform: rotate(180deg); }
.c-collapse-card__body { padding: 12px 16px; font-family: var(--font-serif); font-size: 0.9rem; line-height: 1.65; color: #000; }

/* ═══════════════════════════════════════════════════════════════════════════
   MARK SCHEME  (written-recall — the model mark points with hit / miss marks)
   ───────────────────────────────────────────────────────────────────────────
   The point bodies are RENDERED NOTE CONTENT (serif + KaTeX) → the card stays
   WHITE paper in BOTH themes (light-in-dark rule). Each point is hit (green),
   miss (red), or neutral (grey — used in the no-AI self-mark path, where hit/miss
   isn't known). Tinted header is chrome-on-white, fixed for both themes.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-mark-scheme {
	width: 100%; box-sizing: border-box;
	background: #fff; border: 1px solid var(--border-subtle);
	border-radius: var(--radius-lg); box-shadow: var(--shadow-card); overflow: hidden;
}
html[data-theme="dark"] .c-mark-scheme { background: #fff; border-color: #3A3A3C; box-shadow: none; }
.c-mark-scheme__head {
	display: flex; align-items: center; justify-content: space-between;
	padding: 10px 16px; background: #F3F6FC; border-bottom: 1px solid #E2E5EC;
}
.c-mark-scheme__title { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--primary); }
.c-mark-scheme__count { font-size: 0.72rem; color: #6B6B70; }
.c-mark-scheme__body { padding: 12px 16px; display: flex; flex-direction: column; gap: 8px; }
.c-mark-scheme__point {
	display: flex; align-items: flex-start; gap: 10px;
	font-family: var(--font-serif); font-size: 0.9rem; line-height: 1.5; color: #000;
}
.c-mark-scheme__point--hit  { color: #166534; }
.c-mark-scheme__point--miss { color: #B91C1C; }
.c-mark-scheme__icon {
	flex-shrink: 0; width: 20px; height: 20px; border-radius: 50%;
	display: flex; align-items: center; justify-content: center;
	font-size: 0.7rem; font-weight: 700; margin-top: 1px;
}
.c-mark-scheme__point--hit  .c-mark-scheme__icon { background: #DCFCE7; color: #166534; }
.c-mark-scheme__point--miss .c-mark-scheme__icon { background: #FEE2E2; color: #B91C1C; }
.c-mark-scheme__point--neutral .c-mark-scheme__icon { background: #EFEFEF; color: #8E8E93; }

/* ═══════════════════════════════════════════════════════════════════════════
   SKELETON LOADERS
   ═══════════════════════════════════════════════════════════════════════════ */
@keyframes c-shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
.c-skeleton {
	background: linear-gradient(90deg, #ebebeb 25%, #d8d8d8 37%, #ebebeb 63%);
	background-size: 400% 100%;
	animation: c-shimmer 1.6s ease-in-out infinite;
	border-radius: 4px; height: 12px;
}
.c-skeleton--card { height: 80px; border-radius: var(--radius-md); }
html[data-theme="dark"] .c-skeleton { background: linear-gradient(90deg, #3a3a3c 25%, #48484a 37%, #3a3a3c 63%); background-size: 400% 100%; }

/* ═══════════════════════════════════════════════════════════════════════════
   SIDEBAR + NAV  (248px app shell)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-sidebar {
	width: 248px; background: var(--surface-nav);
	border-right: 1px solid #EBEBEB;
	display: flex; flex-direction: column;
	height: 100%; overflow: hidden;
}
.c-sidebar__brand { display: flex; align-items: center; justify-content: space-between; padding: 18px 16px 10px; }
.c-sidebar__brand-name { font-size: 15px; font-weight: 700; color: var(--primary); letter-spacing: -0.02em; }
.c-sidebar__iconbtn { width: 26px; height: 26px; border: 0; background: transparent; color: var(--text-muted); cursor: pointer; border-radius: 6px; }
.c-sidebar__iconbtn:hover { background: var(--surface-hover); }
.c-sidebar__search { padding: 0 12px 12px; }
.c-sidebar__section { padding: 2px 0; overflow-y: auto; flex: 1; }
.c-sidebar__subject { display: flex; align-items: center; gap: 8px; padding: 5px 10px 5px 14px; font-size: 13px; font-weight: 500; color: var(--text-body); cursor: pointer; }
.c-sidebar__subject:hover { background: var(--surface-hover); }
.c-sidebar__note { padding: 4px 10px 4px 38px; font-size: 12.5px; color: #555; cursor: pointer; }
.c-sidebar__note:hover { background: var(--surface-hover); }
.c-sidebar__note.is-active { color: var(--primary); font-weight: 500; background: var(--surface-active); border-left: 3px solid var(--primary); padding-left: 35px; }
.c-nav-link { display: flex; align-items: center; gap: 10px; padding: 5px 14px; font-size: 13px; font-weight: 500; color: var(--text-body); cursor: pointer; }
.c-nav-link:hover { background: var(--surface-hover); }
.c-nav-link.is-active { color: var(--primary); font-weight: 600; background: var(--surface-active); border-left: 3px solid var(--primary); padding-left: 11px; }
.c-sidebar__footer { display: flex; align-items: center; gap: 8px; padding: 10px 12px 14px; border-top: 1px solid #EBEBEB; }
.c-avatar { width: 28px; height: 28px; border-radius: 50%; background: var(--primary); color: #fff; font-size: 11px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
.c-sidebar__user-name { font-size: 12.5px; font-weight: 500; color: var(--text-body); }
.c-sidebar__user-email { font-size: 11px; color: #8E8E93; }

html[data-theme="dark"] .c-sidebar { background: #252525; border-right-color: #3A3A3C; }
html[data-theme="dark"] .c-sidebar__note { color: #8E8E93; }
html[data-theme="dark"] .c-sidebar__note.is-active { color: var(--secondary); background: var(--surface-active); border-left-color: var(--primary); }
html[data-theme="dark"] .c-nav-link { color: #D1D1D6; }
html[data-theme="dark"] .c-nav-link.is-active { color: var(--secondary); background: var(--surface-active); border-left-color: var(--primary); }
html[data-theme="dark"] .c-sidebar__footer { border-top-color: #3A3A3C; }
html[data-theme="dark"] .c-sidebar__user-email { color: #636366; }

/* ── App top-bar (narrow layouts) ──────────────────────────────────────────
   Compact 52px top bar shown below the mobile breakpoint, where the 248px
   .c-sidebar is hidden and replaced by a hamburger that slides it in as a
   drawer. Promoted from design/mockups/shell.css; shared shell chrome →
   follows the theme via tokens. The page shell (base.html) owns the @media
   rule that toggles its display + turns .c-sidebar into the drawer. */
.app-topbar {
	flex: 0 0 52px;
	display: flex; align-items: center; gap: var(--space-md);
	height: 52px; padding: 0 var(--space-lg);
	background: var(--surface-nav);
	border-bottom: 1px solid var(--border-subtle);
}
.app-topbar__menu {
	width: 30px; height: 30px; flex: 0 0 30px;
	display: flex; align-items: center; justify-content: center;
	border: 0; background: transparent; border-radius: 6px;
	color: var(--text-muted); cursor: pointer;
}
.app-topbar__menu:hover { background: var(--surface-hover); }
.app-topbar__menu svg { width: 18px; height: 18px; fill: currentColor; }
.app-topbar__brand { font-size: 15px; font-weight: 700; color: var(--primary); letter-spacing: -0.02em; }
.app-topbar__spacer { flex: 1; }

/* ═══════════════════════════════════════════════════════════════════════════
   EDITOR CHROME — toolbar, pills/chips, autosave, creation banner
   ═══════════════════════════════════════════════════════════════════════════ */
.c-toolbar { display: flex; align-items: center; gap: 4px; height: 40px; padding: 0 10px; background: #FAFAFA; border-bottom: 1px solid #EBEBEB; }
html[data-theme="dark"] .c-toolbar { background: #1F1F1F; border-bottom-color: #3A3A3C; }
.c-tb-btn { display: inline-flex; align-items: center; flex: 0 0 auto; white-space: nowrap; height: var(--ctl-h-sm); font-size: 12.5px; font-weight: 500; color: var(--text-muted); padding: 0 8px; border: 0; background: transparent; border-radius: 5px; cursor: pointer; }
.c-tb-btn:hover { background: var(--ice); color: var(--primary); }
.c-tb-btn:disabled { opacity: 0.3; }
/* Toggle / pressed state — for toolbar buttons that turn something on (e.g. the
   read page's CONTENTS toggle, editor character styles). */
.c-tb-btn.is-active { background: var(--ice); color: var(--primary); }
html[data-theme="dark"] .c-tb-btn.is-active { background: var(--surface-active); color: var(--secondary); }
/* Active state also gets a hover affordance (a theme-aware deepen) — matches the
   native CTbBtn; the inactive :hover above already has one. */
.c-tb-btn.is-active:hover { filter: brightness(0.97); }
html[data-theme="dark"] .c-tb-btn.is-active:hover { filter: brightness(1.12); }
.c-tb-divider { width: 1px; height: 18px; background: var(--pale); margin: 0 4px; }
/* --pale is a fixed light blue in both themes, so the divider needs a dark override
   to recede into the dark toolbar (matches the .c-toolbar dark border colour). */
html[data-theme="dark"] .c-tb-divider { background: #3A3A3C; }

.c-chip { display: inline-flex; align-items: center; height: var(--ctl-h-sm); font-size: 12px; font-weight: 500; color: #555; background: var(--fill-input); border: 1px solid #DDDDE3; border-radius: 20px; padding: 0 12px; cursor: pointer; }
.c-chip:hover { background: var(--ice); border-color: var(--pale); color: var(--primary); }

.c-pill { display: inline-flex; align-items: center; flex: 0 0 auto; white-space: nowrap; height: var(--ctl-h-sm); font-size: 12.5px; font-weight: 600; color: var(--primary); background: transparent; border: 1.5px solid var(--primary); border-radius: 20px; padding: 0 14px; cursor: pointer; }
.c-pill:hover { background: var(--primary); color: #fff; }
html[data-theme="dark"] .c-pill { color: var(--secondary); border-color: var(--secondary); }
html[data-theme="dark"] .c-pill:hover { background: var(--secondary); color: var(--text-body); }

/* Subject chip: a small subject-coloured pill. Two uses — the /todos subject
   FILTER row (with a colour dot; active = solid subject fill, white text) and
   the Add-task modal subject PICKER (no dot; selected = light subject fill).
   The FILL colour is the subject's own hue → set inline (data, not chrome);
   the component supplies the outline default + the .is-active solid treatment. */
.c-subject-chip {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	font-family: inherit;
	font-size: 11px;
	font-weight: 600;
	padding: 3px 10px;
	border-radius: var(--radius-pill);
	border: 1.5px solid var(--border-subtle);
	background: transparent;
	color: var(--text-muted);
	cursor: pointer;
	transition: border-color 0.1s, background 0.1s, color 0.1s;
}
.c-subject-chip:hover { border-color: var(--border-normal); color: var(--text-body); }
.c-subject-chip__dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
/* Filter active: solid subject fill (set inline) + white text. */
.c-subject-chip.is-active { color: #fff; border-color: transparent; }

.c-autosave { font-size: 11.5px; font-weight: 500; transition: opacity 0.4s; }
.c-autosave--saving { color: var(--text-muted); }
.c-autosave--saved  { color: #2a9d5c; }
.c-autosave--error  { color: #c0392b; }

.c-creation-banner { display: inline-flex; align-items: center; flex: 0 0 auto; white-space: nowrap; gap: 8px; height: var(--ctl-h-sm); font-size: 12px; font-weight: 500; color: #9A3412; background: #FFF7ED; border: 1px solid #FDBA74; border-radius: 20px; padding: 0 12px; }
.c-creation-banner__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--orange); animation: c-pulse 1.5s ease-in-out infinite; }
@keyframes c-pulse { 50% { opacity: 0.5; } }

/* Dark-mode coverage for chrome that was light-only (would render light-on-dark). */
html[data-theme="dark"] .c-chip { background: var(--surface-page); border-color: var(--border-subtle); color: var(--text-muted); }
html[data-theme="dark"] .c-chip:hover { background: rgba(255,255,255,0.08); border-color: var(--border-normal); color: var(--secondary); }
html[data-theme="dark"] .c-creation-banner { background: rgba(232,110,30,0.16); border-color: rgba(232,110,30,0.45); color: #F0A868; }
html[data-theme="dark"] .c-bulk__btn--danger:hover { background: rgba(148,40,90,0.18); }

/* Bulk action toolbar */
.c-bulk { display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: var(--surface-editor-left); border-bottom: 1px solid var(--border-subtle); font-size: 0.78rem; }
.c-bulk__count { font-size: 0.8rem; font-weight: 600; color: var(--primary); }
.c-bulk__btn { padding: 3px 9px; border-radius: 5px; background: var(--surface-card); border: 1px solid var(--border-normal); font-size: 0.78rem; cursor: pointer; }
.c-bulk__btn--danger { color: var(--plum); border-color: transparent; }
.c-bulk__btn--danger:hover { background: #fff0f4; }

/* Inline insert (+) button */
.c-insert { width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--pale); background: var(--surface-nav); color: var(--text-muted); font-size: 12px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.c-insert:hover { background: var(--primary); border-color: var(--primary); color: #fff; }

/* ═══════════════════════════════════════════════════════════════════════════
   CHARACTER-STYLE TOOLBAR (floating, above a text selection)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-chartoolbar { position: relative; display: inline-flex; align-items: center; gap: 2px; height: 36px; padding: 4px; background: var(--surface-card); border: 1px solid rgba(0,71,171,0.12); border-radius: var(--radius-md); box-shadow: var(--shadow-elevated); }
/* Downward pointer tucked under the bottom edge, aimed at the selection. Card-coloured
   fill (no border, matching the native DownArrow). 12px wide × 7px tall, centred. */
.c-chartoolbar::after { content: ""; position: absolute; bottom: -6px; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 7px solid var(--surface-card); }
.c-chartoolbar__btn { width: 28px; height: 28px; border: 0; background: transparent; border-radius: 7px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; color: var(--text-body); transition: background 0.08s; }
.c-chartoolbar__btn:hover { background: #F0F4FF; }
.c-chartoolbar__btn.is-active { background: var(--primary); color: #fff; }
.c-chartoolbar__divider { width: 1px; height: 20px; background: var(--border-subtle); margin: 0 4px; }
.c-swatch { width: 14px; height: 14px; border-radius: 3px; }
html[data-theme="dark"] .c-chartoolbar { background: #2C2C2E; border-color: #3A3A3C; }
html[data-theme="dark"] .c-chartoolbar::after { border-top-color: #2C2C2E; }
html[data-theme="dark"] .c-chartoolbar__btn { color: #E5E5EA; }
html[data-theme="dark"] .c-chartoolbar__btn:hover { background: rgba(255,255,255,0.08); }

/* ═══════════════════════════════════════════════════════════════════════════
   SLASH PICKER / STYLE DROPDOWN
   ═══════════════════════════════════════════════════════════════════════════ */
.c-slash { width: 260px; background: var(--surface-card); border: 1px solid var(--pale); border-radius: 5px; box-shadow: 0 4px 12px rgba(0,0,0,0.12); padding: 0.4rem; }
.c-slash__search { width: 100%; border: 1px solid var(--border-normal); border-radius: 3px; padding: 4px 6px; font-size: 0.82rem; }
.c-slash__list { max-height: 200px; overflow-y: auto; margin-top: 0.3rem; }
.c-slash__item { font-size: 0.82rem; padding: 5px 8px; border-radius: 3px; cursor: pointer; color: var(--text-body); }
.c-slash__item.is-active { background: var(--ice); color: var(--primary); }
.c-slash__group { font-size: 0.7rem; font-weight: 700; color: var(--primary); text-transform: uppercase; padding: 6px 8px 2px; }
html[data-theme="dark"] .c-slash { border-color: var(--border-subtle); }
html[data-theme="dark"] .c-slash__item.is-active { background: var(--surface-active); color: var(--secondary); }

/* ═══════════════════════════════════════════════════════════════════════════
   TABLE BLOCK — compact summary  +  table-editor modal chrome
   ═══════════════════════════════════════════════════════════════════════════ */
.c-table-summary { display: flex; align-items: center; gap: 10px; font-family: var(--font-mono); font-size: 0.78rem; color: var(--text-muted); }
.c-table-summary__edit { font-size: 0.72rem; padding: 2px 8px; border: 1px solid var(--secondary); color: var(--secondary); background: transparent; border-radius: 3px; cursor: pointer; }

.c-te-modal { width: 980px; max-width: 96vw; max-height: 92vh; background: var(--surface-card); border-radius: 14px; box-shadow: 0 20px 60px rgba(0,0,0,0.16), 0 4px 16px rgba(0,0,0,0.08); overflow: hidden; display: flex; flex-direction: column; }
.c-te-modal__header { display: flex; align-items: center; justify-content: space-between; padding: 14px 20px; }
.c-te-modal__title { font-size: 15px; font-weight: 700; color: var(--text-body); }
.c-te-modal__toolbar { display: flex; gap: 8px; padding: 8px 16px; background: #FAFAFA; }
.c-te-tbtn { background: var(--surface-card); border: 1px solid #E0E0E0; border-radius: 8px; font-size: 12px; font-weight: 500; padding: 5px 10px; cursor: pointer; }
.c-te-tbtn--add { color: var(--primary); background: var(--surface-active); border-color: #B3CAEF; }
.c-te-tbtn--del { color: #B91C1C; background: #FFF5F5; border-color: #FECACA; }
html[data-theme="dark"] .c-te-modal__toolbar { background: #1F1F1F; }
html[data-theme="dark"] .c-te-tbtn { background: var(--surface-card); border-color: var(--border-normal); color: var(--text-body); }
html[data-theme="dark"] .c-te-tbtn--add { color: var(--secondary); background: var(--surface-active); border-color: #2F4A78; }
html[data-theme="dark"] .c-te-tbtn--del { color: #F87171; background: rgba(185,28,28,0.18); border-color: rgba(185,28,28,0.4); }

/* Resizable grid: column-header row (with col-resize handles) + row headers
   (with row-resize handles) + dashed add-column button. */
.c-te-colhead-row { display: flex; margin-left: 34px; }
.c-te-colhead {
	position: relative; height: 26px; flex: 1;
	background: var(--fill-input); border: 1px solid #D8D8D8; border-left: none;
	display: flex; align-items: center; justify-content: center;
	font-size: 10px; font-weight: 700; color: #666; letter-spacing: 0.06em; text-transform: uppercase;
	cursor: pointer; user-select: none;
}
.c-te-colhead:first-child { border-left: 1px solid #D8D8D8; }
.c-te-colhead:hover { background: #E4EDFF; }
.c-te-colhead.is-selected { background: #BBD2F5; color: var(--primary); border-color: #7FA8DC; }
.c-te-colrh { position: absolute; right: -4px; top: 0; bottom: 0; width: 8px; cursor: col-resize; z-index: 20; display: flex; align-items: center; justify-content: center; }
.c-te-colrh-bar { width: 2px; height: 100%; background: #C8C8C8; border-radius: 1px; }
.c-te-colrh:hover .c-te-colrh-bar { background: var(--primary); width: 3px; }
.c-te-row { display: flex; }
.c-te-rowhead {
	position: relative; width: 34px; flex: 0 0 34px;
	background: var(--fill-input); border: 1px solid #D8D8D8; border-top: none;
	display: flex; align-items: center; justify-content: center;
	font-size: 10px; font-weight: 700; color: #666; cursor: pointer; user-select: none;
}
.c-te-rowhead:hover { background: #E4EDFF; }
.c-te-rowhead.is-selected { background: #BBD2F5; color: var(--primary); border-color: #7FA8DC; }
.c-te-rowrh { position: absolute; bottom: -4px; left: 0; right: 0; height: 8px; cursor: row-resize; z-index: 20; display: flex; align-items: center; justify-content: center; }
.c-te-rowrh-bar { height: 2px; width: 100%; background: #C8C8C8; border-radius: 1px; }
.c-te-rowrh:hover .c-te-rowrh-bar { background: var(--primary); height: 3px; }
.c-te-cell { flex: 1; border: 1px solid #D8D8D8; border-left: none; border-top: none; font-family: var(--font-serif); font-size: 13px; min-height: 36px; padding: 6px 9px; color: #000; background: var(--surface-card); }
.c-te-cell--head { background: #F0F4FF; font-weight: 700; font-family: var(--font-ui); font-size: 11.5px; color: #333; }
html[data-theme="dark"] .c-te-colhead, html[data-theme="dark"] .c-te-rowhead { background: #2C2C2E; color: #B0B0B5; border-color: #3A3A3C; }
html[data-theme="dark"] .c-te-cell { background: #2C2C2E; color: var(--text-body); border-color: #3A3A3C; }
html[data-theme="dark"] .c-te-cell--head { background: var(--surface-active); color: #D1D1D6; }
/* Dark selected-header state — needs the data-theme prefix to out-specify the dark
   base rule above (which would otherwise clobber the light .is-selected). */
html[data-theme="dark"] .c-te-colhead.is-selected,
html[data-theme="dark"] .c-te-rowhead.is-selected { background: rgba(0,71,171,0.55); color: var(--secondary); border-color: var(--secondary); }

/* Modal chrome the full editor needs beyond the gallery stub: header subtitle,
   toolbar separator/hint, body, dashed add-row/add-col, footer. */
.c-te-modal__subtitle { font-size: 12px; font-weight: 400; color: var(--text-muted); }
.c-te-tbtn:disabled { opacity: 0.32; cursor: default; pointer-events: none; }
.c-te-tbtn-sep { width: 1px; height: 20px; background: var(--border-subtle); margin: 0 4px; flex-shrink: 0; }
.c-te-toolbar-spacer { flex: 1; }
.c-te-hint { font-size: 11px; font-style: italic; color: var(--text-muted); }
.c-te-modal__body { flex: 1; overflow: auto; padding: 20px 24px 16px; }
.c-te-table-outer { display: flex; align-items: stretch; gap: 6px; }
.c-te-table-main { display: flex; flex-direction: column; position: relative; }
/* (rows/columns are added/removed from the modal toolbar — no in-grid + buttons) */

/* Selected cell (being edited) — blue ring, mirrors the live :focus state */
.c-te-cell--editing { border-color: var(--primary) !important; background: #FAFCFF; box-shadow: inset 0 0 0 1px var(--secondary); position: relative; z-index: 5; }
html[data-theme="dark"] .c-te-cell--editing { background: var(--surface-active); }

/* Cell-style bar — appears under the grid when a cell is selected. The dropdown
   opens the same slash/style picker (.c-slash) used in the main editor. */
.c-te-csb { display: flex; align-items: center; gap: 8px; margin-top: 12px; padding: 7px 12px; background: #F8F9FF; border: 1px solid #DDE8FF; border-radius: 8px; }
.c-te-csb__label { font-size: 11.5px; font-weight: 500; color: var(--text-muted); white-space: nowrap; }
.c-te-csb__btn { min-width: 150px; text-align: left; border: 1px solid #C8D4EE; border-radius: 6px; padding: 4px 28px 4px 9px; font-size: 12px; color: var(--text-body); background: var(--surface-card) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23888'/%3E%3C/svg%3E") no-repeat right 8px center; cursor: pointer; }
.c-te-csb__btn:hover { border-color: var(--primary); }
html[data-theme="dark"] .c-te-csb { background: var(--surface-active); border-color: var(--border-normal); }
html[data-theme="dark"] .c-te-csb__btn { background-color: var(--surface-card); border-color: var(--border-normal); }

.c-te-modal__footer { display: flex; align-items: center; justify-content: space-between; padding: 12px 20px; border-top: 1px solid var(--border-subtle); flex-shrink: 0; }
.c-te-footer-meta { font-size: 11.5px; color: var(--text-muted); }
.c-te-footer-actions { display: flex; gap: 8px; }

/* ═══════════════════════════════════════════════════════════════════════════
   CREATION MODE — right-pane manage/reorder list
   In creation mode the right pane swaps the A4 preview for a management list:
   a Flashcards|Written Recall tab toggle (.c-tabs) over rows keyed by HEADING.
   Each row is draggable to reorder; clicking opens the Create & Manage modal.
   Rows show only the heading + a snippet of the selected blocks (truncated).
   ═══════════════════════════════════════════════════════════════════════════ */
.c-cm-manage { flex: 1; min-width: 0; overflow: auto; background: var(--surface-editor-left); padding: 0 16px 16px; display: flex; flex-direction: column; }
html[data-theme="dark"] .c-cm-manage { background: #1F1F1F; }
.c-cm-manage__tabs { position: sticky; top: 0; background: inherit; padding-top: 12px; }
.c-cm-manage__head { display: flex; align-items: center; justify-content: space-between; margin: 12px 2px 8px; }
.c-cm-manage__count { font-size: 0.72rem; font-weight: 600; color: var(--text-muted); }
.c-cm-manage__hint { font-size: 0.7rem; color: var(--text-muted); font-style: italic; }
.c-cm-entry { display: flex; align-items: center; gap: 10px; padding: 9px 11px; margin-bottom: 6px; background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: 9px; cursor: pointer; transition: border-color var(--motion-fast), box-shadow var(--motion-fast); }
.c-cm-entry:hover { border-color: var(--dusty); box-shadow: var(--shadow-card); }
.c-cm-entry__drag { flex: 0 0 auto; color: var(--text-muted); cursor: grab; display: inline-flex; }
.c-cm-entry__drag:active { cursor: grabbing; }
.c-cm-entry__drag svg { width: 13px; height: 13px; fill: currentColor; }
.c-cm-entry__num { flex: 0 0 auto; width: 20px; height: 20px; border-radius: 6px; background: var(--ice); color: var(--primary); font-size: 0.66rem; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
html[data-theme="dark"] .c-cm-entry__num { background: var(--surface-active); color: var(--secondary); }
.c-cm-entry__main { flex: 1; min-width: 0; }
.c-cm-entry__heading { font-size: 0.83rem; font-weight: 600; color: var(--text-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.c-cm-entry__snippet { font-size: 0.72rem; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; }
.c-cm-entry__chev { flex: 0 0 auto; color: var(--text-muted); }
.c-cm-entry__chev svg { width: 14px; height: 14px; fill: currentColor; transform: rotate(-90deg); }
.c-cm-manage__empty { border: 1.5px dashed var(--pale); border-radius: 8px; padding: 18px; font-size: 12px; color: var(--text-muted); text-align: center; }
html[data-theme="dark"] .c-cm-manage__empty { border-color: var(--border-normal); }

/* ═══════════════════════════════════════════════════════════════════════════
   CREATE & MANAGE MODAL  (opened from a heading's +/counter pills)
   Uses .c-modal (medium) + .c-tabs. Body parts below. The FRONT preview box
   stays light in both themes (it shows serif/black rendered note content).
   ═══════════════════════════════════════════════════════════════════════════ */
.c-tabs { display: flex; border-bottom: 1px solid var(--border-subtle); }
/* Works as either a <div> or a <button> — the reset (appearance/background/
   border/font) keeps a native <button> from drawing its default chrome, so the
   only border that shows is the 2px underline. */
.c-tab {
	appearance: none; -webkit-appearance: none;
	background: transparent; border: 0; border-bottom: 2px solid transparent;
	font-family: inherit;
	padding: 0.6rem 1rem; font-size: 0.82rem; font-weight: 500;
	color: var(--text-muted); cursor: pointer; margin-bottom: -1px;
}
.c-tab:hover { color: var(--secondary); }
.c-tab.is-active { color: var(--primary); font-weight: 600; border-bottom-color: var(--primary); }
.c-cm-seclabel { font-size: 0.66rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-muted); margin: 14px 0 6px; }
.c-cm-seclabel:first-child { margin-top: 0; }
.c-cm-front { background: #EEF4FF; border: 1px solid #DCE6F5; border-radius: 8px; padding: 9px 13px; color: #000; }
.c-cm-front .block-preview { margin: 0 !important; }
.c-cm-block { display: flex; align-items: flex-start; gap: 10px; padding: 7px 8px; border-radius: 6px; cursor: pointer; font-size: 0.84rem; }
.c-cm-block:hover { background: var(--surface-hover); }
.c-cm-block.is-checked { background: var(--surface-active); }
.c-cm-block input { margin-top: 2px; accent-color: var(--primary); flex: 0 0 auto; }
/* Fixed-width gutter (right-aligned, abbreviated style names) so every block's
   content starts at the same x — mirrors the editor's .c-block-row__label. */
.c-cm-block__chip { flex: 0 0 76px; width: 76px; text-align: right; font-size: 0.64rem; font-weight: 600; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-top: 1px; }
.c-cm-block__text { flex: 1; min-width: 0; color: var(--text-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Additional-headings selector — the front can span several headings (for a
   process with subheadings). Checkbox + the heading text in the serif note font. */
.c-cm-headrow { display: flex; align-items: center; gap: 10px; padding: 5px 8px; border-radius: 6px; cursor: pointer; font-family: var(--font-serif); font-size: 0.9rem; color: var(--text-body); }
.c-cm-headrow:hover { background: var(--surface-hover); }
.c-cm-headrow input { accent-color: var(--primary); flex: 0 0 auto; }

/* ── Written Recall tab ────────────────────────────────────────────────────────
   Read-only reference of the content under the heading (+ any selected extra
   headings) to write mark points against, an ordered-process toggle, and the
   mark-scheme point inputs. */
.c-cm-ref { background: var(--surface-page); border: 1px solid var(--border-subtle); border-radius: 8px; padding: 4px 6px; max-height: 168px; overflow: auto; }
.c-cm-ref__row { display: flex; gap: 10px; padding: 5px 4px; font-size: 0.8rem; border-bottom: 1px solid var(--border-subtle); }
.c-cm-ref__row:last-child { border-bottom: 0; }
.c-cm-ref__chip { flex: 0 0 76px; width: 76px; text-align: right; font-size: 0.62rem; font-weight: 600; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-top: 2px; }
.c-cm-ref__text { flex: 1; min-width: 0; color: var(--text-body); }
.c-cm-ordered { display: flex; align-items: center; gap: 8px; font-size: 0.84rem; color: var(--text-body); cursor: pointer; }
.c-cm-ordered input { accent-color: var(--primary); }
.c-mp-row { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.c-mp-row__num { flex: 0 0 18px; width: 18px; height: 18px; border-radius: 50%; background: var(--ice); color: var(--primary); font-size: 0.66rem; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
html[data-theme="dark"] .c-mp-row__num { background: var(--surface-active); color: var(--secondary); }
.c-mp-row__rm { flex: 0 0 auto; width: 26px; height: 26px; border: 0; background: transparent; color: var(--text-muted); cursor: pointer; border-radius: 6px; font-size: 14px; }
.c-mp-row__rm:hover { background: var(--surface-hover); color: var(--plum); }
.c-cm-addpoint { align-self: flex-start; font-size: 0.78rem; font-weight: 600; color: var(--primary); background: transparent; border: 1px solid var(--border-normal); border-radius: 6px; padding: 5px 11px; cursor: pointer; }
.c-cm-addpoint:hover { border-color: var(--secondary); background: var(--surface-active); }

/* ═══════════════════════════════════════════════════════════════════════════
   SESSION SUMMARY  (multi-card: header · score · history)
   Mirrors the shared sum- component. Count-number colours match the donut/bar
   (correct #22C55E / partial #EAB308 / wrong #EF4444) so the whole card is one
   colour language.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-sum-wrap { display: flex; flex-direction: column; gap: var(--space-md); }
.c-sum-card { background: var(--surface-card); border-radius: 18px; box-shadow: var(--shadow-card); padding: 22px 26px; }
.c-sum-card__label { font-size: 10px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-muted); }

/* Header card */
.c-sum-header-inner { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.c-sum-badge { display: inline-flex; align-items: center; font-size: 10px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; background: var(--primary); color: #fff; border-radius: var(--radius-pill); padding: 4px 11px; margin-bottom: 9px; }
.c-sum-badge--fc { background: var(--primary); }   /* Flashcards badge = same dark primary as Written Recall */
.c-sum-note-name { font-size: 1.1rem; font-weight: 700; color: var(--text-body); letter-spacing: -0.02em; line-height: 1.3; }
.c-sum-meta { display: flex; align-items: center; gap: 6px; font-size: 0.78rem; color: var(--text-muted); margin-top: 5px; }
.c-sum-duration { flex-shrink: 0; background: var(--ice); color: var(--secondary); font-size: 0.75rem; font-weight: 600; border-radius: var(--radius-pill); padding: 4px 12px; white-space: nowrap; }

/* Score card */
.c-sum-score-inner { display: flex; gap: 24px; align-items: center; }
.c-sum-ring { position: relative; width: 108px; height: 108px; flex-shrink: 0; border-radius: 50%; }
.c-sum-ring__inner { position: absolute; inset: 18px; background: var(--surface-card); border-radius: 50%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; }
.c-sum-ring__pct { font-size: 1.1rem; font-weight: 700; color: var(--text-body); letter-spacing: -0.03em; line-height: 1; }
.c-sum-ring__sub { font-size: 8px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); }
.c-sum-score-details { flex: 1; display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.c-sum-stackbar { height: 7px; border-radius: var(--radius-pill); overflow: hidden; display: flex; background: var(--border-subtle); }
.c-sum-seg--correct { background: #22C55E; }
.c-sum-seg--partial { background: #EAB308; }
.c-sum-seg--wrong   { background: #EF4444; }
.c-sum-counts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; text-align: center; }
.c-sum-count__num { font-size: 1.25rem; font-weight: 700; letter-spacing: -0.03em; line-height: 1; }
.c-sum-count__num--correct { color: #22C55E; }
.c-sum-count__num--partial { color: #EAB308; }
.c-sum-count__num--wrong   { color: #EF4444; }
.c-sum-count__num--skipped { color: var(--text-muted); }
.c-sum-count__label { font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); margin-top: 2px; }
.c-sum-divider { height: 1px; background: var(--border-subtle); margin: 18px 0 14px; }
.c-sum-pills { display: flex; gap: 10px; }
.c-sum-pill { flex: 1; background: var(--surface-page); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); padding: 11px 16px; }
.c-sum-pill__label { font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-muted); margin-bottom: 4px; }
.c-sum-pill__value { font-size: 1.4rem; font-weight: 700; color: var(--text-body); letter-spacing: -0.02em; line-height: 1; }
.c-sum-pill__sub { font-size: 0.72rem; color: var(--text-muted); margin-top: 3px; }

/* History card */
.c-sum-hist-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.c-sum-hist-tabs { display: flex; background: var(--ice); border-radius: 8px; padding: 2px; gap: 2px; }
.c-sum-hist-tab { font-size: 11px; font-weight: 600; color: var(--text-muted); background: transparent; border: 0; border-radius: 6px; padding: 4px 10px; cursor: pointer; white-space: nowrap; }
.c-sum-hist-tab.is-active { background: #fff; color: var(--primary); box-shadow: 0 1px 3px rgba(0,0,0,0.10); }
.c-sum-delta { display: inline-flex; align-items: center; font-size: 0.75rem; font-weight: 600; border-radius: var(--radius-pill); padding: 3px 10px; }
.c-sum-delta--up { background: #DCFCE7; color: #166534; }
.c-sum-delta--down { background: #FEE2E2; color: #B91C1C; }
.c-sum-stats { display: flex; gap: 18px; }
.c-sum-stat { text-align: center; }
.c-sum-stat__label { font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); }
.c-sum-stat__value { font-size: 1.05rem; font-weight: 700; color: var(--text-body); letter-spacing: -0.02em; }
.c-sum-bars { display: flex; align-items: flex-end; gap: 10px; height: 100px; margin-top: 14px; }
.c-sum-bar { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; }
.c-sum-bar__pct { font-size: 10px; color: var(--text-muted); margin-bottom: 4px; }
.c-sum-bar__pct.is-current { color: var(--primary); font-weight: 700; }
.c-sum-bar__fill { width: 100%; max-width: 40px; background: var(--pale); border-radius: 4px 4px 0 0; min-height: 3px; }
.c-sum-bar__fill.is-current { background: var(--primary); }
.c-sum-bar__lbl { font-size: 10px; color: var(--text-muted); margin-top: 4px; }
.c-sum-bar__lbl.is-current { color: var(--primary); font-weight: 600; }

/* Card breakdown list + result chip (chip also used by the history modal) */
.c-sum-breakdown { max-height: 240px; overflow-y: auto; margin-top: 6px; }
.c-sum-bd-row { display: flex; align-items: center; gap: 10px; padding: 9px 2px; border-bottom: 1px solid var(--border-subtle); }
.c-sum-bd-row:last-child { border-bottom: 0; }
.c-sum-bd-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 8px; }
.c-sum-bd-name { flex: 1; font-size: 0.95rem; color: var(--text-body); }
.c-result-chip { font-size: 11px; font-weight: 700; border-radius: var(--radius-pill); padding: 3px 12px; white-space: nowrap; }
.c-result-chip--correct { background: #DCFCE7; color: #166534; }
.c-result-chip--partial { background: #FEF9C3; color: #854D0E; }
.c-result-chip--wrong   { background: #FEE2E2; color: #B91C1C; }
/* Skipped completes the chip family (the session summary's breakdown can include
   skipped items). Uses theme-aware tokens (--border-subtle / --text-muted), so it
   adapts to dark on its own — no dark override needed, unlike the fixed pastels
   above. Mirrors the live `.sum-grade-chip.skipped`. */
.c-result-chip--skipped { background: var(--border-subtle); color: var(--text-muted); }

/* Footer action row */
.c-sum-actions { display: flex; gap: 10px; }
.c-sum-actions .c-btn { flex: 1; }

/* --ice is a fixed light blue in BOTH themes, so any .c-sum-* element using it as a
   fill (the duration pill, the history-tabs track) must flip to a dark surface in
   dark mode — otherwise it reads as a pale pill on the dark card. Recessed track →
   --surface-page; the active tab + duration pill sit raised on --surface-active
   (the same combo the dropdown items use). */
html[data-theme="dark"] .c-sum-duration { background: var(--surface-active); }
html[data-theme="dark"] .c-sum-hist-tabs { background: var(--surface-page); }
html[data-theme="dark"] .c-sum-hist-tab.is-active { background: var(--surface-active); color: var(--secondary); }
/* History bar chart: --pale is a fixed light blue (theme-fixed), so the historic
   bars glare on the dark card. In dark, the historic bars become a muted slate-blue
   (lighter than the --surface-card #2C2C2E so they read, but dim) and the current
   session's bar + labels brighten to --secondary so the just-completed run pops
   most (mirrors the sidebar active-in-dark treatment). */
html[data-theme="dark"] .c-sum-bar__fill { background: #44506B; }
html[data-theme="dark"] .c-sum-bar__fill.is-current { background: var(--secondary); }
html[data-theme="dark"] .c-sum-bar__pct.is-current,
html[data-theme="dark"] .c-sum-bar__lbl.is-current { color: var(--secondary); }
html[data-theme="dark"] .c-sum-delta--up { background: rgba(34,197,94,0.18); color: #4ADE80; }
html[data-theme="dark"] .c-sum-delta--down { background: rgba(239,68,68,0.18); color: #F87171; }
html[data-theme="dark"] .c-result-chip--correct { background: rgba(34,197,94,0.18); color: #4ADE80; }
html[data-theme="dark"] .c-result-chip--partial { background: rgba(234,179,8,0.18); color: #FCD34D; }
html[data-theme="dark"] .c-result-chip--wrong   { background: rgba(239,68,68,0.18); color: #F87171; }

/* ═══════════════════════════════════════════════════════════════════════════
   EXAM SERIES CARD  (Add Result step 1)
   ═══════════════════════════════════════════════════════════════════════════ */
.c-series { border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); padding: 10px 12px; cursor: pointer; display: flex; align-items: center; gap: 10px; }
.c-series:hover { border-color: var(--secondary); background: rgba(0,71,171,0.03); }
.c-series.is-selected { border-color: var(--secondary); background: rgba(0,71,171,0.06); }
.c-series__name { font-size: 13px; font-weight: 600; }
.c-series__meta { font-size: 11px; color: var(--text-muted); }
.c-series__badge { font-size: 10px; font-weight: 600; background: var(--ice); color: var(--secondary); border-radius: var(--radius-pill); padding: 2px 8px; }

/* ═══════════════════════════════════════════════════════════════════════════
   LOGIN CARD
   ═══════════════════════════════════════════════════════════════════════════ */
.c-login { width: 380px; max-width: 100%; background: var(--surface-card); border-radius: var(--radius-sm); box-shadow: var(--shadow-elevated); padding: var(--space-xxl); }
.c-login__brand { font-size: 1.6rem; font-weight: 700; color: var(--primary); text-align: center; }
.c-login__sub { font-size: var(--fs-small); color: var(--secondary); text-align: center; margin-top: 4px; margin-bottom: var(--space-xl); }
/* Stacked form fields with an even rhythm; the submit button spans full width.
   (Evolved from the minimal seed, which spaced fields with inline margins.)
   Controls are the CANONICAL .c-input / .c-btn-primary as-is — no height/font
   override — so auth matches the gallery #login and every other form exactly. */
.c-login__form { display: flex; flex-direction: column; gap: var(--space-md); }
.c-login__form .c-btn-primary { width: 100%; margin-top: 4px; }
/* Two-column row (register first/last name). Collapses to one column when the card
   reflows narrow (mobile frames set their own width; this just stays graceful). */
.c-login__row { display: flex; gap: var(--space-md); }
.c-login__row > .c-field { flex: 1; min-width: 0; }
/* Inline error line — hidden until a failed attempt (.is-shown). Plum, like the
   live; --plum is theme-fixed, so the dark side gets a legible soft-plum override. */
.c-login__error { display: none; color: var(--plum); font-size: var(--fs-small); margin-top: 2px; }
.c-login__error.is-shown { display: block; }
html[data-theme="dark"] .c-login__error { color: #F2B8CD; }
/* Footer action (Create account / Sign in) — a centred ghost button, matching the
   gallery seed. (The live used a plain link; the redesign uses the ghost button.) */
.c-login__footer { text-align: center; margin-top: var(--space-md); }
/* Registration-closed note — single-user tool, ALLOW_REGISTRATION=false. A calm
   info panel above a disabled form. Uses --pale (theme-fixed) as a tint, so it gets
   an explicit dark fill (the fixed-token trap). */
.c-login__note {
	display: flex; gap: 8px;
	padding: 10px 12px; margin-bottom: var(--space-lg);
	background: var(--ice); border: 1px solid var(--pale); border-radius: var(--radius-sm);
	font-size: var(--fs-small); color: var(--text-body); line-height: 1.4;
}
html[data-theme="dark"] .c-login__note { background: rgba(255,255,255,0.05); border-color: var(--border-normal); }

/* ═══════════════════════════════════════════════════════════════════════════
   EDITOR BLOCK ROW  (left-pane editing unit: gutter style-label + content)
   Promoted from the live editor (editor.css .block-edit-row) into the canonical
   set — tokenised + dark-safe. The content uses the UI (sans) font; only the
   rendered preview is serif. States: hover, selected/focus-within (controls
   appear). Equation/code blocks use the --mono content variant.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-block-row { display: flex; align-items: flex-start; position: relative; padding: 2px 0; border-radius: 4px; }
.c-block-row:hover { background: var(--surface-card); }
.c-block-row.is-selected, .c-block-row:focus-within { background: var(--surface-card); }
html[data-theme="dark"] .c-block-row:hover,
html[data-theme="dark"] .c-block-row.is-selected,
html[data-theme="dark"] .c-block-row:focus-within { background: rgba(255,255,255,0.05); }

/* Gutter style label — doubles as the style-picker trigger */
.c-block-row__label {
	flex: 0 0 84px; text-align: right;
	padding: 5px 8px 0 0; line-height: 1.5;
	font-size: 0.75rem; font-weight: 600; letter-spacing: 0.01em;
	color: var(--text-muted); background: none;
	border: 0; border-right: 2px solid transparent; cursor: pointer;
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
	transition: color var(--motion-fast), border-color var(--motion-fast);
}
.c-block-row__label:hover { color: var(--secondary); border-right-color: var(--pale); }
.c-block-row.is-selected .c-block-row__label,
.c-block-row:focus-within .c-block-row__label { color: var(--secondary); border-right-color: var(--secondary); }

/* Content (editable area) — UI font; mono variant for equation/code */
.c-block-row__content {
	flex: 1; min-width: 0;
	font-family: var(--font-ui); font-size: 0.875rem; line-height: 1.65;
	color: var(--text-body); background: transparent;
	padding: 4px 38px 4px 6px;
	border-bottom: 1px solid transparent;
	white-space: pre-wrap; word-break: break-word; outline: none;
}
.c-block-row__content:focus { border-bottom-color: var(--dusty); }
.c-block-row__content--mono { font-family: var(--font-mono); font-size: 0.81rem; }

/* Mini controls — float top-right, appear on hover/selection */
.c-block-row__controls {
	position: absolute; top: 3px; right: 3px; z-index: 10;
	display: flex; align-items: center; gap: 1px;
	opacity: 0; visibility: hidden; transition: opacity var(--motion-fast);
	background: var(--surface-card); border: 1px solid var(--border-subtle);
	border-radius: 4px; padding: 1px 3px; box-shadow: var(--shadow-card);
}
.c-block-row:hover .c-block-row__controls,
.c-block-row.is-selected .c-block-row__controls,
.c-block-row:focus-within .c-block-row__controls { opacity: 1; visibility: visible; }
.c-block-row__btn {
	display: inline-flex; align-items: center; justify-content: center;
	padding: 2px 4px; border: 0; border-radius: 3px;
	background: transparent; color: var(--text-muted); cursor: pointer;
}
.c-block-row__btn:hover { background: var(--surface-hover); color: var(--primary); }
.c-block-row__btn--danger:hover { background: rgba(148,40,90,0.12); color: var(--plum); }
.c-block-row__btn svg { width: 12px; height: 12px; fill: currentColor; }
.c-block-row__drag { cursor: grab; }
.c-block-row__drag:active { cursor: grabbing; }

/* ── Creation-mode states ──────────────────────────────────────────────────────
   In creation mode the row mini-controls give way to the entry-point pills.
   --front = heading that already has cards (blue left rule + fill)
   --back  = content block included in some card's back (green left rule)
   Both carry a 3px coloured left rule so the front/back grouping reads clearly
   against the editor surface (a plain fill tint was too low-contrast). */
.c-block-row--front { background: #DCE8FF; border-left: 3px solid var(--primary); border-radius: 0 6px 6px 0; padding-left: 8px; }
html[data-theme="dark"] .c-block-row--front { background: rgba(0,71,171,0.32); border-left-color: var(--secondary); }
.c-block-row--back { background: #F0FFF4; border-left: 3px solid #30B060; border-radius: 0 4px 4px 0; padding-left: 8px; }
html[data-theme="dark"] .c-block-row--back { background: rgba(48,176,96,0.14); }

/* Heading entry-point tools (creation mode) — float top-right of a heading row.
   A flashcard counter pill + a written-recall counter pill + an add button; each
   opens the Create & Manage modal on the matching tab. Zero-count pills are muted. */
.c-cm-tools { position: absolute; top: 4px; right: 6px; z-index: 6; display: inline-flex; align-items: center; gap: 4px; }
.c-cm-pill { display: inline-flex; align-items: center; gap: 3px; height: 19px; padding: 0 7px; border: 0; border-radius: 10px; font-size: 0.64rem; font-weight: 700; cursor: pointer; }
.c-cm-pill svg { width: 10px; height: 10px; fill: currentColor; }
.c-cm-pill--fc { background: var(--ice); color: var(--primary); }
.c-cm-pill--recall { background: #E7F6EC; color: #2A8A4A; }
.c-cm-pill.is-zero { background: transparent; color: var(--text-muted); box-shadow: inset 0 0 0 1px var(--border-subtle); }
.c-cm-add { width: 19px; height: 19px; border-radius: 50%; border: 1.5px dashed var(--border-normal); background: transparent; color: var(--text-muted); font-size: 12px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.c-cm-add:hover { border-style: solid; border-color: var(--secondary); color: var(--primary); background: var(--surface-active); }
html[data-theme="dark"] .c-cm-pill--fc { background: rgba(0,71,171,0.22); color: var(--secondary); }
html[data-theme="dark"] .c-cm-pill--recall { background: rgba(48,176,96,0.18); color: #5FCC85; }

/* ═══════════════════════════════════════════════════════════════════════════
   ZOOM CONTROL  (editor toolbar — − / % / +). Buttons reuse .c-tb-btn.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-zoom { display: inline-flex; align-items: center; gap: 2px; }
.c-zoom__display { min-width: 3.1rem; text-align: center; font-size: 0.8rem; font-weight: 500; }

/* ═══════════════════════════════════════════════════════════════════════════
   TABLE OF CONTENTS  (subject-read CONTENTS panel — auto-generated nav)
   ───────────────────────────────────────────────────────────────────────────
   Bold note-title group headers + each note's heading blocks beneath, numbered
   and indented by level, with a search box (reuse .c-search) and a collapse
   toggle (‹). The entry tracking scroll position gets .is-active (scroll-spy).
   Persistent panel on wide layouts; the same panel is reused inside the narrow
   .c-toc-drawer. Tokenised + dark-safe; this is CHROME (follows the theme).
   ═══════════════════════════════════════════════════════════════════════════ */
.c-toc {
	display: flex; flex-direction: column;
	width: 240px; flex: 0 0 240px;
	background: var(--surface-nav);
	border-right: 1px solid var(--border-subtle);
	overflow: hidden;
}
.c-toc__head { display: flex; align-items: center; justify-content: space-between; padding: 14px 8px 8px 16px; }
.c-toc__title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); }
.c-toc__collapse {
	width: 24px; height: 24px; flex: 0 0 24px;
	border: 0; background: transparent; color: var(--text-muted); cursor: pointer;
	border-radius: 6px; display: inline-flex; align-items: center; justify-content: center;
}
.c-toc__collapse:hover { background: var(--surface-hover); color: var(--primary); }
.c-toc__collapse svg { width: 14px; height: 14px; fill: currentColor; }
.c-toc__search { padding: 0 12px 10px; }
.c-toc__list { flex: 1; overflow-y: auto; padding: 0 0 16px; }

/* Group header = the note title (bold, not numbered) */
.c-toc__group {
	display: block; padding: 11px 12px 4px 16px;
	font-size: 12.5px; font-weight: 700; color: var(--text-body);
	text-decoration: none; cursor: pointer;
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.c-toc__group:hover { color: var(--primary); }

/* Heading entry rows — numbered, level-indented, active scroll-spy state */
.c-toc__link {
	display: block; padding: 3px 12px 3px 16px;
	font-size: 12px; line-height: 1.4; color: var(--text-muted);
	text-decoration: none; cursor: pointer;
	border-left: 3px solid transparent;
	overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
	transition: background var(--motion-fast), color var(--motion-fast), border-color var(--motion-fast);
}
.c-toc__link:hover { background: var(--surface-hover); color: var(--primary); border-left-color: var(--pale); }
.c-toc__link.is-active { background: var(--ice); color: var(--primary); border-left-color: var(--primary); }
.c-toc__num { color: var(--text-muted); font-variant-numeric: tabular-nums; margin-right: 5px; }
.c-toc__link.is-active .c-toc__num { color: var(--primary); }
/* Level indents (headings nest under the note-title group) */
.c-toc__link--l1 { padding-left: 24px; }
.c-toc__link--l2 { padding-left: 38px; }
.c-toc__link--l3 { padding-left: 52px; }
.c-toc__link--l4 { padding-left: 66px; font-size: 11.5px; }
.c-toc__link--l5 { padding-left: 80px; font-size: 11.5px; }

/* Collapsed (wide layouts) — slim rail with just the expand toggle */
.c-toc.is-collapsed { width: 40px; flex-basis: 40px; }
.c-toc.is-collapsed .c-toc__title,
.c-toc.is-collapsed .c-toc__search,
.c-toc.is-collapsed .c-toc__list { display: none; }
.c-toc.is-collapsed .c-toc__head { justify-content: center; padding: 12px 0; }

html[data-theme="dark"] .c-toc__link.is-active { background: var(--surface-active); color: var(--secondary); border-left-color: var(--primary); }
html[data-theme="dark"] .c-toc__link.is-active .c-toc__num { color: var(--secondary); }

/* CONTENTS drawer — narrow widths (iOS / web-mobile / iPad-portrait). The same
   .c-toc panel in a left slide-in sheet over a dimmed backdrop, opened by the
   toolbar's "Contents" button. Anchors to a position:relative ancestor (the
   page sets it on .rd-body); .is-open reveals it. */
.c-toc-drawer { position: absolute; inset: 0; z-index: 40; display: none; }
.c-toc-drawer.is-open { display: block; }
.c-toc-drawer__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.42); }
.c-toc-drawer .c-toc {
	position: absolute; top: 0; left: 0; height: 100%;
	width: 264px; max-width: 84%;
	/* Right-edge shadow only — negative spread = blur cancels the vertical bleed,
	   so no shadow shows on the top (or bottom) edge. */
	box-shadow: 12px 0 12px -12px rgba(0,0,0,0.40);
}

/* Respect reduced-motion: stop the looping shimmer/pulse for users who ask for it. */
@media (prefers-reduced-motion: reduce) {
	.c-skeleton, .c-creation-banner__dot { animation: none; }
	.c-scope *, .c-scope *::before, .c-scope *::after { transition-duration: 0.01ms !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SCORE-TRENDS CHART  (Exam Results — per-subject % line chart)
   ───────────────────────────────────────────────────────────────────────────
   A small data-viz widget: one inline-SVG line chart per subject (gridlines,
   connecting polyline, grade-coloured dots, −45° date labels). Promoted from
   the live exams.js renderSubjectTrends() — the Dashboard's exam card shows the
   same viz, so it's a genuine reusable widget, not page layout.

   Theme-adaptive parts (gridlines, axis text, dot halo) read tokens via these
   classes; the per-subject LINE colour (subject colour) and per-dot FILL (grade
   --g-bar) are set inline by the caller since they're data, not chrome. Dots add
   a g-* class so the fill can also read var(--g-bar) for the grade colour.
   ═══════════════════════════════════════════════════════════════════════════ */
.c-trends { display: flex; flex-wrap: wrap; gap: var(--space-lg); }
.c-trends__chart { min-width: 0; }
.c-trends__label { font-size: 11px; font-weight: 600; color: var(--text-muted); margin-bottom: 3px; display: flex; align-items: center; gap: 5px; }
.c-trends__svg { display: block; max-width: 100%; height: auto; }
.c-trends__grid { stroke: var(--border-subtle); stroke-width: 0.75; }
.c-trends__axis { fill: var(--text-muted); font-size: 8px; font-family: inherit; }
.c-trends__date { fill: var(--text-muted); font-size: 9px; font-family: inherit; }
.c-trends__line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; opacity: 0.6; }   /* stroke (subject colour) inline */
.c-trends__dot  { stroke: var(--surface-card); stroke-width: 1.5; }                                            /* fill (grade colour) inline */

/* ═══════════════════════════════════════════════════════════════════════════
   TOPIC-BREAKDOWN BARS  (Exam Results — per-topic average % bar list)
   ───────────────────────────────────────────────────────────────────────────
   A labelled horizontal %-bar list: topic name · track+fill · value. Promoted
   from the live exams.js renderTopicChart(); the Dashboard's "weakest topics"
   surface reuses the same pattern. The fill colour is the grade --g-bar for the
   topic's average — add a g-* class to the fill element so it resolves. Track is
   token-driven (theme-adaptive). Collision-checked: distinct from .c-proximity
   (that's an un-labelled 6px score bar with boundary ticks).
   ═══════════════════════════════════════════════════════════════════════════ */
.c-topic-bars { display: flex; flex-direction: column; gap: 6px; }
.c-topic-bars__row { display: grid; grid-template-columns: 130px 1fr 40px; gap: 8px; align-items: center; }
.c-topic-bars__label { font-size: 11px; color: var(--text-muted); text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.c-topic-bars__track { display: block; height: 10px; border-radius: 3px; background: var(--border-subtle); overflow: hidden; }
/* display:block is load-bearing — the fill is a <span> child of the track (not a
   grid item, so not blockified), and an inline span ignores width/height → the
   bar would render empty. The g-* class on the fill sets --g-bar (grade colour). */
.c-topic-bars__fill { display: block; height: 100%; border-radius: 3px; background: var(--g-bar, var(--secondary)); }
.c-topic-bars__value { font-size: 10px; color: var(--text-muted); }

/* ═══════════════════════════════════════════════════════════════════════════
   ADMIN SYSTEMATISATION  (wave 13) — tab error variant · badge semantics ·
   key/value row · table cell helpers · trends bar-series + legend
   ───────────────────────────────────────────────────────────────────────────
   The live /admin page was entirely bespoke (one big <style> block). These
   additions re-express its widgets in the component system. The dominant risk
   was the theme-fixed-token trap: the live leaned on --ice fills + hardcoded
   badge hex, so every fill here either routes through a THEMED token or carries
   an explicit dark override (mirrors how .c-rating / .g-* handle semantic hex).
   ═══════════════════════════════════════════════════════════════════════════ */

/* Errors tab — plum-tinted underline tab (the live .admin-tab.errors-tab). The
   base .c-tab/.c-tabs (above) is already a 2px underline bar, so this is the one
   semantic colour swap; active state underlines in plum too. */
.c-tab--errors { color: var(--plum); }
.c-tab--errors:hover { color: var(--plum); }
.c-tab--errors.is-active { color: var(--plum); border-bottom-color: var(--plum); }

/* ── Badge semantic modifiers ──────────────────────────────────────────────
   Extend the existing .c-badge (--fc/--rq) with the admin status semantics. The
   blue/plum/orange route through tokens; the green (ok) + red (danger) follow
   the curated-semantic-hex pattern (.c-rating, .g-*) with explicit dark
   overrides — there is no green/red token to point at. */
.c-badge--study { background: var(--ice); color: var(--primary); }            /* Study type · admin tag · audit action */
.c-badge--recall { background: #FDF0F7; color: var(--plum); }                 /* Recall type */
.c-badge--ok { background: #E6F4EA; color: #1A7F3C; }                         /* env YES · login success */
.c-badge--danger { background: #FDE8E8; color: #B91C1C; }                     /* env NO · login failed */
.c-badge--warn { background: #FFF4ED; color: var(--orange); }                 /* suspended */
.c-badge--sm { font-size: 9.5px; padding: 1px 6px; letter-spacing: 0.02em; }  /* inline row tags (admin/suspended) */
html[data-theme="dark"] .c-badge--study { background: rgba(0,71,171,0.18); color: var(--secondary); }
html[data-theme="dark"] .c-badge--recall { background: rgba(148,40,90,0.18); color: #E879B0; }
html[data-theme="dark"] .c-badge--ok { background: rgba(26,127,60,0.18); color: #4ADE80; }
html[data-theme="dark"] .c-badge--danger { background: rgba(185,28,28,0.18); color: #F87171; }
html[data-theme="dark"] .c-badge--warn { background: rgba(232,110,30,0.18); color: #FB923C; }

/* ── Key/value row ─────────────────────────────────────────────────────────
   A label-left / value-right divider row. Promoted (recurs on Overview's System
   Health + DB Snapshot, the System tab's three cards, and likely the Account
   page). Chrome → follows the theme. The --boxed variant is the env-grid chip
   (filled, no divider) that sits in a 2-up grid (the grid is page-local). */
.c-kv-row {
	display: flex; align-items: center; justify-content: space-between;
	gap: var(--space-md); padding: 8px 12px;
	border-bottom: 1px solid var(--border-subtle);
	font-size: 13px;
}
.c-kv-row:last-child { border-bottom: 0; }
.c-kv-row__key { color: var(--text-muted); min-width: 0; }
.c-kv-row__key--mono { font-family: var(--font-mono); font-size: 12px; }
.c-kv-row__val { color: var(--text-body); font-weight: 500; text-align: right; white-space: nowrap; }
.c-kv-row__val--mono { font-family: var(--font-mono); font-size: 12px; font-weight: 400; }
.c-kv-row__val--strong { font-weight: 700; font-variant-numeric: tabular-nums; }
.c-kv-row--boxed {
	border-bottom: 0; border-radius: var(--radius-sm);
	background: var(--surface-editor-left); padding: 7px 10px;
}

/* ── Table cell helpers ────────────────────────────────────────────────────
   Small scoped helpers for the dense admin tables (Users/Activity/Audit/DB).
   --zebra stripes even rows with a THEMED fill (the live used --ice → a
   theme-fixed token, which doesn't darken; here it routes through a token +
   dark override). */
.c-table--zebra tbody tr:nth-child(even) > td { background: var(--surface-editor-left); }
html[data-theme="dark"] .c-table--zebra tbody tr:nth-child(even) > td { background: rgba(255,255,255,0.02); }
.c-table .cell-muted { color: var(--text-muted); }
.c-table .cell-mono { font-family: var(--font-mono); font-size: 12px; }
.c-table .cell-num { text-align: right; font-variant-numeric: tabular-nums; }
.c-table .cell-center { text-align: center; }
.c-table .cell-strong { font-weight: 600; }

/* ── Trends bar-series + legend ────────────────────────────────────────────
   The line classes above stay for line charts (Exam Results). Admin's chart is
   a 2-series grouped vertical BAR chart (signups vs sessions), so this adds the
   bar mark + a legend, keeping ONE .c-trends family. The per-series bar FILL +
   legend-dot colour are set inline (data, like the line stroke). rx is set as a
   <rect> attribute in markup. */
.c-trends__bar { opacity: 0.85; }
.c-trends__legend { display: flex; gap: var(--space-lg); flex-wrap: wrap; margin-top: 4px; }
.c-trends__legend-item { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-muted); }
.c-trends__legend-dot { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }

/* ── Action row ────────────────────────────────────────────────────────────
   A label + sub-label on the left, a trailing action button on the right, in a
   filled inset row. Promoted from the admin user-detail modal (toggle admin /
   suspend / export / delete) because the Account page (p14) has near-identical
   account-action rows. Chrome → follows the theme. The danger button variant
   reuses the curated red (mirrors .c-badge--danger) with a dark override. Must
   sit inside a .c-scope (the __btn height reads --ctl-h-sm). */
.c-action-row {
	display: flex; align-items: center; justify-content: space-between;
	gap: var(--space-md); padding: 10px 12px;
	background: var(--surface-editor-left); border-radius: var(--radius-md);
}
.c-action-row__label { font-size: 13px; font-weight: 500; color: var(--text-body); }
.c-action-row__sub { font-size: 12px; color: var(--text-muted); margin-top: 1px; }
.c-action-row__btn {
	appearance: none; -webkit-appearance: none;
	flex: 0 0 auto; height: var(--ctl-h-sm); padding: 0 12px;
	/* inline-flex centring + no underline so an <a> consumer (admin's Export
	   download link) renders identically to a <button>. */
	display: inline-flex; align-items: center; justify-content: center;
	text-decoration: none;
	border: 1px solid var(--border-normal); border-radius: var(--radius-sm);
	background: var(--surface-card); color: var(--text-body);
	font-family: inherit; font-size: 13px; font-weight: 600;
	cursor: pointer; white-space: nowrap;
	transition: background var(--motion-fast), color var(--motion-fast);
}
.c-action-row__btn:hover { background: var(--surface-hover); }
.c-action-row__btn--danger { border-color: #B91C1C; color: #B91C1C; }
.c-action-row__btn--danger:hover { background: #FDE8E8; }
html[data-theme="dark"] .c-action-row__btn--danger { border-color: #F87171; color: #F87171; }
html[data-theme="dark"] .c-action-row__btn--danger:hover { background: rgba(185,28,28,0.18); }

/* ═══════════════════════════════════════════════════════════════════════════
   STUDY LAUNCHERS  (.c-study-mode, .c-study-row)
   ───────────────────────────────────────────────────────────────────────────
   Promoted 2026-06-10 from the Study-Hub wave (was .sh-mode / .shn page-glue).
   Two consumption surfaces for launching a study session:
     · .c-study-mode — a subject-level launcher CARD (one per mode: Flashcards /
       Written Recall): icon+title, blurb, a Total/Due meta block, a Due/All/
       Shuffle scope segment, and a full-width launch CTA.
     · .c-study-row  — a per-NOTE launch row: note name/date + one or more mode
       groups (icon, "<total> · N due" count, a Study/Recall button).
   Both render counts only (no note content) and MUST sit inside a .c-scope (the
   nested .c-segment / .c-btn read the --ctl-h* control-height tokens). Page
   composition — the grids that place several, the streak chip, narrow stacking —
   stays in the page's own CSS.
   ═══════════════════════════════════════════════════════════════════════════ */

.c-study-mode {
	display: flex; flex-direction: column;
	background: var(--surface-card);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-card);
	padding: var(--space-xl);
}
.c-study-mode__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.c-study-mode__icon {
	width: 34px; height: 34px; flex: 0 0 34px;
	border-radius: var(--radius-sm);
	display: flex; align-items: center; justify-content: center;
	background: var(--ice); color: var(--secondary);
}
html[data-theme="dark"] .c-study-mode__icon { background: #383838; }
.c-study-mode__title { font-size: 16px; font-weight: 700; color: var(--text-body); }
.c-study-mode__desc { font-size: 13px; line-height: 1.5; color: var(--text-muted); margin-bottom: var(--space-lg); }
.c-study-mode__meta {
	display: flex; flex-direction: column; gap: 6px;
	border-top: 1px solid var(--border-subtle);
	padding-top: var(--space-md); margin-bottom: var(--space-lg);
}
.c-study-mode__row { display: flex; justify-content: space-between; font-size: 13px; }
.c-study-mode__row span:first-child { color: var(--text-muted); }
.c-study-mode__row span:last-child { color: var(--text-body); font-weight: 600; }
/* The meta Total + Due values share one colour (text-body) in BOTH themes — the
   per-note row keeps the blue "N due" highlight, but the launcher meta does not,
   so the two figures never diverge across light/dark. */
.c-study-mode__scope { margin-bottom: var(--space-md); }
.c-study-mode__scope .c-segment { width: 100%; }
.c-study-mode__scope .c-segment__btn { flex: 1; text-align: center; }
.c-study-mode__foot { margin-top: auto; }
.c-study-mode__foot .c-btn { width: 100%; }

.c-study-row {
	display: flex; align-items: center; gap: var(--space-lg);
	background: var(--surface-card);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-card);
	padding: var(--space-md) var(--space-lg);
}
.c-study-row__id { flex: 1; min-width: 0; }
.c-study-row__name { font-size: 14px; font-weight: 600; color: var(--text-body); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.c-study-row__date { font-size: 12px; color: var(--text-muted); margin-top: 1px; }
.c-study-row__modes { display: flex; gap: var(--space-md); flex: 0 0 auto; }
.c-study-row__mode { display: flex; align-items: center; gap: 8px; }
.c-study-row__mode-icon {
	width: 28px; height: 28px; flex: 0 0 28px;
	border-radius: var(--radius-sm);
	display: flex; align-items: center; justify-content: center;
	background: var(--ice); color: var(--secondary);
}
html[data-theme="dark"] .c-study-row__mode-icon { background: #383838; }
.c-study-row__count { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.c-study-row__count strong { color: var(--text-body); }
.c-study-row__count .due { color: var(--primary); }
html[data-theme="dark"] .c-study-row__count .due { color: var(--secondary); }
