/* ==========================================================================
   Genki Music Tools - shared stylesheet
   --------------------------------------------------------------------------
   The same tokens as drums.genkimusic.com, the metronome and genkimusic.com,
   so everything reads as one family. Each tool sets its own --accent on
   <body> via a data-tool attribute; nothing else changes between them.
   Mobile-first: these get used on a phone on a music stand more than anywhere.
   ========================================================================== */

:root {
	--bg:            #0b0c10;
	--bg-elevated:   #13151c;
	--surface:       #171a22;
	--surface-hover: #1e222c;
	--line:          #272b36;
	--line-soft:     #1f232c;

	--text:          #eceef3;
	--text-muted:    #9aa2b1;
	--text-faint:    #6b7383;

	--red:     #ff5f6d;
	--orange:  #ff9f45;
	--yellow:  #ffd166;
	--green:   #5ddc95;
	--teal:    #45c9d6;
	--blue:    #6f8cff;
	--purple:  #b98cff;
	--pink:    #ff7ab8;

	/* Overridden per tool below. Orange belongs to the drum generator and
	   teal to the metronome, so the new four take the remaining colours. */
	--accent: var(--blue);
	--accent-ink: #06102e;
	--accent-lift: #8ba4ff; /* the hover shade of --accent */

	--font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
	             Roboto, Helvetica, Arial, sans-serif;
	--font-display: "Space Grotesk", var(--font-sans);
	--font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

	--wrap: 1040px;
	--radius: 14px;
	--radius-sm: 8px;
	--header-h: 60px;
	--shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 28px rgba(0, 0, 0, .35);
}

body[data-tool="melody"]     { --accent: var(--purple); --accent-ink: #1b0b33; --accent-lift: #cba6ff; }
body[data-tool="harmony"]    { --accent: var(--green);  --accent-ink: #04220f; --accent-lift: #86e9b3; }
body[data-tool="notes"]      { --accent: var(--blue);   --accent-ink: #06102e; --accent-lift: #8ba4ff; }
body[data-tool="transcribe"] { --accent: var(--pink);   --accent-ink: #33061d; --accent-lift: #ff9ecb; }
body[data-tool="hub"]        { --accent: var(--yellow); --accent-ink: #2b2000; --accent-lift: #ffe08f; }

*, *::before, *::after { box-sizing: border-box; }

[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
	margin: 0;
	background: var(--bg);
	color: var(--text);
	font-family: var(--font-sans);
	font-size: 16px;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
	-webkit-tap-highlight-color: transparent;
	overflow-wrap: break-word;
}

img { max-width: 100%; height: auto; display: block; }

a { color: var(--accent); text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.18); }
a:hover { border-bottom-color: currentColor; }

h1, h2, h3 { font-family: var(--font-display); font-weight: 600; line-height: 1.25; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; }

.skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	padding: 10px 16px;
	background: var(--accent);
	color: var(--accent-ink);
	border: 0;
	z-index: 100;
}
.skip-link:focus { left: 8px; top: 8px; }

/* --- Header ------------------------------------------------------------- */

.site-header {
	position: sticky;
	top: 0;
	z-index: 20;
	display: flex;
	align-items: center;
	gap: 14px;
	height: var(--header-h);
	padding: 0 16px;
	background: rgba(11, 12, 16, .88);
	backdrop-filter: blur(10px);
	border-bottom: 1px solid var(--line);
}

.brand {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 14px;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--text-muted);
	border: 0;
	white-space: nowrap;
}
.brand:hover { color: var(--text); }

.site-title {
	margin: 0;
	font-size: 18px;
	letter-spacing: -.01em;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.site-title::before {
	content: "";
	display: inline-block;
	width: 6px; height: 6px;
	margin-right: 9px;
	border-radius: 50%;
	background: var(--accent);
	vertical-align: middle;
}

.header-actions {
	margin-left: auto;
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 12px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--text-faint);
	white-space: nowrap;
}
.header-actions a { color: var(--text-faint); border: 0; }
.header-actions a:hover { color: var(--accent); }

/* --- Layout ------------------------------------------------------------- */

.wrap {
	max-width: var(--wrap);
	margin: 0 auto;
	padding: 18px 14px 60px;
}

.panel {
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--radius);
	padding: 16px;
	margin-bottom: 16px;
	box-shadow: var(--shadow);
}

.panel__title {
	margin: 0 0 14px;
	font-size: 15px;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--text-muted);
}
.panel__hint {
	text-transform: none;
	letter-spacing: 0;
	font-size: 13px;
	font-weight: 400;
	color: var(--text-faint);
	margin-left: 8px;
}

.sub {
	margin: 20px 0 6px;
	font-size: 14px;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--accent);
}
.sub:first-child { margin-top: 4px; }

.note {
	margin: 6px 0;
	font-size: 13px;
	color: var(--text-faint);
	line-height: 1.5;
}
.note--warn { color: var(--yellow); }
.note--error { color: var(--red); }

/* --- Collapsing panels -------------------------------------------------- */
/* <details>/<summary> rather than scripted show/hide: it opens with no script,
   keyboard works for free and screen readers announce the state. */

.panel--collapse { padding: 0; }

.panel__toggle {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 14px 16px;
	margin: 0;
	font-family: var(--font-display);
	font-size: 15px;
	font-weight: 600;
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--text-muted);
	cursor: pointer;
	list-style: none;
	border-radius: var(--radius);
}
.panel__toggle::-webkit-details-marker { display: none; }
.panel__toggle:hover { color: var(--text); background: var(--surface-hover); }

.panel__toggle::after {
	content: "+";
	margin-left: auto;
	font-size: 20px;
	line-height: 1;
	color: var(--text-faint);
}
.panel--collapse[open] > .panel__toggle {
	border-bottom: 1px solid var(--line);
	border-radius: var(--radius) var(--radius) 0 0;
	color: var(--text);
}
.panel--collapse[open] > .panel__toggle::after { content: "\2212"; }

.panel__body { padding: 4px 16px 18px; }

/* --- Stave -------------------------------------------------------------- */
/* VexFlow draws black-on-white by default and fights any attempt to recolour
   every glyph, so the score keeps its own manuscript-paper background rather
   than being forced into the dark theme. It also prints and exports properly
   this way. */

.panel--score { background: linear-gradient(180deg, var(--bg-elevated), var(--surface)); }

.score {
	background: #f7fbff;
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	padding: 4px;
	overflow-x: auto;
	overflow-y: hidden;
	min-height: 150px;
}
.score svg { display: block; margin: 0 auto; }

/* Highlights the note currently sounding during playback. */
.score .vf-note--playing path,
.score .vf-note--playing rect { fill: #d2402a; stroke: #d2402a; }

.score__empty {
	display: grid;
	place-items: center;
	min-height: 150px;
	color: #6b7383;
	font-size: 14px;
	text-align: center;
	padding: 20px;
}

/* --- Transport ---------------------------------------------------------- */

.transport { text-align: center; }

.transport__buttons {
	display: flex;
	justify-content: center;
	gap: 10px;
	flex-wrap: wrap;
	margin-top: 16px;
}

.bpm {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	margin: 18px 0 2px;
}

.bpm__main { min-width: 180px; }

.bpm__value {
	display: block;
	font-family: var(--font-display);
	font-size: 60px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: -.03em;
	font-variant-numeric: tabular-nums;
}

.bpm__unit {
	display: block;
	font-size: 12px;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--text-faint);
}

.bpm__step {
	width: 48px; height: 48px;
	flex: 0 0 auto;
	font-family: var(--font-sans);
	font-size: 24px;
	line-height: 1;
	color: var(--text);
	background: var(--surface-hover);
	border: 1px solid var(--line);
	border-radius: 50%;
	cursor: pointer;
}
.bpm__step:active { background: var(--accent); color: var(--accent-ink); }

.bpm__slider { width: 100%; max-width: 520px; margin: 8px 0 0; }

/* Range inputs, styled the same across every tool */
input[type="range"] {
	-webkit-appearance: none;
	appearance: none;
	width: 100%;
	height: 26px;
	background: transparent;
	cursor: pointer;
}
input[type="range"]::-webkit-slider-runnable-track {
	height: 5px;
	border-radius: 3px;
	background: var(--line);
}
input[type="range"]::-webkit-slider-thumb {
	-webkit-appearance: none;
	width: 20px; height: 20px;
	margin-top: -8px;
	border-radius: 50%;
	background: var(--accent);
	border: 0;
}
input[type="range"]::-moz-range-track { height: 5px; border-radius: 3px; background: var(--line); }
input[type="range"]::-moz-range-thumb {
	width: 20px; height: 20px; border: 0; border-radius: 50%; background: var(--accent);
}

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

.btn {
	font-family: var(--font-sans);
	font-size: 15px;
	font-weight: 600;
	color: var(--text);
	background: var(--surface-hover);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	padding: 11px 18px;
	cursor: pointer;
	transition: background-color .15s ease, border-color .15s ease, transform .06s ease;
}
.btn:hover { background: #232734; border-color: #3a4050; }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; }

.btn--primary {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--accent-ink);
	min-width: 150px;
}
.btn--primary:hover { background: var(--accent-lift); border-color: var(--accent-lift); }

.btn--ghost { background: transparent; padding: 8px 12px; font-size: 14px; }
.btn--tiny { font-size: 13px; padding: 7px 12px; font-weight: 500; }
.btn--stop:hover { border-color: var(--red); color: var(--red); }
.btn--rec { color: var(--red); }
.btn--rec.is-armed { background: var(--red); border-color: var(--red); color: #2a0409; }

/* --- Form controls ------------------------------------------------------ */

.fields {
	display: grid;
	grid-template-columns: 1fr;
	gap: 14px;
}

.field { display: flex; flex-direction: column; gap: 6px; }

.field__label {
	font-size: 12px;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--text-muted);
}
.field__hint { font-size: 12px; color: var(--text-faint); }
/* A hint that has turned into a complaint - an input driven past full scale,
   for one. Same size and place, so nothing moves when it changes. */
.field__hint--warn { color: var(--yellow); }

/* The mic panel stacks two controls, each with a hint under it. Without this
   the first hint sits hard against the second label and it stops being clear
   which belongs to which. */
.mc-field + .mc-field { margin-top: 14px; }

select, input[type="text"], input[type="number"] {
	font-family: var(--font-sans);
	font-size: 15px;
	color: var(--text);
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	padding: 11px 12px;
	min-height: 44px;
	width: 100%;
	appearance: none;
}
select {
	/* A chevron drawn in the URL rather than an image request. */
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%239aa2b1' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 12px center;
	background-size: 12px 8px;
	padding-right: 34px;
}
select:hover, input:hover { border-color: #3a4050; }
optgroup { background: var(--bg-elevated); color: var(--text-faint); }

/* --- Option checkboxes -------------------------------------------------- */

.opts {
	display: grid;
	grid-template-columns: 1fr;
	gap: 8px;
}

.check {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 44px;
	padding: 4px 12px;
	font-size: 14px;
	color: var(--text);
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	cursor: pointer;
}
.check:hover { background: var(--surface-hover); border-color: #3a4050; }
.check input {
	width: 20px; height: 20px;
	flex: 0 0 auto;
	accent-color: var(--accent);
	cursor: pointer;
}
.check:has(input:checked) { border-color: var(--accent); }
.check__sub { color: var(--text-faint); }

/* --- Segmented control (radio pills) ------------------------------------ */

.seg { display: flex; flex-wrap: wrap; gap: 6px; }

.seg label {
	flex: 1 1 auto;
	text-align: center;
	min-height: 40px;
	display: grid;
	place-items: center;
	padding: 4px 12px;
	font-size: 14px;
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	cursor: pointer;
	white-space: nowrap;
}
.seg input { position: absolute; opacity: 0; pointer-events: none; }
.seg label:hover { background: var(--surface-hover); }
.seg label:has(input:checked) {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--accent-ink);
	font-weight: 600;
}

/* --- Big readout (note namer) ------------------------------------------- */

.readout { text-align: center; padding: 10px 0 4px; }

.readout__note {
	font-family: var(--font-display);
	font-size: clamp(72px, 22vw, 148px);
	font-weight: 700;
	line-height: .95;
	letter-spacing: -.04em;
	color: var(--accent);
	min-height: 1em;
}
.readout__note.is-idle { color: var(--line); }
.readout__acc { font-size: .45em; vertical-align: super; letter-spacing: 0; }
.readout__oct { font-size: .34em; color: var(--text-muted); vertical-align: sub; margin-left: .06em; }

.readout__meta {
	display: flex;
	justify-content: center;
	gap: 22px;
	flex-wrap: wrap;
	margin-top: 10px;
	font-size: 13px;
	color: var(--text-faint);
	font-variant-numeric: tabular-nums;
}
.readout__meta b { color: var(--text-muted); font-weight: 600; }

/* Tuner strip: -50 to +50 cents, with the needle positioned by script. */
.tuner {
	position: relative;
	height: 54px;
	margin: 14px auto 0;
	max-width: 460px;
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	overflow: hidden;
}
.tuner__centre {
	position: absolute;
	left: 50%; top: 6px; bottom: 6px;
	width: 2px;
	margin-left: -1px;
	background: var(--line);
}
.tuner__band {
	position: absolute;
	left: 45%; right: 45%; top: 0; bottom: 0;
	background: rgba(93, 220, 149, .10);
}
.tuner__needle {
	position: absolute;
	top: 4px; bottom: 4px;
	left: 50%;
	width: 4px;
	margin-left: -2px;
	border-radius: 2px;
	background: var(--accent);
	transition: left .06s linear, background-color .2s ease;
}
.tuner__needle.is-intune { background: var(--green); }
.tuner__scale {
	position: absolute;
	inset: auto 8px 3px;
	display: flex;
	justify-content: space-between;
	font-size: 10px;
	letter-spacing: .08em;
	color: var(--text-faint);
}

/* Input level meter */
.level {
	position: relative;
	height: 8px;
	margin: 12px auto 0;
	max-width: 460px;
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	border-radius: 5px;
	overflow: hidden;
}
.level__fill {
	height: 100%;
	width: 0;
	background: linear-gradient(90deg, var(--green), var(--yellow) 70%, var(--red));
	transition: width .05s linear;
}

/* Where the noise gate sits, drawn on the meter itself. Seeing the threshold
   against the live level is the quickest way to understand why quiet playing
   is or is not registering. */
.level--wide { max-width: none; height: 14px; margin: 0; flex: 1 1 auto; }
.level__gate {
	position: absolute;
	top: -2px; bottom: -2px;
	width: 2px;
	background: var(--text);
	box-shadow: 0 0 0 1px rgba(0, 0, 0, .55);
}

.meter-row {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 14px 0 12px;
}
.meter-row .field__hint {
	min-width: 8ch;
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/* --- Tuner ---------------------------------------------------------------- */

/* Teal is the metronome's colour, and a tuner sits beside a metronome in
   anyone's head, so the two sharing an accent is the right kind of hint. */
body[data-tool="tuner"] { --accent: var(--teal); --accent-ink: #032a2f; --accent-lift: #7adde8; }

/* The strings of whatever is being tuned, laid out as buttons. Tapping one
   locks the tuner to it; otherwise it follows whichever you play. */
.strings {
	display: grid;
	grid-auto-flow: column;
	grid-auto-columns: 1fr;
	gap: 6px;
	margin: 18px 0 4px;
}
/* Past about seven strings, columns get too narrow to tap; wrap instead. */
.strings--many {
	grid-auto-flow: row;
	grid-template-columns: repeat(auto-fit, minmax(64px, 1fr));
}

.string {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	min-height: 62px;
	padding: 8px 4px;
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	color: var(--text-muted);
	font-family: var(--font-sans);
	cursor: pointer;
	transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.string:hover { background: var(--surface-hover); }
.string__name {
	font-family: var(--font-display);
	font-size: 20px;
	font-weight: 600;
	line-height: 1;
	color: var(--text);
}
.string__num { font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--text-faint); }
.string__hz { font-size: 10px; color: var(--text-faint); font-variant-numeric: tabular-nums; }

/* Hearing a string's note is its own control rather than a second meaning for
   tapping the cell, so neither gesture can disturb the other. */
.string__play {
	display: grid;
	place-items: center;
	width: 26px; height: 22px;
	margin-top: 1px;
	font-size: 12px;
	line-height: 1;
	color: var(--text-faint);
	background: transparent;
	border: 1px solid var(--line);
	border-radius: 5px;
	cursor: pointer;
}
.string__play:hover { color: var(--accent); border-color: var(--accent); }
.string__play:active { background: var(--accent); color: var(--accent-ink); }

/* Chromatic mode: nothing to lock onto, so the cell stops behaving like a
   button. The note button inside it stays usable. */
.string.is-inert { cursor: default; opacity: .72; }
.string.is-inert:hover { background: var(--bg-elevated); }
.string.is-inert .string__play { cursor: pointer; opacity: 1; }

/* The string currently being played. */
.string.is-near { border-color: var(--accent); color: var(--text); }
.string.is-near .string__name { color: var(--accent); }
/* Held in tune long enough to count as done. */
.string.is-done { border-color: var(--green); background: rgba(93, 220, 149, .1); }
.string.is-done .string__name { color: var(--green); }
.string.is-done .string__num::after { content: " ✓"; color: var(--green); }
/* Locked by tapping it. */
.string.is-locked { outline: 2px solid var(--accent); outline-offset: 1px; }

/* A bigger version of the tuner strip, since this is the whole point here. */
.tuner--big { height: 104px; max-width: 620px; }
.tuner--big .tuner__needle { width: 6px; margin-left: -3px; border-radius: 3px; }
.tuner--big .tuner__band { left: 46.5%; right: 46.5%; }

/* Marks every 10 cents, so you can see how far out you are at a glance. */
.tuner__ticks { position: absolute; inset: 0; pointer-events: none; }
.tuner__tick {
	position: absolute;
	top: 8px;
	width: 1px;
	height: 9px;
	background: var(--line);
}
.tuner__tick--major { height: 15px; background: var(--line-soft); background: #3a4050; }

.verdict {
	margin-top: 12px;
	min-height: 30px;
	font-family: var(--font-display);
	font-size: 20px;
	font-weight: 600;
	letter-spacing: .01em;
}
.verdict.is-flat { color: var(--yellow); }
.verdict.is-sharp { color: var(--yellow); }
.verdict.is-intune { color: var(--green); }
.verdict.is-idle { color: var(--text-faint); font-weight: 400; font-size: 16px; }

.cents-big {
	font-family: var(--font-display);
	font-size: 34px;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	line-height: 1;
}

/* --- Chips / note history ----------------------------------------------- */

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

.chip {
	font-family: var(--font-mono);
	font-size: 13px;
	padding: 5px 10px;
	border-radius: 999px;
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	color: var(--text-muted);
}
.chip--accent { border-color: var(--accent); color: var(--accent); }

/* --- Status line -------------------------------------------------------- */

.status {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
	min-height: 24px;
	font-size: 13px;
	color: var(--text-muted);
	text-align: center;
}
.status__dot {
	width: 9px; height: 9px;
	border-radius: 50%;
	background: var(--line);
	flex: 0 0 auto;
}
.status.is-live .status__dot { background: var(--green); animation: pulse 1.6s ease-in-out infinite; }
.status.is-rec  .status__dot { background: var(--red);   animation: pulse .9s ease-in-out infinite; }
.status.is-error .status__dot { background: var(--red); }

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) {
	.status__dot { animation: none !important; }
	* { transition-duration: .01ms !important; }
}

/* --- Analysis / results grid -------------------------------------------- */

.facts {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: 10px;
}
.fact {
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	padding: 12px;
}
.fact__label {
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--text-faint);
}
.fact__value {
	font-family: var(--font-display);
	font-size: 22px;
	font-weight: 600;
	line-height: 1.2;
	margin-top: 2px;
}

/* --- Chord ribbon (harmoniser) ------------------------------------------ */

.ribbon {
	display: flex;
	gap: 8px;
	overflow-x: auto;
	padding-bottom: 4px;
}
.ribbon__cell {
	flex: 1 0 96px;
	text-align: center;
	padding: 12px 8px;
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
}
.ribbon__bar {
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--text-faint);
}
.ribbon__chord {
	font-family: var(--font-display);
	font-size: 21px;
	font-weight: 600;
	color: var(--accent);
}
.ribbon__roman { font-size: 12px; color: var(--text-faint); font-style: italic; }

/* --- Editable note list (transcriber) ----------------------------------- */

.editor { display: grid; gap: 6px; }

.editor__row {
	display: grid;
	grid-template-columns: 34px 1fr auto auto;
	align-items: center;
	gap: 8px;
	padding: 6px 10px;
	background: var(--bg-elevated);
	border: 1px solid var(--line);
	border-radius: var(--radius-sm);
	font-size: 14px;
}
.editor__row.is-rest { color: var(--text-faint); }
.editor__idx { color: var(--text-faint); font-size: 12px; font-variant-numeric: tabular-nums; }
.editor__name { font-family: var(--font-mono); font-size: 15px; }
.editor__len { color: var(--text-faint); font-size: 12px; }
.editor__tools { display: flex; gap: 4px; }
.editor__btn {
	width: 32px; height: 32px;
	display: grid; place-items: center;
	font-size: 13px;
	color: var(--text-muted);
	background: transparent;
	border: 1px solid var(--line);
	border-radius: 6px;
	cursor: pointer;
}
.editor__btn:hover { color: var(--accent); border-color: var(--accent); }
.editor__btn--del:hover { color: var(--red); border-color: var(--red); }

/* Nine buttons will not fit beside a note name on a phone, and a row that
   overflows puts Delete somewhere you cannot reach. Below this width the
   buttons drop onto their own line and wrap. */
@media (max-width: 620px) {
	.editor__row {
		grid-template-columns: 34px 1fr auto;
		row-gap: 6px;
	}
	.editor__tools {
		grid-column: 1 / -1;
		flex-wrap: wrap;
		justify-content: flex-start;
	}
	.editor__btn { width: 40px; height: 38px; }
}

/* --- Landing page cards ------------------------------------------------- */

.cards {
	display: grid;
	grid-template-columns: 1fr;
	gap: 14px;
}

.card {
	position: relative;
	display: block;
	padding: 20px;
	background: var(--surface);
	border: 1px solid var(--line);
	border-left: 3px solid var(--card-accent, var(--accent));
	border-radius: var(--radius);
	color: var(--text);
	box-shadow: var(--shadow);
}
a.card { border-bottom-color: var(--line); }
a.card:hover { background: var(--surface-hover); border-color: var(--card-accent, var(--accent)); }
.card h2 { margin: 0 0 6px; font-size: 19px; }
.card p { margin: 0; font-size: 14px; color: var(--text-muted); }
.card__meta {
	display: inline-block;
	margin-bottom: 8px;
	font-size: 11px;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--card-accent, var(--accent));
}

.lede {
	max-width: 62ch;
	margin: 0 0 26px;
	font-size: 17px;
	color: var(--text-muted);
}

/* --- Footer ------------------------------------------------------------- */

.site-footer {
	margin-top: 34px;
	padding-top: 18px;
	border-top: 1px solid var(--line-soft);
	font-size: 13px;
	color: var(--text-faint);
	text-align: center;
}
.site-footer p { margin: 4px 0; }
.site-footer a { color: var(--text-muted); }

/* --- Wider screens ------------------------------------------------------ */

@media (min-width: 560px) {
	.opts { grid-template-columns: 1fr 1fr; }
	.opts--three { grid-template-columns: repeat(3, 1fr); }
	.fields { grid-template-columns: 1fr 1fr; }
	.cards { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 860px) {
	.wrap { padding: 26px 20px 80px; }
	.fields--wide { grid-template-columns: repeat(3, 1fr); }
	.fields--quad { grid-template-columns: repeat(4, 1fr); }
}

/* --- Print -------------------------------------------------------------- */
/* Printing the page is the quickest route to a paper copy, and it should give
   a clean score rather than a screenshot of a dark interface. */

@media print {
	body { background: #fff; color: #000; }
	.site-header, .transport__buttons, .panel--collapse, .site-footer,
	.bpm, .bpm__slider, form, .status, .level, .tuner { display: none !important; }
	.panel, .panel--score { background: none; border: 0; box-shadow: none; padding: 0; }
	.score { background: none; border: 0; overflow: visible; }
}
