:root {
  color-scheme: dark;
  --bg: #0b0d10;
  --bg-soft: #12161c;
  --panel: rgba(30, 35, 43, 0.74);
  --panel-strong: rgba(42, 48, 58, 0.86);
  --dashboard-frost: rgba(34, 42, 54, 0.68);
  --dashboard-frost-strong: rgba(48, 58, 72, 0.76);
  --line: rgba(255, 255, 255, 0.1);
  --line-strong: rgba(255, 255, 255, 0.18);
  --text: #f4f7fb;
  --muted: #a6afbc;
  --dim: #737d8b;
  --blue: #7bb7ff;
  --cyan: #76e3e2;
  --green: #9be16b;
  --amber: #ffd166;
  --rose: #ff8fa3;
  --shadow: 0 14px 38px rgba(0, 0, 0, 0.28);
  --dashboard-glass-shadow: 0 20px 70px rgba(0, 0, 0, 0.34);
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
  --radius: 8px;
  --dashboard-card-radius: 22px;
  --modal-surface: #0e1116;
  --degrade-strong: 68%;
  --degrade-soft: 34%;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
}

/* No pinch-zoom, no double-tap-zoom. The viewport meta's maximum-scale and
   user-scalable are ignored by iOS Safari on purpose (Apple treats disabling
   zoom as an accessibility violation) — touch-action is what actually works.
   pan-x/pan-y keep ordinary scrolling untouched; only the zoom gestures are
   dropped. touch-action is not inherited, so it goes on every element (not
   just html/body) or a touch starting on some inner div would still zoom. */
html, body, * {
  touch-action: pan-x pan-y;
}

[hidden] {
  display: none !important;
}

body {
  min-width: 320px;
  height: 100vh;
  min-height: 100vh;
  margin: 0;
  overflow: hidden;
  color: var(--text);
  background:
    radial-gradient(ellipse 80% 60% at 85% 10%, rgba(50, 90, 200, 0.18), transparent),
    #07090f;
  letter-spacing: 0;
}

body.level-theme-modern {
  background:
    radial-gradient(circle at 18% 8%, rgba(40, 104, 221, 0.06), transparent 28%),
    linear-gradient(145deg, #060a10 0%, #080e16 48%, #050910 100%);
}

button,
input,
select {
  font: inherit;
}

button {
  color: inherit;
}

.app-shell {
  position: relative;
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  height: 100vh;
  min-height: 100vh;
  overflow: hidden;
}


.sidebar {
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  position: sticky;
  top: 0;
  z-index: 2;
  height: 100vh;
  padding: 24px 18px;
  border-right: 1px solid var(--line);
  background: rgba(14, 17, 22, 0.72);
  backdrop-filter: blur(18px) saturate(1.08);
}

.sidebar-profile-row {
  display: flex;
  align-items: center;
  gap: 4px;
}

.sidebar-profile-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  padding: 10px 12px;
  border-radius: 10px;
  border: none;
  background: transparent;
  cursor: pointer;
  text-align: left;
  transition: background 0.15s;
}

.sidebar-profile-btn:hover {
  background: rgba(255,255,255,0.06);
}

.sidebar-profile-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
}

.sidebar-profile-name {
  font-size: 13px;
  font-weight: 500;
  color: rgba(255,255,255,0.7);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.sidebar-profile-menu-wrap {
  position: relative;
  flex-shrink: 0;
}

.sidebar-dots-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 7px;
  border: none;
  background: transparent;
  color: rgba(255,255,255,0.4);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.sidebar-dots-btn:hover {
  background: rgba(255,255,255,0.08);
  color: rgba(255,255,255,0.8);
}

.sidebar-profile-menu {
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  background: #1e2028;
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 10px;
  padding: 4px;
  min-width: 140px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  z-index: 100;
}

.sidebar-profile-menu button {
  display: block;
  width: 100%;
  padding: 8px 12px;
  border: none;
  background: transparent;
  color: rgba(255,255,255,0.75);
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  border-radius: 7px;
  cursor: pointer;
  transition: background 0.12s;
}

.sidebar-profile-menu button:hover {
  background: rgba(255,255,255,0.07);
  color: #fff;
}

.brand {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 34px;
}

.brand h1 {
  font-family: "Bodoni Moda", "Bodoni 72", Didot, Georgia, serif;
  font-size: 22px;
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1;
}

.brand-mark {
  display: grid;
  width: 28px;
  height: 28px;
  place-items: center;
  border: none;
  border-radius: 6px;
  background: none;
  box-shadow: none;
  overflow: hidden;
  flex-shrink: 0;
}

h1,
h2,
h3,
p {
  margin: 0;
}

h1 {
  font-size: 18px;
  font-weight: 650;
}

h2 {
  margin-top: 2px;
  font-size: 32px;
  font-weight: 680;
}

h3 {
  font-size: 20px;
  font-weight: 640;
}

.eyebrow {
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.nav-list {
  display: grid;
  gap: 10px;
}

.nav-item--mobile-profile { display: none !important; }

.nav-item,
.ghost-button,
.primary-button,
.segmented button,
.close-inspector {
  border: 0;
  cursor: pointer;
}

.nav-item {
  width: 100%;
  padding: 7px 12px;
  border-radius: 12px;
  background: transparent;
  color: var(--muted);
  text-align: left;
  transition: none;
}

.nav-item:hover {
  background: rgba(255, 255, 255, 0.07);
  color: var(--text);
}

.nav-item.active {
  background: rgba(255, 255, 255, 0.12);
  color: white;
  font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09);
}

.nav-item--muted .nav-icon,
.nav-item--muted:hover .nav-icon,
.nav-item--muted.active .nav-icon {
  color: var(--muted) !important;
  opacity: 0.5;
}

.nav-item--muted .nav-label,
.nav-item--muted:hover .nav-label,
.nav-item--muted.active .nav-label {
  color: var(--muted) !important;
  opacity: 0.6;
}

.nav-item--muted.active {
  background: rgba(255, 255, 255, 0.06);
}

.sidebar-bottom {
  position: absolute;
  right: 18px;
  bottom: 22px;
  left: 18px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.sidebar-card {
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.06);
}


.sidebar-card strong {
  display: block;
  margin: 8px 0 2px;
  font-size: 30px;
}

.sidebar-time-unit {
  font-size: 17px;
  font-weight: 500;
  color: var(--muted);
}

#sidebarMonthSessions {
  font-size: 13px;
}

.sidebar-card span,
.muted {
  color: var(--muted);
}

.workspace {
  position: relative;
  z-index: 1;
  display: flex;
  height: 100vh;
  min-height: 0;
  flex-direction: column;
  overflow: hidden;
  padding: 30px;
  transition: padding-right 180ms var(--ease-out);
  background:
    radial-gradient(ellipse 80% 60% at 85% 10%, rgba(50, 90, 200, 0.18), transparent),
    #07090f;
}

.workspace:has(#dashboard.active) {
  background:
    radial-gradient(ellipse 80% 60% at 85% 10%, rgba(50, 90, 200, 0.18), transparent),
    #07090f;
}

.workspace:has(#dashboard.active) #dashboard {
  background: transparent !important;
  box-shadow: none !important;
}

/* Teaching is a different part of the app, so the ground drops darker and the
   blue glow pulls most of the way back. */
.workspace:has(#teaching.active),
.workspace:has(#lessons.active) {
  background:
    radial-gradient(ellipse 80% 60% at 85% 10%, rgba(50, 90, 200, 0.07), transparent),
    #04060b;
  transition: background-color 260ms var(--ease-out);
}

/* The sidebar sits against it, so it follows the same step down. */
.app-shell:has(#teaching.active) .sidebar,
.app-shell:has(#lessons.active) .sidebar {
  background: rgba(10, 12, 17, 0.78);
  transition: background-color 260ms var(--ease-out);
}

.workspace.inspector-open {
  padding-right: 420px;
}

.workspace.practice-active .search {
  display: none;
}

.workspace.practice-active .topbar {
  margin-bottom: 18px;
}

#practice {
  position: relative;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 24px;
}

.topbar-actions {
  display: flex;
  align-items: center;
  column-gap: 10px;
  row-gap: 2px;
}

.topbar-actions.overview-mode .search {
  display: none;
}

/* Config: nothing to search or add. */
.topbar-actions.config-mode .search,
.topbar-actions.config-mode #topbarActionButton {
  display: none;
}

/* Settings and Teaching: nothing to search or add either. */
.topbar-actions.bare-mode .search,
.topbar-actions.bare-mode #topbarActionButton {
  display: none;
}

.search {
  display: flex;
  align-items: center;
  width: min(520px, 46vw);
  height: 42px;
  padding: 0 14px;
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.32);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow:
    inset 0 2px 6px rgba(0, 0, 0, 0.55),
    inset 0 1px 2px rgba(0, 0, 0, 0.4),
    inset 0 -1px 0 rgba(255, 255, 255, 0.07);
}

.round-icon-button {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.32);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow:
    inset 0 2px 6px rgba(0, 0, 0, 0.55),
    inset 0 1px 2px rgba(0, 0, 0, 0.4),
    inset 0 -1px 0 rgba(255, 255, 255, 0.07);
  color: var(--text);
  cursor: pointer;
}

.round-icon-button > span {
  display: grid;
  width: 100%;
  height: 100%;
  place-items: center;
  line-height: 1;
}

.round-icon-button:hover {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.12);
}

.topbar-plus-button {
  font-size: 0;
  font-weight: 400;
}

.topbar-plus-button > span {
  position: relative;
  transform: none;
}

.topbar-plus-button > span::before,
.topbar-plus-button > span::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 2px;
  border-radius: 999px;
  background: currentColor;
  transform: translate(-50%, -50%);
}

.topbar-plus-button > span::after {
  transform: translate(-50%, -50%) rotate(90deg);
}

.topbar-plus-button.settings-mode {
  font-size: 0;
}

.topbar-plus-button.settings-mode > span::before {
  width: 16px;
  height: 16px;
  border: 2px solid currentColor;
  border-radius: 999px;
  background: transparent;
}

.topbar-plus-button.settings-mode > span::after {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: currentColor;
  transform: translate(-50%, -50%);
}

/* The drawn glyph is for phones; desktop keeps the ring-and-handle icon. */
.search .search-glyph {
  display: none;
}

.search-icon {
  position: relative;
  width: 15px;
  height: 15px;
  flex: 0 0 15px;
  border: 2px solid var(--dim);
  border-radius: 999px;
}

.search-icon::after {
  content: "";
  position: absolute;
  right: -5px;
  bottom: -4px;
  width: 7px;
  height: 2px;
  border-radius: 999px;
  background: var(--dim);
  transform: rotate(45deg);
}

.search input {
  width: 100%;
  margin-left: 14px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
}

.view {
  display: none;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
}

.view::-webkit-scrollbar {
  display: none;
}

.view.active {
  display: block;
}

#dashboard,
#dashboard.active {
  background: transparent !important;
  box-shadow: none !important;
}

#dashboard .dashboard-top-row,
#dashboard .dashboard-main-grid,
#dashboard .dashboard-left-column,
#dashboard .dashboard-grid {
  background: transparent !important;
  box-shadow: none !important;
}

#composers,
#composer-detail {
  overflow: hidden;
}

/* Library fills the viewport so the table scrolls inside it (and shows its
   own scrollbar) instead of growing and scrolling the whole page. */
#library.active {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 126px);
  overflow: hidden;
}

#levels.active {
  display: flex;
  height: calc(100vh - 126px);
  min-height: 0;
  flex-direction: column;
  overflow: hidden;
}

#overview.active {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 126px);
  overflow: hidden;
  position: relative;
}

.overview-ticker {
  flex-shrink: 0;
  order: 1;
  height: 40px;
  border-top: 1px solid var(--line);
  overflow: hidden;
  display: flex;
  align-items: center;
  position: relative;
  background: rgba(255, 255, 255, 0.012);
}


@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.ticker-track {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  animation: ticker-scroll 36s linear infinite;
}

.ticker-scroll {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  position: relative;
}

.ticker-scroll::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 60px;
  background: linear-gradient(270deg, var(--bg, #111827) 20%, transparent);
  z-index: 2;
  pointer-events: none;
}

.ticker-label {
  flex-shrink: 0;
  font-size: 9px;
  font-weight: 750;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
  padding: 0 20px 0 18px;
  border-right: 1px solid var(--line);
  opacity: 0.7;
  white-space: nowrap;
}

.ticker-sep {
  color: var(--muted);
  padding: 0 18px;
  opacity: 0.35;
  font-size: 12px;
}

.ticker-item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 28px 0 0;
}

.ticker-dot {
  font-size: 7px;
  line-height: 1;
  opacity: 0.9;
}

.ticker-title {
  font-size: 13px;
  font-weight: 580;
  color: rgba(218, 230, 248, 0.88);
  font-family: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif;
}

.ticker-composer {
  font-size: 12px;
  color: var(--muted);
  font-family: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif;
}

.overview-map {
  flex: 1;
  min-height: 0;
  position: relative;
  overflow: hidden;
  cursor: grab;
  will-change: transform;
}

.overview-map.interacting .star-pulse {
  animation-play-state: paused;
}

.overview-map:active {
  cursor: grabbing;
}

.overview-empty {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: var(--muted);
  font-size: 14px;
  text-align: center;
  max-width: 320px;
  line-height: 1.6;
}

.star-dot {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dot-color);
  box-shadow: 0 0 7px 2px color-mix(in srgb, var(--dot-color) 55%, transparent);
  transform: translate(-50%, -50%);
  cursor: default;
  transition: transform 180ms ease, box-shadow 180ms ease;
  z-index: 1;
}

.star-dot:hover {
  transform: translate(-50%, -50%) scale(2.2);
  box-shadow: 0 0 16px 5px color-mix(in srgb, var(--dot-color) 72%, transparent);
  z-index: 10;
}

@keyframes star-pulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1);   box-shadow: 0 0 7px 2px color-mix(in srgb, var(--dot-color) 55%, transparent); }
  50%       { transform: translate(-50%, -50%) scale(1.6); box-shadow: 0 0 12px 4px color-mix(in srgb, var(--dot-color) 75%, transparent); }
}

.star-pulse {
  animation: star-pulse 2.8s ease-in-out infinite;
}

.star-pulse:hover {
  animation: none;
}

.overview-nebula-count {
  position: absolute;
  bottom: 54px;
  right: 18px;
  font-size: 18px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.55);
  letter-spacing: 0.04em;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 6px;
}

.overview-nebula-count span {
  font-weight: 400;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.3);
  margin-left: 3px;
  pointer-events: none;
}

.nebula-eye-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 2px;
  cursor: pointer;
  color: rgba(255, 255, 255, 0.35);
  opacity: 0;
  transition: opacity 150ms ease, color 150ms ease;
  pointer-events: none;
}

.overview-nebula-count:hover .nebula-eye-btn,
.nebula-eye-btn.is-hidden {
  opacity: 1;
  pointer-events: auto;
}

.nebula-eye-btn:hover {
  color: rgba(255, 255, 255, 0.75);
}

#overviewMap.nebulas-hidden .overview-nebula {
  opacity: 0;
  pointer-events: none;
  transition: opacity 250ms ease;
}

#overviewMap .overview-nebula {
  transition: opacity 250ms ease;
}

.overview-count {
  position: absolute;
  bottom: 84px;
  right: 18px;
  font-size: 18px;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.55);
  letter-spacing: 0.04em;
  pointer-events: none;
  user-select: none;
}

.overview-count span {
  font-weight: 400;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.3);
  margin-left: 3px;
}

.star-card {
  position: absolute;
  bottom: calc(100% + 12px);
  left: 50%;
  transform: translateX(-50%);
  width: 160px;
  padding: 5px 8px 6px;
  background: rgba(14, 20, 34, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  backdrop-filter: blur(16px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
  pointer-events: none;
  opacity: 0;
  transition: opacity 140ms ease;
  white-space: normal;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif;
}

.star-dot:hover .star-card {
  opacity: 1;
}

.star-dot.card-below .star-card {
  bottom: auto;
  top: calc(100% + 12px);
}

.star-card-level {
  font-size: 8px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 2px;
}

.star-card-title {
  font-size: 9px;
  font-weight: 600;
  color: rgba(228, 238, 252, 0.96);
  line-height: 1.3;
  margin-bottom: 1px;
}

.star-card-composer {
  font-size: 9px;
  color: var(--muted);
}

.overview-nebula {
  position: absolute;
  transform: translate(-50%, -50%);
  cursor: default;
  z-index: 0;
}

.overview-nebula:hover {
  z-index: 10;
}

.nebula-glow {
  filter: blur(14px);
  opacity: 0.5;
  transition: opacity 300ms ease, filter 300ms ease, transform 300ms ease;
  transform-origin: center;
}

.overview-nebula:hover .nebula-glow {
  opacity: 0.82;
  filter: blur(9px);
  transform: scale(1.1);
}

.nebula-card {
  position: absolute;
  bottom: calc(100% + 12px);
  left: 50%;
  transform: translateX(-50%);
  width: 180px;
  padding: 8px 12px 9px;
  background: rgba(14, 20, 34, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  backdrop-filter: blur(16px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
  pointer-events: none;
  opacity: 0;
  transition: opacity 140ms ease;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif;
  white-space: normal;
}

.nebula-card-below {
  bottom: auto;
  top: calc(100% + 10px);
}

.overview-nebula:hover .nebula-card {
  opacity: 1;
}

.nebula-card-title {
  font-size: 13px;
  font-weight: 600;
  color: rgba(228, 238, 252, 0.96);
  margin-bottom: 3px;
}

.nebula-card-count {
  font-size: 11px;
  color: var(--muted);
}

#composer-detail {
  position: relative;
  grid-template-rows: auto auto auto minmax(0, 1fr);
  height: calc(100vh - 126px);
  min-height: 0;
  overflow: hidden;
  isolation: isolate;
}

#composer-detail.active {
  display: grid;
}

#composer-detail > :not(.composer-detail-portrait) {
  position: relative;
  z-index: 1;
}

.composer-detail-portrait {
  position: fixed;
  right: -28px;
  bottom: -70px;
  z-index: 0;
  width: min(390px, 26vw);
  height: min(59vh, 570px);
  object-fit: cover;
  object-position: right bottom;
  opacity: 0.16;
  pointer-events: none;
  user-select: none;
  filter: grayscale(1) contrast(1.06) brightness(1.08);
  transition: opacity 220ms var(--ease-out), filter 220ms var(--ease-out);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.82) 26%, #000 100%);
  mask-image: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.82) 26%, #000 100%);
}

#composer-detail.portrait-subdued .composer-detail-portrait {
  opacity: 0.075;
  filter: grayscale(1) contrast(0.98) brightness(0.92);
}

@keyframes viewIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.dashboard-top-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 0.38fr);
  gap: 16px;
}

.hero-panel,
.most-played-card,
.panel,
.metric-card {
  border: 0;
  border-radius: var(--dashboard-card-radius);
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: var(--dashboard-glass-shadow);
}

.hero-panel {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  min-height: 164px;
  padding: 24px;
  overflow: hidden;
}

.daily-quote-layout {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  align-items: start;
  gap: 28px;
  flex: 1;
  min-width: 0;
}

.daily-quote-icon {
  width: 44px;
  height: 44px;
  margin-top: 8px;
  color: #5aa9ff;
  opacity: 0.92;
  filter: drop-shadow(0 0 16px rgba(55, 140, 255, 0.24));
}

.daily-quote-icon path {
  fill: currentColor;
}

.hero-panel h3 {
  margin-top: 12px;
  font-size: 28px;
  line-height: 1.2;
  display: -webkit-box;
  max-width: none;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  padding-bottom: 4px;
}

.daily-quote-author {
  margin-top: 12px;
  color: var(--muted);
  font-size: 14px;
  font-weight: 700;
}

.daily-quote-author:not(:empty)::before {
  content: "- ";
}

.most-played-card {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 164px;
  overflow: hidden;
  padding: 24px;
  cursor: pointer;
}

.most-played-copy {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 10px;
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
}

.dashboard-card-label,
.most-played-label {
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.most-played-card strong {
  display: block;
  padding-right: 76px;
  font-family: Georgia, "Times New Roman", ui-serif, serif;
  font-size: 34px;
  font-weight: 600;
  line-height: 1.05;
}

.most-played-copy > span {
  display: block;
  color: var(--muted);
  font-size: 13px;
  font-weight: 650;
}

.most-played-portrait {
  position: absolute;
  right: -18px;
  top: 0;
  width: 142px;
  height: 164px;
  object-fit: cover;
  object-position: right bottom;
  opacity: 0.16;
  pointer-events: none;
  user-select: none;
  filter: grayscale(1) contrast(1.06) brightness(1.08);
  transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out);
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.82) 28%, #000 100%);
  mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.82) 28%, #000 100%);
}

.most-played-card.rotating .most-played-copy {
  opacity: 0;
  transform: translateY(6px);
}

.most-played-card.rotating .most-played-portrait {
  opacity: 0.04;
  transform: translateX(10px);
}

.metric-card p,
.piece-meta,
.practice-row span {
  color: var(--muted);
  font-size: 13px;
}

.piece-source {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 13px;
  overflow: visible;
}

.piece-meta strong {
  color: inherit;
  font-weight: 760;
}

.dashboard-main-grid {
  display: grid;
  grid-template-columns: 1.45fr 1fr;
  gap: 16px;
  margin: 16px 0 0;
  align-items: stretch;
}

.dashboard-left-column {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: 16px;
  min-width: 0;
}

.dashboard-right-column {
  display: grid;
  /* Timer, then Metronome and Perfect Practice at the same fixed width. */
  grid-template-columns: 1fr 164px 164px;
  grid-template-rows: minmax(0, 1fr) 164px;
  gap: 16px;
  min-width: 0;
}

.dashboard-right-column .completed-pieces-panel {
  grid-column: 1 / -1;
}

.dashboard-tools-row {
  display: contents;
}

.perfect-practice-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 8px;
  text-align: center;
}

.pp-modal-header {
  padding: 28px 32px 0;
}

.pp-modal-title {
  font-size: 32px;
  font-weight: 680;
}

@keyframes pp-expand {
  from { opacity: 0; transform: scale(0.08); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes pp-collapse {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(0.08); }
}

.pp-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0);
  transition: background 280ms ease;
}

.pp-modal-backdrop.open {
  background: rgba(0, 0, 0, 0.55);
}

.pp-modal-backdrop[hidden] {
  display: none;
}

.pp-modal-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 580px;
  height: 580px;
  transform-origin: var(--pp-ox, 50%) var(--pp-oy, 50%);
  transform: scale(0.08);
  opacity: 0;
  will-change: transform, opacity;
}

.pp-modal-inner.pp-entering {
  animation: pp-expand 320ms cubic-bezier(0.34, 1.4, 0.64, 1) forwards;
}

.pp-modal-inner.pp-leaving {
  animation: pp-collapse 200ms cubic-bezier(0.4, 0, 1, 1) forwards;
}

.pp-modal-inner .close-inspector.modal-close-pill {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.055);
  color: var(--muted);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition: border-color 150ms var(--ease-out), background 150ms var(--ease-out), color 150ms var(--ease-out);
}
.pp-modal-inner .close-inspector.modal-close-pill:hover {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.09);
  color: var(--text);
}
.pp-modal-inner .close-inspector.modal-close-pill::before,
.pp-modal-inner .close-inspector.modal-close-pill::after {
  left: 12px;
  top: 18px;
  width: 14px;
}

/* ── Metronome modal ─────────────────────────────────────────────────────
   The dial: a 300-degree ring from 40 bpm (lower left) over the top to
   220 bpm (lower right), grey track, blue fill up to the tempo, and the
   tempo in the middle. The knob only shows while the ring is being dragged. */
/* Beat lights: fill the room above the dial. The current beat is blue with
   a quick pulse; the rest stay grey. */
/* Dots and dial sit together in the middle of the modal. */
.metronome-top {
  width: 100%;
  box-sizing: border-box;
  margin: auto 0 20px;
  padding: 14px 16px 0;
}

/* Always one row: up to 12 dots, shrinking (with tighter gaps, set from
   the count in JS) when the row would be too wide. By ID, so the phone
   rule capping everything in .workspace at 100% does not win. */
#metronomeBeats {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: center;
  /* Gaps also tighten on narrow screens, so the dots keep their size. */
  --dot: 26px;
  --gap: min(var(--beat-gap, 20px), 2.6vw);
  gap: var(--gap);
  width: 100%;
  /* Fixed: smaller dots must not shorten the row and shift the dial. */
  height: var(--dot);
  max-width: calc(var(--beats, 4) * var(--dot) + (var(--beats, 4) - 1) * var(--gap));
  margin: 0 auto;
}

/* Bottom row under the dial: Tap, the beats editor, Play. */
.metronome-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: -4px;
}

/* The pencil and the editor share one spot; the editor grows out of the
   pencil (a pill unclipping from the centre) and shrinks back into it. */
.metronome-edit-slot {
  display: grid;
  place-items: center;
  flex: 1;
  min-width: 0;
  height: 54px;
}

.metronome-edit-slot > * {
  grid-area: 1 / 1;
}

.metronome-edit {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: var(--muted);
  cursor: pointer;
  transition: opacity 180ms ease, transform 300ms cubic-bezier(0.32, 0.72, 0, 1), background 150ms var(--ease-out), color 150ms var(--ease-out);
}

.metronome-edit:hover {
  background: rgba(255, 255, 255, 0.14);
  color: var(--text);
}

.metronome-edit-slot.is-editing .metronome-edit {
  opacity: 0;
  transform: scale(0.6);
  pointer-events: none;
}

.metronome-beats-editor {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  clip-path: inset(0 calc(50% - 20px) round 999px);
  opacity: 0;
  pointer-events: none;
  transition: clip-path 320ms cubic-bezier(0.32, 0.72, 0, 1), opacity 200ms ease;
}

.metronome-edit-slot.is-editing .metronome-beats-editor {
  clip-path: inset(0 0 round 999px);
  opacity: 1;
  pointer-events: auto;
}

.metronome-beats-editor > * {
  opacity: 0;
  transition: opacity 140ms ease;
}

.metronome-edit-slot.is-editing .metronome-beats-editor > * {
  opacity: 1;
  transition: opacity 200ms ease 90ms;
}

.metronome-step {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  font-size: 20px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
}

.metronome-step:disabled {
  opacity: 0.35 !important;
  cursor: default;
}

.metronome-beats-count {
  min-width: 64px;
  color: var(--text);
  font-size: 15px;
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* Each dot is a button: tap to make it an accent (bigger; lights white). */
.metronome-beat {
  --beat-scale: 1;
  position: relative;
  flex: 0 1 var(--dot, 26px);
  min-width: 0;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  cursor: pointer;
  transform: scale(var(--beat-scale));
  -webkit-tap-highlight-color: transparent;
  transition: transform 260ms cubic-bezier(0.34, 1.4, 0.64, 1), background 220ms ease-out, box-shadow 220ms ease-out;
}

/* A bigger hit area than the dot itself. */
.metronome-beat::after {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
}

.metronome-beat.is-accent {
  --beat-scale: 1.4;
  background: rgba(255, 255, 255, 0.18);
}

.metronome-beat.is-on {
  background: #5aa9ff;
  box-shadow: 0 0 18px rgba(90, 169, 255, 0.55);
  transition: transform 260ms cubic-bezier(0.34, 1.4, 0.64, 1), background 40ms linear, box-shadow 40ms linear;
  animation: metronome-beat-pulse 200ms cubic-bezier(0.2, 0.9, 0.3, 1);
}

.metronome-beat.is-accent.is-on {
  background: #fff;
  box-shadow: 0 0 22px rgba(255, 255, 255, 0.6);
}

@keyframes metronome-beat-pulse {
  0% { transform: scale(var(--beat-scale)); }
  30% { transform: scale(calc(var(--beat-scale) * 1.35)); }
  100% { transform: scale(var(--beat-scale)); }
}

/* Sat a little above the middle of the modal. */
.metronome-stage {
  position: relative;
  flex: 0 0 auto;
  width: min(316px, 100%);
  margin: 0 auto auto;
  padding-bottom: 26px;
}

.metronome-play,
.metronome-tap {
  flex: 0 0 54px;
}

.metronome-tap {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: var(--muted);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out);
}

.metronome-tap:hover {
  background: rgba(255, 255, 255, 0.14);
  color: var(--text);
}

.metronome-tap.is-tapped {
  animation: metronome-tap-pulse 220ms var(--ease-out);
}

@keyframes metronome-tap-pulse {
  0% { transform: scale(0.88); background: rgba(90, 169, 255, 0.3); color: #5aa9ff; }
  100% { transform: scale(1); }
}

.metronome-dial {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 1;
  outline: none;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  cursor: pointer;
}

.metronome-dial-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.metronome-dial-track,
.metronome-dial-fill {
  fill: none;
  stroke-width: 14;
  stroke-linecap: round;
}

.metronome-dial-track {
  stroke: rgba(255, 255, 255, 0.08);
}

.metronome-dial-fill {
  stroke: #5aa9ff;
}

.metronome-dial-knob {
  fill: #fff;
  opacity: 0;
  transform: scale(0.4);
  transform-box: fill-box;
  transform-origin: center;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.45));
  transition: opacity 180ms var(--ease-out), transform 220ms cubic-bezier(0.34, 1.4, 0.64, 1);
  pointer-events: none;
}

.metronome-dial.is-dragging .metronome-dial-knob {
  opacity: 1;
  transform: scale(1);
}

/* The tempo marking, curved through the gap at the bottom of the ring. */
.metronome-marking {
  fill: var(--muted);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.metronome-readout {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  pointer-events: none;
}

.metronome-bpm {
  color: var(--text);
  font-size: 84px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

.metronome-bpm-unit {
  margin-top: 6px;
  color: var(--muted);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.06em;
}

.pp-reps-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: 40px 32px 0;
}

.pp-reps-count {
  font-size: 72px;
  font-weight: 700;
  line-height: 1;
  min-width: 80px;
  text-align: center;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.pp-reps-btn {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.055);
  color: #ffffff;
  cursor: pointer;
  flex-shrink: 0;
  transition: border-color 150ms var(--ease-out), background 150ms var(--ease-out), color 150ms var(--ease-out), transform 150ms var(--ease-out);
}

.pp-reps-btn:hover {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.09);
  color: #ffffff;
  transform: scale(1.08);
}

.pp-reps-btn:active {
  transform: scale(0.93);
}

.pp-reset-row {
  display: flex;
  justify-content: center;
  padding: 0 32px 24px;
}

.pp-reset-btn {
  height: 52px;
  padding: 0 48px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-size: 17px;
  font-weight: 650;
  cursor: pointer;
  transition: border-color 150ms var(--ease-out), background 150ms var(--ease-out), color 150ms var(--ease-out);
}

.pp-reset-btn:disabled {
  opacity: 0.3;
  cursor: default;
}

.pp-reset-btn:hover {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
}

@keyframes pp-reset-breathe {
  0%, 100% { transform: scale(1); }
  50%       { transform: scale(1.07); }
}

.pp-reset-btn.pp-reset-complete {
  border-color: rgba(60, 200, 110, 0.7);
  background: rgba(60, 200, 110, 0.18);
  color: #5ce89a;
  animation: pp-reset-breathe 2s ease-in-out infinite;
}

.pp-action-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 60px 28px 40px;
  flex: 1;
}

.pp-bars-section {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  flex: 1;
  align-self: stretch;
}

.pp-action-btn {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 1px solid;
  cursor: pointer;
  transition: transform 150ms var(--ease-out), background 150ms var(--ease-out), filter 150ms var(--ease-out);
}

.pp-action-btn:hover {
  transform: scale(1.08);
  filter: brightness(1.15);
}

.pp-action-btn:active {
  transform: scale(0.93);
}

.pp-action-fail {
  border-color: rgba(255, 90, 80, 0.6);
  background: rgba(255, 90, 80, 0.18);
  color: #ff8077;
}

.pp-action-pass {
  border-color: rgba(60, 200, 110, 0.6);
  background: rgba(60, 200, 110, 0.18);
  color: #5ce89a;
}

.pp-bar {
  flex: 1;
  max-width: 20px;
  height: 80px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  transition: background 200ms var(--ease-out);
}

.pp-bar.pp-bar-filled {
  background: var(--blue, #2d83ff);
  box-shadow: 0 0 12px rgba(45, 131, 255, 0.45);
}

@keyframes pp-bar-fadeout-partial {
  0%   { background: var(--blue, #2d83ff); box-shadow: 0 0 12px rgba(45, 131, 255, 0.45); }
  100% { background: rgba(255, 255, 255, 0.14); box-shadow: none; }
}

@keyframes pp-bar-active-fadeout {
  0%   { background: var(--blue, #2d83ff); box-shadow: 0 0 14px rgba(45, 131, 255, 0.5); height: 106px; max-width: 26px; }
  100% { background: rgba(255, 255, 255, 0.14); box-shadow: none; height: 80px; max-width: 20px; }
}

.pp-bar.pp-bar-fadeout-partial {
  animation: pp-bar-fadeout-partial 380ms ease-out both;
}

.pp-bar.pp-bar-active-fadeout {
  animation: pp-bar-active-fadeout 380ms ease-out both;
}

@keyframes pp-bar-fadeout-complete {
  0%   { background: #3cd878; box-shadow: 0 0 14px rgba(60, 200, 100, 0.45); }
  100% { background: rgba(255, 255, 255, 0.14); box-shadow: none; }
}

.pp-bar.pp-bar-fadeout {
  animation: pp-bar-fadeout 320ms ease-out both;
}

.pp-bar.pp-bar-fadeout-complete {
  animation: pp-bar-fadeout-complete 380ms ease-out both;
}

@keyframes pp-bar-green {
  0%   { background: var(--blue, #2d83ff); box-shadow: 0 0 12px rgba(45, 131, 255, 0.45); transform: scaleY(1); }
  45%  { background: #5cf09a; box-shadow: 0 0 22px rgba(60, 220, 120, 0.7); transform: scaleY(1.12); }
  100% { background: #3cd878; box-shadow: 0 0 14px rgba(60, 200, 100, 0.45); transform: scaleY(1); }
}

.pp-bar.pp-bar-complete {
  animation: pp-bar-green 320ms cubic-bezier(0.34, 1.4, 0.64, 1) both;
  height: 80px;
  max-width: 20px;
}

@keyframes pp-bar-fill {
  0%   { background: rgba(255, 255, 255, 0.14); transform: scaleY(0.75); box-shadow: none; }
  55%  { background: #7ec8ff; transform: scaleY(1.08); box-shadow: 0 0 22px rgba(100, 180, 255, 0.8); }
  100% { background: var(--blue, #2d83ff); transform: scaleY(1); box-shadow: 0 0 14px rgba(45, 131, 255, 0.5); }
}

.pp-bar.pp-bar-active {
  height: 106px;
  max-width: 26px;
  background: var(--blue, #2d83ff);
  box-shadow: 0 0 14px rgba(45, 131, 255, 0.5);
  transform-origin: center;
  animation: pp-bar-fill 380ms cubic-bezier(0.34, 1.4, 0.64, 1) both;
}

/* Metronome glyph: drawn from the same bold, rounded strokes as the
   Perfect Practice bars, in the same blue and at the same height. */
.metronome-icon {
  display: block;
  /* 44px box: the drawn glyph comes out ~32px tall, the bars' height. */
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  color: #2d83ff;
}

.perfect-practice-lines {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-shrink: 0;
  /* Same 44px slot as the metronome icon beside it, so the two cards'
     titles and Start buttons line up. */
  height: 44px;
}

.perfect-practice-lines span {
  display: block;
  width: 6px;
  height: 32px;
  background: #2d83ff;
  border-radius: 999px;
}

.perfect-practice-card .eyebrow {
  margin: 0;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.perfect-practice-toggle {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  color: var(--dim);
  transition: color 150ms ease, transform 120ms ease;
}

.perfect-practice-toggle:hover {
  color: var(--muted);
  transform: scale(1.08);
}

.perfect-practice-toggle[aria-pressed="true"] {
  color: #4ade80;
}

.perfect-practice-icon {
  width: 64px;
  height: 64px;
  display: block;
}

.perfect-practice-label {
  font-size: 11px;
  color: var(--dim);
  font-weight: 500;
}

.perfect-practice-start {
  margin-top: 6px;
  height: 34px;
  padding: 0 20px;
  background: rgba(0, 80, 200, 0.28);
  border: 0;
  border-radius: 999px;
  color: var(--blue);
  font-size: 13px;
  font-weight: 750;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out), transform 150ms var(--ease-out), box-shadow 150ms var(--ease-out);
}

.perfect-practice-start:hover {
  background: rgba(0, 80, 200, 0.42);
  color: #a8cfff;
  transform: scale(1.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 8px 20px rgba(0, 0, 0, 0.16);
}

.dashboard-extra-card {
  min-height: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0;
  padding: 18px 20px;
}

.today-log-left {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
}

.today-stopwatch {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex: 1;
}

/* Timer: clock (with the goal bar under it), then the play/pause and reset
   pair stacked, then Log. */
.timer-main {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 22px;
  max-width: 100%;
}

.timer-readout {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.timer-goal {
  display: flex;
  align-items: center;
  gap: 10px;
}

.timer-goal-track {
  flex: 1;
  height: 6px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
}

.timer-goal-fill {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--blue);
  transition: width 600ms var(--ease-out), background 300ms var(--ease-out);
}

.timer-goal-fill.is-done {
  background: #5de896;
}

.timer-goal-label {
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

/* Log over Reset, one width. */
.timer-side-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 84px;
}

.timer-side-buttons .stopwatch-btn {
  width: 100%;
  padding: 0;
}

.timer-round {
  display: grid;
  place-items: center;
  /* Never shrinks: as a flex item it used to give up width when the row got
     tight, which squashed the circle into an oval on phones. */
  flex: 0 0 54px;
  width: 54px;
  height: 54px;
  padding: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: background 150ms var(--ease-out), transform 150ms var(--ease-out);
}

.timer-round:hover {
  transform: scale(1.08);
}

/* The lighter blue of the Quote of the Day mark. */
.timer-round--play {
  border: 2px solid #5aa9ff;
  background: rgba(90, 169, 255, 0.12);
  color: #5aa9ff;
}

.timer-round--play:hover {
  background: rgba(90, 169, 255, 0.22);
}

/* Play until it runs, then pause. */
.timer-round--play .timer-icon-pause,
.timer-round--play.is-running .timer-icon-play {
  display: none;
}

.timer-round--play.is-running .timer-icon-pause {
  display: block;
}

.stopwatch-display {
  font-size: 52px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  letter-spacing: 0.02em;
}

.stopwatch-controls {
  display: flex;
  gap: 6px;
}

.stopwatch-btn {
  height: 34px;
  padding: 0 16px;
  background: rgba(255, 255, 255, 0.08);
  border: 0;
  border-radius: 999px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 750;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out), transform 150ms var(--ease-out), box-shadow 150ms var(--ease-out);
}

.stopwatch-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.12);
  color: var(--text);
  transform: scale(1.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 8px 20px rgba(0, 0, 0, 0.16);
}

.stopwatch-btn:disabled {
  opacity: 0.35;
  cursor: default;
}

.stopwatch-register {
  background: rgba(0, 80, 200, 0.28);
  color: var(--blue);
}

.stopwatch-register:hover:not(:disabled) {
  background: rgba(0, 80, 200, 0.42);
  color: #a8cfff;
}

.dashboard-extra-card .eyebrow {
  margin: 0;
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.today-log-date {
  margin: 0;
  font-size: 12px;
  color: var(--muted);
}

.today-log-total {
  margin: 0 0 6px;
  font-size: 22px;
  font-weight: 700;
  color: var(--blue);
}

.today-log-form {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 2px;
}

.today-log-inputs {
  display: flex;
  align-items: center;
  gap: 6px;
}

.today-log-field {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  color: var(--muted);
}

.today-log-input {
  min-width: 52px;
  height: 34px;
  padding: 0 14px;
  background: rgba(0, 0, 0, 0.32);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 999px;
  color: var(--text);
  font-size: 13px;
  font-weight: 750;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  line-height: 34px;
  cursor: text;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: inset 0 2px 6px rgba(0,0,0,0.55), inset 0 1px 2px rgba(0,0,0,0.4), inset 0 -1px 0 rgba(255,255,255,0.07);
}

.today-log-input:empty::before {
  content: attr(data-placeholder);
  color: var(--muted);
}

.today-log-input:focus {
  outline: none;
  border-color: rgba(123, 183, 255, 0.45);
}

.today-log-save {
  height: 34px;
  padding: 0 16px;
  background: rgba(0, 80, 200, 0.28);
  border: 0;
  border-radius: 999px;
  color: var(--blue);
  font-size: 13px;
  font-weight: 750;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out), transform 150ms var(--ease-out), box-shadow 150ms var(--ease-out);
}

.today-log-save:hover {
  background: rgba(0, 80, 200, 0.42);
  color: #a8cfff;
  transform: scale(1.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 8px 20px rgba(0, 0, 0, 0.16);
}

.dashboard-grid {
  display: flex;
  gap: 14px;
}

.dashboard-grid .metric-card {
  flex: 1;
}

.dashboard-grid .metric-card.assigned,
.dashboard-grid .metric-card.working {
  flex: 0.6;
}


.metric-card {
  position: relative;
  display: flex;
  min-height: 96px;
  align-items: end;
  justify-content: space-between;
  gap: 16px;
  padding: 16px;
  transition: transform 150ms var(--ease-out), border-color 150ms var(--ease-out), background 150ms var(--ease-out);
  will-change: transform;
}

[data-dashboard-list-stage] {
  cursor: pointer;
}

.metric-card.mastery-dash-card {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 20px;
  padding: 16px 20px;
  cursor: pointer;
  animation: none !important;
  transition: transform 150ms ease-out, background 150ms ease-out !important;
  will-change: transform;
}

.metric-card.mastery-dash-card:hover {
  transform: scale(1.02);
  background: rgba(255, 255, 255, 0.07);
}

.mastery-dash-chevron {
  margin-left: auto;
  color: var(--muted);
  flex-shrink: 0;
}


.mastery-dash-badge {
  width: 80px;
  height: 80px;
  object-fit: contain;
}

.mastery-dash-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.mastery-dash-label {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--muted);
  text-transform: uppercase;
}

.mastery-dash-tier {
  font-size: 12px !important;
  font-weight: 600 !important;
  letter-spacing: 0.22em !important;
  text-transform: uppercase !important;
  color: var(--muted) !important;
}

.mastery-dash-rings {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-left: 16px;
}

.mastery-dash-mini-ring {
  position: relative;
  width: 72px;
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mastery-dash-mini-ring svg {
  position: absolute;
  inset: 0;
}

.mastery-dash-mini-label {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
}

.mastery-dash-mini-val {
  font-size: 14px !important;
  font-weight: 700 !important;
  letter-spacing: normal !important;
  text-transform: none !important;
  color: var(--text) !important;
  line-height: 1;
}

.mastery-dash-mini-sub {
  font-size: 10px !important;
  font-weight: 500 !important;
  color: var(--muted) !important;
  text-transform: uppercase !important;
  letter-spacing: 0.05em !important;
  line-height: 1;
}

.mastery-dash-card .mastery-dash-name {
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 28px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: normal;
  text-transform: none;
}

.mastery-dash-xp {
  font-size: 13px;
  color: var(--muted);
}

.mastery-dash-next {
  font-size: 11px;
  color: var(--blue);
  opacity: 0.8;
}

/* Placeholder slot left where the removed "Ready" metric card used to sit. */
.metric-card.placeholder {
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.012);
  box-shadow: none;
  cursor: default;
  pointer-events: none;
}

.metric-card-label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.metric-card-chevron {
  width: 13px;
  height: 13px;
  color: var(--muted);
  opacity: 0.6;
  flex-shrink: 0;
}

.metric-card:not(.mastery-dash-card):hover {
  transform: scale(1.02);
  background: rgba(255, 255, 255, 0.07);
}

.metric-card.dashboard-list-active {
  border-color: rgba(123, 183, 255, 0.4) !important;
  background: rgba(123, 183, 255, 0.08) !important;
}

#dashboardListTitle.dashboard-list-active {
  cursor: default;
}

.metric-card span {
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.metric-card strong {
  order: 2;
  font-size: 42px;
  line-height: 0.86;
}

.metric-card p {
  display: none;
}

.recorded strong {
  color: #edf6ff;
}

.ready strong {
  color: var(--green);
}

.working strong {
  color: var(--amber);
}

.assigned strong {
  color: var(--blue);
}

.panel {
  padding: 18px;
}

.panel.full {
  min-height: 620px;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}

.panel-title-with-count {
  display: inline-flex;
  align-items: baseline;
  gap: 12px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.panel-title-with-count .panel-count {
  display: inline-block;
  color: var(--stage-color, var(--amber));
  font-size: 42px;
  font-weight: 700;
  line-height: 1;
}

.panel-title-with-count .panel-count-label {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.completed-pieces-panel {
  display: flex;
  min-width: 0;
  flex-direction: column;
}

.workspace:has(#dashboard.active) .hero-panel,
.workspace:has(#dashboard.active) .most-played-card,
.workspace:has(#dashboard.active) .metric-card,
.workspace:has(#dashboard.active) .panel {
  background: rgba(255, 255, 255, 0.04) !important;
  backdrop-filter: blur(20px) !important;
  -webkit-backdrop-filter: blur(20px) !important;
  border: 0 !important;
  box-shadow: none !important;
}

body.wallpaper-light .workspace:has(#dashboard.active) .hero-panel,
body.wallpaper-light .workspace:has(#dashboard.active) .most-played-card,
body.wallpaper-light .workspace:has(#dashboard.active) .metric-card,
body.wallpaper-light .workspace:has(#dashboard.active) .panel {
  background: rgba(0, 0, 0, 0.38) !important;
  backdrop-filter: blur(60px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(60px) saturate(140%) !important;
  border: 0 !important;
}

.workspace:has(#dashboard.active) .metric-card:not(.mastery-dash-card):hover {
  transform: scale(1.02);
  background: rgba(255, 255, 255, 0.07);
}

.completed-pieces-title {
  display: inline-flex;
  align-items: baseline;
  gap: 12px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.completed-pieces-title span {
  color: #edf6ff;
  font-size: 42px;
  font-weight: 700;
  line-height: 1;
}

.ghost-button,
.primary-button {
  height: 34px;
  padding: 0 16px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
}

.primary-button {
  background: rgba(123, 183, 255, 0.22);
  color: #dcecff;
}

/* Pieces panel head: the count and "Pieces", then the Working/Assigned
   selector beside them. */
.dashboard-list-head {
  display: flex;
  align-items: center;
  gap: 20px;
  min-width: 0;
}

.dashboard-list-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

.dashboard-list-pager {
  display: flex;
  align-items: stretch;
  height: 34px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  overflow: hidden;
}

.dashboard-list-prev,
.dashboard-list-next {
  display: grid;
  place-items: center;
  width: 36px;
  height: 100%;
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  transition: background 150ms, color 150ms, transform 150ms;
}

.dashboard-list-prev:hover:not(:disabled),
.dashboard-list-next:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  transform: scale(1.08);
}

.dashboard-list-prev:disabled,
.dashboard-list-next:disabled {
  opacity: 0.3;
  cursor: default;
}

.dashboard-list-divider {
  width: 1px;
  background: rgba(255, 255, 255, 0.15);
  align-self: center;
  height: 20px;
}

.dashboard-piece-list {
  min-height: calc(5 * 72px + 4 * 9px);
  overflow: hidden;
}

.dashboard-list-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 44px 20px 40px;
  text-align: center;
  margin: 0;
}

/* A soft disc behind the glyph, so the state reads as considered rather than
   as something missing. */
.dashboard-list-empty-icon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin-bottom: 16px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.045);
  color: rgba(255, 255, 255, 0.32);
}

.dashboard-list-empty-title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.62);
  letter-spacing: -0.01em;
}

.dashboard-list-empty-sub {
  margin: 6px 0 0;
  max-width: 290px;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.3);
}


.dashboard-page-dots {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 6px;
  padding-top: 14px;
}

.dashboard-page-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.25);
  transition: background 200ms, width 200ms cubic-bezier(0.34, 1.3, 0.64, 1);
}

.dashboard-page-dot.active {
  background: rgba(255, 255, 255, 0.9);
  width: 18px;
}

@keyframes metric-card-in {
  from { opacity: 0; transform: translateY(8px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.metric-swap-anim .metric-card:not(.placeholder) {
  animation: metric-card-in 0.24s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

@keyframes dash-page-in-next {
  from { opacity: 0; transform: translateX(28px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes dash-page-in-prev {
  from { opacity: 0; transform: translateX(-28px); }
  to   { opacity: 1; transform: translateX(0); }
}

.dashboard-piece-list.anim-next {
  animation: dash-page-in-next 0.22s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.dashboard-piece-list.anim-prev {
  animation: dash-page-in-prev 0.22s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.piece-row-placeholder {
  height: 72px;
  border-radius: var(--radius);
  background: transparent;
  pointer-events: none;
}

.dashboard-view-all-button {
  height: 34px;
  border: none;
  background: rgba(255, 255, 255, 0.055);
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 750;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition: background 150ms var(--ease-out), border-color 150ms var(--ease-out), color 150ms var(--ease-out), transform 150ms var(--ease-out), box-shadow 150ms var(--ease-out);
}

.dashboard-view-all-button:hover {
  background: rgba(255, 255, 255, 0.12);
  color: var(--text);
  transform: scale(1.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 8px 20px rgba(0, 0, 0, 0.16);
}

.piece-map-button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 190px;
  height: 54px;
  overflow: hidden;
  padding: 0 18px;
  border: 1px solid rgba(123, 183, 255, 0.18);
  border-radius: 999px;
  background: linear-gradient(135deg, rgba(8, 19, 43, 0.98), rgba(12, 43, 96, 0.92) 54%, rgba(5, 17, 42, 0.98));
  color: #dcecff;
  cursor: pointer;
  font-size: 14px;
  font-weight: 750;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: inset 0 1px 0 rgba(123, 183, 255, 0.12), inset 0 -1px 0 rgba(0,0,0,0.3), 0 8px 24px rgba(6, 18, 42, 0.24);
  transition: color 150ms var(--ease-out), transform 150ms var(--ease-out), box-shadow 150ms var(--ease-out), border-color 150ms var(--ease-out);
}

.piece-map-button span,
.piece-map-button svg {
  position: relative;
  z-index: 1;
}

.piece-map-button svg {
  width: 16px;
  height: 16px;
}

.piece-map-button path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.piece-map-button::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 0%, rgba(123, 183, 255, 0.18) 46%, transparent 74%);
  opacity: 0.58;
  pointer-events: none;
  transform: translateX(-72%);
  animation: pieceMapGlow 3.8s ease-in-out infinite;
}

.piece-map-button:hover {
  color: #f4f9ff;
  transform: scale(1.08);
  box-shadow: 0 10px 28px rgba(10, 40, 96, 0.34);
}

@keyframes pieceMapGlow {
  0%,
  18% {
    opacity: 0;
    transform: translateX(-72%);
  }
  42% {
    opacity: 0.58;
  }
  74%,
  100% {
    opacity: 0;
    transform: translateX(72%);
  }
}

.piece-list,
.accordion,
.practice-list {
  display: grid;
  gap: 9px;
}

.composer-piece-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding-right: 0;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.composer-piece-list {
  align-content: start;
}

.composer-piece-list::-webkit-scrollbar {
  display: none;
}

#composers {
  height: calc(100vh - 126px);
  min-height: 0;
  overflow: hidden;
}

#composers.bars-view {
  overflow: hidden;
}

.pieces-view-toggle .composer-sort-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 13px;
}

.pieces-view-toggle .composer-sort-toggle svg {
  display: block;
  width: 19px;
  height: 19px;
}

/* Stage filter & Sort by Recent don't apply in workflow view. */
#levels.workflow-active #stageFilterPills,
#levels.workflow-active #recentSortToggle {
  display: none;
}

/* === Workflow (kanban) view === */
.pieces-workflow {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: minmax(0, 1fr);
  gap: 14px;
  /* Fill the fixed-height #levels area; columns size to their content but cap
     at the available height (align-items: start) and scroll independently. */
  align-items: start;
  flex: 1;
  min-height: 0;
  margin-top: 8px;
  overflow: hidden;
}

.workflow-column {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-width: 0;
  min-height: 0;
  max-height: 100%;
  padding: 12px 11px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.022);
}

.workflow-column-header {
  flex-shrink: 0;
}

.workflow-column-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2px 4px 4px;
}

/* Recorded header: title left, sort toggle centred, count right. */
.workflow-column-header {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
}

.workflow-column-title {
  grid-column: 1;
  justify-self: start;
}

.workflow-sort-toggle {
  grid-column: 2;
  justify-self: center;
}

.workflow-column-count {
  grid-column: 3;
  justify-self: end;
}

/* Compact variant of the shared segmented selector. */
.workflow-sort-toggle.composer-sort-toggles {
  padding: 2px;
}

.workflow-sort-toggle .composer-sort-toggle {
  height: 25px;
  padding: 0 11px;
  font-size: 11.5px;
}

.workflow-column-title {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
}

.workflow-column-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 14px;
  font-weight: 700;
}

.workflow-column-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
}

.piece-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  min-height: 56px;
  padding: 5px 14px 5px 18px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  /* Percentage stops so the colour fades proportionally to the card width —
     reads like a normal list row, just shorter (colour on the left, gone before
     the right edge) rather than filling the whole card. */
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 20%, transparent) 0%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 10%, transparent) 30%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 4%, transparent) 52%,
      transparent 68%
    ),
    rgba(255, 255, 255, 0.045);
  cursor: pointer;
  overflow: hidden;
  transition: transform 140ms var(--ease-out), border-color 140ms var(--ease-out);
  font-family: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif;
}

.piece-card::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 8px;
  border-radius: var(--radius) 0 0 var(--radius);
  background: var(--level-color, #7bb7ff);
  pointer-events: none;
  z-index: 1;
}

.piece-card > * {
  position: relative;
  z-index: 2;
}

.piece-card:hover {
  transform: translateX(2px);
  border-color: var(--line);
}

/* Recorded cards: blue overlay sits ON TOP of the content, fading whatever is
   underneath it on the right; the checkmark stays crisp above the overlay. */
.workflow-column[data-stage="Recorded"] .piece-card::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 30%;
  background: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.34) 40%, rgba(0, 0, 0, 0.72) 100%);
  pointer-events: none;
  z-index: 3;
}

.piece-card-check {
  position: relative;
  z-index: 4;
  margin-left: auto;
  padding-left: 12px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  color: #f0c040;
  filter: drop-shadow(0 0 4px rgba(240, 192, 64, 0.6));
}

.piece-card-check svg {
  width: 20px;
  height: 20px;
  overflow: visible;
}

.piece-card-check path {
  fill: none;
  stroke: url(#goldShine);
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.piece-card .piece-level-marker {
  flex: 0 0 58px;
  width: 58px;
  min-width: 58px;
  max-width: 58px;
  box-sizing: border-box;
  transform: none;
  height: 44px;
  padding: 6px 6px 5px;
  border-radius: 7px;
}

.piece-card .piece-level-marker span {
  font-size: 9px;
}

.piece-card .piece-level-marker strong {
  font-size: 24px;
}

.piece-card .piece-copy {
  transform: none;
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}

/* Level selected: source/rating pill on the right (replaces the level badge). */
.piece-card-source {
  position: relative;
  z-index: 4;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
}

.piece-card-source .map-pill {
  min-height: 22px;
  padding: 3px 7px;
  font-size: 11px;
  border-radius: 6px;
}

.piece-card .piece-title {
  font-size: 13px;
  margin-bottom: 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.piece-card .piece-meta {
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.level-filter-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 16px;
  margin: 4px 0 18px;
  padding: 6px 0;
}

.level-filter-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

/* Only a phone collapses the level pills; there is room for all of them here. */
.level-filter-menu-btn {
  display: none;
}

.level-filter-count {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 800;
  white-space: nowrap;
  text-transform: uppercase;
}

.level-filter-count b {
  color: var(--text);
  font-size: 30px;
  line-height: 0.9;
}

.level-filter-count b small {
  color: var(--muted);
  font-size: 17px;
  font-weight: 800;
}

.level-filter-count span {
  color: var(--muted);
}

.level-filter-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  width: 48px;
  min-width: 48px;
  height: 48px;
  min-height: 48px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  font-weight: 800;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  overflow: visible;
  white-space: nowrap;
  transition: transform 150ms var(--ease-out), filter 150ms var(--ease-out),
    border-color 240ms ease, background 240ms ease, color 240ms ease,
    width 320ms cubic-bezier(0.34, 1.3, 0.64, 1),
    min-width 320ms cubic-bezier(0.34, 1.3, 0.64, 1),
    padding 320ms cubic-bezier(0.34, 1.3, 0.64, 1),
    box-shadow 240ms ease;
}

.level-pill-badge {
  position: absolute;
  top: -3px;
  right: -3px;
  z-index: 3;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--level-color, #4a6b8a);
  color: #fff;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  pointer-events: none;
}

.level-pill-badge.dark {
  color: #14171d;
}

.level-filter-full {
  display: inline-block;
  min-width: 0;
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  white-space: nowrap;
  vertical-align: middle;
  transition: opacity 160ms ease 60ms, max-width 300ms cubic-bezier(0.34, 1.3, 0.64, 1);
}

.level-filter-compact {
  display: inline-block;
  min-width: 0;
  max-width: 40px;
  overflow: hidden;
  opacity: 1;
  white-space: nowrap;
  vertical-align: middle;
  transition: opacity 120ms ease, max-width 220ms ease;
}

.level-filter-pill:hover {
  transform: scale(1.08);
  border-color: var(--line-strong);
  color: var(--text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 10px 24px rgba(0, 0, 0, 0.2);
}

/* Edge pills scale inward so they aren't clipped by the row's overflow bounds. */
.level-filter-pill:first-child:hover {
  transform-origin: left center;
}

.level-filter-pill:last-child:hover {
  transform-origin: right center;
}

.level-filter-pill.active {
  justify-content: center;
  gap: 0;
  width: 148px;
  min-width: 148px;
  padding: 0 20px;
  border-color: color-mix(in srgb, var(--level-color) var(--degrade-strong), rgba(255, 255, 255, 0.18));
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.04)),
    color-mix(in srgb, var(--level-color) var(--degrade-strong), rgba(255, 255, 255, 0.045));
  color: var(--level-text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 8px 22px rgba(0, 0, 0, 0.16);
}

.level-filter-pill.all.active {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.15);
  color: var(--text);
}

.level-filter-pill.active .level-filter-full {
  opacity: 1;
  max-width: 120px;
}

.level-filter-pill.active .level-filter-compact {
  opacity: 0;
  max-width: 0;
}

.level-filter-pill small {
  display: none;
  min-width: 0;
  background: transparent;
  color: inherit;
  font-size: 19px;
  line-height: 1;
  opacity: 0.9;
}

.level-filter-pill.active small {
  display: none;
  background: transparent;
}

.levels-list {
  flex: 1;
  min-height: 0;
  margin-top: 8px;
  overflow-x: hidden;
  overflow-y: auto;
  align-content: start;
  grid-auto-rows: minmax(70px, auto);
}

/* === Custom scrollbar for the pieces lists === */
.levels-list,
.workflow-column-body {
  scroll-behavior: smooth;
  /* Firefox */
  scrollbar-width: thin;
  scrollbar-color: rgba(140, 170, 210, 0.28) transparent;
}

.levels-list::-webkit-scrollbar,
.workflow-column-body::-webkit-scrollbar {
  width: 11px;
}

.levels-list::-webkit-scrollbar-track,
.workflow-column-body::-webkit-scrollbar-track {
  background: transparent;
}

.levels-list::-webkit-scrollbar-thumb,
.workflow-column-body::-webkit-scrollbar-thumb {
  /* transparent border + padding-box clip makes a slim floating pill */
  border: 3px solid transparent;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(150, 180, 222, 0.36), rgba(120, 150, 200, 0.3));
  background-clip: padding-box;
  transition: background 200ms var(--ease-out);
}

.levels-list::-webkit-scrollbar-thumb:hover,
.workflow-column-body::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, rgba(170, 200, 245, 0.6), rgba(140, 175, 230, 0.52));
  background-clip: padding-box;
}

.levels-list::-webkit-scrollbar-thumb:active,
.workflow-column-body::-webkit-scrollbar-thumb:active {
  background: linear-gradient(180deg, rgba(190, 215, 255, 0.78), rgba(160, 195, 245, 0.7));
  background-clip: padding-box;
}


#composerImportanceFilter {
  margin: 6px 0 2px;
}

.composer-controls-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  flex-shrink: 0;
}

.composer-controls-row #composerImportanceFilter {
  grid-column: 1;
  margin: 6px 0 2px;
}

#composers.bars-view #composerImportanceFilter {
  display: none;
}

.composer-controls-row #composerViewToggle {
  grid-column: 3;
  margin: 0;
}

.composer-grid {
  display: grid;
  gap: 18px;
  max-height: calc(100% - 90px);
  margin: 2px 0 -8px;
  padding: 14px 14px 8px;
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

/* Bar chart view */
.composer-grid.composer-grid-list-view {
  display: block;
  padding: 10px 14px 0;
  overflow-x: auto;
  overflow-y: auto;
  max-height: calc(100vh - 178px);
  height: calc(100vh - 178px);
}

.cbars-root {
  display: flex;
  flex-direction: column;
  gap: 28px;
  min-width: max-content;
}

.cbars-row {
  display: flex;
  align-items: flex-end;
  gap: 0;
}

.cbars-era {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding-right: 24px;
  margin-right: 0;
}

.cbars-era:last-child {
  padding-right: 0;
}

.cbars-bars {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 220px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}

.cbars-slot {
  width: 20px;
  flex-shrink: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  cursor: pointer;
}

.cbars-count {
  font-size: 10px;
  line-height: 1;
  color: var(--dim);
  margin-bottom: 3px;
  pointer-events: none;
}

.cbars-bar {
  width: 16px;
  background: #3d8ef0;
  border-radius: 3px 3px 0 0;
  min-height: 3px;
  transition: background 120ms ease;
  pointer-events: none;
}

.cbars-slot:hover .cbars-bar {
  background: #6faeff;
}

/* Names row — mirrors .cbars-bars gap/width exactly for column alignment */
.cbars-names {
  display: flex;
  gap: 4px;
  overflow: visible;
}

.cbars-name-cell {
  width: 20px;
  flex-shrink: 0;
  height: 140px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  overflow: hidden;
}

.cbars-name {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  white-space: nowrap;
  font-size: 11.5px;
  font-weight: 500;
  color: var(--muted);
  pointer-events: none;
  transition: color 120ms ease;
  max-height: 138px;
  overflow: hidden;
}

.cbars-name-cell.hovered .cbars-name {
  color: var(--text);
}

.cbars-era-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
  text-align: center;
  padding: 18px 0 2px;
  white-space: nowrap;
}

.composer-grid::-webkit-scrollbar {
  display: none;
}

.composer-category-row {
  display: grid;
  gap: 12px;
}

.composer-category-head {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

.composer-category-head > h3 {
  width: 130px;
  text-align: right;
  color: var(--muted);
  font-family: Georgia, "Times New Roman", ui-serif, serif;
  font-size: 16px;
  font-style: italic;
  font-weight: 700;
}

.composer-category-chevron {
  position: relative;
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
  transition: transform 160ms var(--ease-out);
}

.composer-category-chevron::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 2px;
  width: 7px;
  height: 7px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(45deg);
}

.composer-category-row:not(.open) .composer-category-chevron {
  transform: rotate(-90deg);
}

.composer-category-head > span {
  flex: 1;
  height: 0;
  border-top: 1px solid var(--line);
}

.composer-category-cards {
  display: grid;
  gap: 12px;
}

.composer-category-row:not(.open) .composer-category-cards {
  display: none;
}

.composer-card-row {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-auto-rows: 57px;
  gap: 12px;
}

.icon-button {
  display: grid;
  width: 36px;
  height: 36px;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.075);
  color: var(--text);
  cursor: pointer;
  font-size: 19px;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.icon-button:hover {
  background: rgba(255, 255, 255, 0.12);
  color: var(--text);
}

.composer-settings-list {
  display: grid;
  gap: 0;
  width: 100%;
  max-width: 1180px;
  margin-top: 18px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.035);
}

.composer-settings-toolbar {
  padding: 12px 16px 8px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.composer-settings-add-btn {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: rgba(255,255,255,0.06);
  color: var(--text);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s;
}

.composer-settings-add-btn:hover {
  background: rgba(255,255,255,0.13);
}

.composer-settings-search {
  width: 100%;
  max-width: 320px;
  padding: 8px 12px;
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--text);
  font-size: 13px;
  outline: none;
}

.composer-settings-search:focus {
  border-color: rgba(255,255,255,0.2);
}

.composer-settings-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 14px 16px;
  border-top: 1px solid var(--line);
}

.cs-page-btn {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: rgba(255,255,255,0.05);
  color: var(--text);
  font-size: 18px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
}

.cs-page-btn:hover:not(:disabled) {
  background: rgba(255,255,255,0.12);
}

.cs-page-btn:disabled {
  opacity: 0.3;
  cursor: default;
}

.cs-page-info {
  font-size: 13px;
  color: var(--text-secondary, #b0b0c0);
}

.cs-page-info small {
  color: var(--muted);
  font-size: 11px;
}

.composer-settings-portrait {
  width: 36px;
  height: 36px;
  border-radius: 6px;
  object-fit: cover;
  display: block;
  flex-shrink: 0;
}

.composer-settings-no-portrait {
  font-size: 10px;
  color: var(--muted);
  opacity: 0.5;
  white-space: nowrap;
}

.composer-settings-row {
  display: grid;
  grid-template-columns: 80px minmax(220px, 1.4fr) minmax(130px, 0.7fr) minmax(150px, 0.8fr) minmax(150px, 0.8fr) minmax(130px, 0.7fr) 86px 42px;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 8px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
  background: transparent;
}

.composer-settings-row:last-child {
  border-bottom: 0;
}

.composer-settings-row:hover {
  background: rgba(255, 255, 255, 0.045);
}

.composer-settings-row > * {
  color: var(--muted);
  font-size: 14px;
  font-style: normal;
  font-weight: 600;
}

.composer-settings-row strong {
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
}

.composer-major-label {
  justify-self: start;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  line-height: 1.2;
}

.edit-icon-button {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.075);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23f4f7fb' d='M16.862 4.487a2.1 2.1 0 0 1 2.97 2.97L8.55 18.74 4 20l1.26-4.55L16.862 4.487Z'/%3E%3Cpath fill='none' stroke='%23f4f7fb' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m15.45 5.9 2.65 2.65'/%3E%3C/svg%3E");
  background-position: center;
  background-repeat: no-repeat;
  background-size: 16px 16px;
  color: var(--text);
  cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.edit-icon-button svg {
  display: none;
}

:root[data-is-admin="false"] [data-edit-composer] {
  display: none;
}

.composer-edit-modal {
  width: min(1120px, calc(100vw - 48px));
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  overflow-x: hidden;
}

.piece-create-modal {
  width: min(900px, calc(100vw - 48px));
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}

.mini-modal .piece-create-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 0.9fr);
  align-items: start;
  column-gap: 22px;
  row-gap: 0;
  margin-top: 18px;
}

.piece-create-column {
  display: grid;
  gap: 12px;
  min-width: 0;
}

.piece-create-level-column {
  padding-left: 22px;
  border-left: 1px solid var(--line);
}

.piece-create-form .modal-actions {
  grid-column: 1 / -1;
}

.piece-create-form label {
  position: relative;
  gap: 0;
}

.piece-create-form .field-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.piece-create-form input {
  height: 54px;
  padding: 0 18px;
  border: 0;
  border-radius: var(--dashboard-card-radius);
  outline: 0;
  background: rgba(0, 0, 0, 0.18);
  color: var(--text);
  font-size: 16px;
  font-weight: 600;
}

.piece-create-form input::placeholder {
  color: var(--muted);
  font-weight: 400;
  opacity: 1;
}

.locked-field {
  opacity: 0.78;
}

.locked-field .custom-select-button {
  cursor: default;
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 6%, transparent) 0%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 4.5%, transparent) 34%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 2%, transparent) 56%,
      transparent 70%
    ),
    rgba(255, 255, 255, 0.045);
}

.locked-field .custom-select-button .chevron {
  opacity: 0;
}

.composer-edit-form {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: start;
  column-gap: 24px;
  row-gap: 0;
  margin-top: 18px;
}

.composer-edit-column {
  display: grid;
  gap: 12px;
  min-width: 0;
}

.composer-edit-secondary {
  padding-left: 24px;
  border-left: 1px solid var(--line);
}

.composer-edit-form .modal-actions {
  grid-column: 1 / -1;
}

.composer-edit-form label,
.activity-period,
.composer-major-toggle-field {
  display: grid;
  gap: 7px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
}

.composer-edit-form input,
.composer-edit-form select {
  height: 40px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  outline: 0;
  background: rgba(0, 0, 0, 0.18);
  color: var(--text);
}

.portrait-upload-field {
  position: relative;
}

.portrait-upload-field input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

.portrait-upload-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  min-width: 132px;
  height: 40px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  cursor: pointer;
  font-weight: 700;
}

.portrait-upload-button:hover {
  background: rgba(255, 255, 255, 0.12);
}

.portrait-upload-field small {
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
  text-transform: none;
}

.activity-period > div {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.composer-major-toggle {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.18);
}

.composer-major-toggle button {
  height: 34px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-weight: 800;
}

.composer-major-toggle button.active {
  background: rgba(92, 139, 190, 0.72);
  color: var(--text);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14);
}

.activity-year-field {
  display: grid;
  gap: 7px;
}

.activity-year-field span {
  color: var(--dim);
  font-size: 11px;
  font-weight: 700;
}

.composer-card {
  --composer-card-radius: 22px;
  position: relative;
  overflow: hidden;
  grid-column: span 2;
  grid-row: span 2;
  min-height: 0;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--composer-card-radius);
  background: rgba(255, 255, 255, 0.045);
  cursor: pointer;
  transform-origin: center;
  transition: transform 140ms var(--ease-out), border-color 140ms var(--ease-out), background 140ms var(--ease-out);
}

.composer-card:hover {
  transform: scale(1.018);
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.07);
}

.composer-card strong {
  position: relative;
  z-index: 1;
  display: block;
  max-width: none;
  white-space: nowrap;
  font-family: Georgia, "Times New Roman", ui-serif, serif;
  font-size: 36px;
  font-weight: 600;
  line-height: 1.15;
}

.composer-card-minor {
  grid-column: span 2;
  grid-row: span 1;
  min-height: 0;
  padding: 12px 16px;
}

.composer-card-minor strong {
  white-space: nowrap;
  font-size: 24px;
  line-height: 1.15;
}

.composer-minor-stack {
  display: grid;
  grid-column: span 2;
  grid-row: span 2;
  grid-template-rows: repeat(2, 57px);
  gap: 12px;
  min-height: 0;
}

.composer-minor-stack .composer-card-minor {
  grid-column: auto;
  grid-row: auto;
}

.composer-count {
  position: absolute;
  left: 16px;
  bottom: 14px;
  z-index: 1;
  display: grid;
  justify-items: start;
}

.composer-count b {
  color: #9fcfff;
  font-size: 34px;
  line-height: 0.9;
}

.composer-card-portrait {
  position: absolute;
  right: -10px;
  top: 0;
  bottom: auto;
  width: 112px;
  height: 128px;
  object-fit: cover;
  object-position: right bottom;
  opacity: 0.16;
  pointer-events: none;
  user-select: none;
  filter: grayscale(1) contrast(1.06) brightness(1.08);
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.82) 28%, #000 100%);
  mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.82) 28%, #000 100%);
}

.back-button {
  position: relative;
  display: block;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.075);
  color: var(--text);
  cursor: pointer;
  line-height: 1;
  padding: 0;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.back-button::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 10px;
  height: 10px;
  border-left: 2.5px solid currentColor;
  border-bottom: 2.5px solid currentColor;
  border-radius: 1px;
  transform: translate(-40%, -50%) rotate(45deg);
}

.back-button:hover {
  background: rgba(255, 255, 255, 0.12);
}

.title-row {
  display: flex;
  align-items: center;
  gap: 16px;
}

#view-title.composer-subview-title {
  margin-top: 0;
  font-size: 24px;
  font-weight: 500;
}

.topbar.composer-subview .title-row {
  gap: 12px;
}

.topbar.composer-subview .title-row > span {
  font-weight: 500;
}

.topbar.composer-subview .back-button {
  width: 30px;
  height: 30px;
}

.topbar.composer-subview .back-button::before {
  width: 8px;
  height: 8px;
  border-left-width: 2px;
  border-bottom-width: 2px;
}

.composer-detail-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 18px;
}

.composer-detail-copy {
  display: grid;
  gap: 6px;
}

.composer-detail-meta {
  color: var(--muted);
  font-size: 14px;
  font-weight: 750;
  letter-spacing: 0;
  text-transform: uppercase;
}

.composer-detail-head h3 {
  font-family: Georgia, "Times New Roman", ui-serif, serif;
  color: var(--text);
  font-size: 48px;
  font-weight: 600;
}

#composerDetailName {
  color: var(--text);
}

.composer-detail-copy > small {
  color: var(--muted);
  font-family: Georgia, "Times New Roman", ui-serif, serif;
  font-size: 20px;
  font-style: normal;
  font-weight: 700;
}

.title-row > span {
  color: var(--muted);
}

.composer-detail-head span {
  color: var(--muted);
}

.composer-detail-count {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.composer-detail-count b {
  color: var(--text);
  font-size: 26px;
  line-height: 1;
}

.composer-detail-count small {
  color: var(--muted);
  font-size: 14px;
}

.composer-stage-menu {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin: 0 0 16px;
  padding-top: 2px;
}

.stage-count-card {
  display: flex;
  min-height: 92px;
  align-items: end;
  justify-content: space-between;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--dashboard-card-radius);
  background: rgba(255, 255, 255, 0.045);
  color: var(--muted);
  cursor: pointer;
  text-align: left;
  transition: border-color 150ms var(--ease-out), background 150ms var(--ease-out), transform 150ms var(--ease-out);
}

.stage-count-card:hover,
.stage-count-card.active {
  border-color: rgba(123, 183, 255, 0.34);
  background: rgba(123, 183, 255, 0.1);
  color: var(--text);
  transform: translateY(-1px);
}

.stage-count-card span {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.stage-count-card strong {
  color: var(--text);
  font-size: 42px;
  line-height: 0.86;
}

.stage-count-card-recorded,
.metric-card.recorded {
  border-color: rgba(79, 131, 194, 0.34);
  background:
    linear-gradient(135deg, rgba(11, 42, 91, 0.42), rgba(23, 75, 145, 0.18)),
    rgba(255, 255, 255, 0.045);
}

.stage-count-card-recorded:hover,
.stage-count-card-recorded.active,
.metric-card.recorded:hover {
  border-color: rgba(156, 207, 255, 0.48);
  background:
    linear-gradient(135deg, rgba(11, 42, 91, 0.58), rgba(23, 75, 145, 0.32)),
    rgba(123, 183, 255, 0.1);
}

.composer-filter-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.composer-mode-toggle {
  flex-shrink: 0;
}

#composer-detail.exercises-mode .composer-sort-toggles,
#composer-detail.exercises-mode .composer-stage-menu,
#composer-detail.exercises-mode #composerDetailPieces {
  display: none;
}

#composerDetailExercises {
  display: none;
  overflow-y: auto;
}

#composer-detail.exercises-mode #composerDetailExercises {
  display: block;
}

.composer-sort-toggles,
.segmented {
  position: relative;
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition: transform 200ms var(--ease-out);
}

.composer-sort-toggles:hover,
.segmented:hover {
  transform: scale(1.04);
}

.composer-sort-toggles {
  justify-self: end;
  margin: 0 0 0 auto;
}

.level-filter-row .composer-sort-toggles {
  margin: 0;
}

/* Shared by every segmented pill selector (stage filters, view toggles,
   Library tabs). The selected segment reads darker than the track. */
.stage-indicator {
  position: absolute;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.34);
  pointer-events: none;
  z-index: 0;
  transition: left 300ms cubic-bezier(0.34, 1.3, 0.64, 1),
              width 300ms cubic-bezier(0.34, 1.3, 0.64, 1),
              top 300ms cubic-bezier(0.34, 1.3, 0.64, 1),
              height 300ms cubic-bezier(0.34, 1.3, 0.64, 1);
}

.composer-sort-toggle,
.segmented button {
  position: relative;
  z-index: 1;
  height: 32px;
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #fff;
  cursor: pointer;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 13px;
  font-weight: 500;
  transition: color 200ms ease;
}

.composer-sort-toggle:hover,
.segmented button:hover {
  color: var(--text);
}

.composer-sort-toggle.active,
.segmented button.active {
  color: #2e9bff;
}

.piece-row {
  position: relative;
  display: grid;
  grid-template-columns: 122px minmax(280px, 1fr) 132px minmax(116px, 0.26fr) 58px;
  align-items: center;
  gap: 12px;
  min-height: 70px;
  padding: 7px 24px 7px 42px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 10%, transparent) 0%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 7%, transparent) 34%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 3.5%, transparent) 56%,
      transparent 70%
    ),
    rgba(255, 255, 255, 0.045);
  cursor: default;
  overflow: hidden;
  transition: transform 140ms var(--ease-out), border-color 140ms var(--ease-out);
  will-change: transform;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif;
}

.piece-row::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 8px;
  border-radius: var(--radius) 0 0 var(--radius);
  background: var(--level-color, #7bb7ff);
  pointer-events: none;
  z-index: 1;
}

.piece-row > * {
  position: relative;
  z-index: 2;
}

.piece-row:has(.stage-status.Recorded)::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 18%;
  border-radius: 0 var(--radius) var(--radius) 0;
  background:
    linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.34) 58%, rgba(0, 0, 0, 0.72) 100%);
  opacity: 1;
  pointer-events: none;
  z-index: 1;
}

.piece-row:has(.stage-status.Recorded) .stage-status {
  position: relative;
  z-index: 2;
}

.piece-row:hover {
  transform: translateX(2px);
  border-color: var(--line);
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 12%, transparent) 0%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 8%, transparent) 34%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 4%, transparent) 56%,
      transparent 70%
    ),ned
    rgba(255, 255, 255, 0.08);
}

body.level-theme-modern .piece-row {
  border-color: rgba(255, 255, 255, 0.035);
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #2f87ff)) 14%, transparent) 0%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #2f87ff)) 9%, transparent) 30%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #2f87ff)) 4%, transparent) 54%,
      transparent 70%
    ),
    rgba(255, 255, 255, 0.035);
}

body.level-theme-modern .piece-row:hover {
  border-color: rgba(86, 151, 255, 0.18);
  background:
    linear-gradient(
      90deg,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #2f87ff)) 16%, transparent) 0%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #2f87ff)) 10%, transparent) 30%,
      color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #2f87ff)) 4.5%, transparent) 54%,
      transparent 70%
    ),
    rgba(255, 255, 255, 0.055);
}

body.level-theme-modern .level-filter-pill {
  border-color: rgba(255, 255, 255, 0.075);
  background: rgba(255, 255, 255, 0.045);
  color: rgba(190, 201, 215, 0.9);
}

body.level-theme-modern .level-filter-pill:hover {
  border-color: color-mix(in srgb, var(--level-color, #2f87ff) 24%, rgba(255, 255, 255, 0.1));
  background: color-mix(in srgb, var(--level-color, #2f87ff) 8%, rgba(255, 255, 255, 0.045));
  color: var(--level-secondary-color, #74adff);
}

body.level-theme-modern .level-filter-pill.active {
  border-color: color-mix(in srgb, var(--level-color, #2f87ff) 50%, rgba(255, 255, 255, 0.12));
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.025)),
    color-mix(in srgb, var(--level-color, #2f87ff) 32%, rgba(255, 255, 255, 0.035));
  color: var(--level-secondary-color, #74adff);
}

body.level-theme-modern .level-filter-pill.all.active {
  border-color: rgba(255, 255, 255, 0.12);
  background: rgba(255, 255, 255, 0.105);
  color: var(--text);
}

.piece-level-marker {
  display: grid;
  width: 74px;
  height: 56px;
  align-content: center;
  overflow: hidden;
  justify-items: center;
  justify-self: start;
  padding: 8px 8px 7px;
  border: 0;
  border-radius: 9px;
  background: color-mix(in srgb, var(--level-color, #7bb7ff) 5%, rgba(255, 255, 255, 0.026));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.035),
    0 8px 22px rgba(0, 0, 0, 0.08);
  transform: translateX(-10px);
}

.piece-level-marker span {
  color: rgba(190, 201, 215, 0.82);
  font-size: 11px;
  font-weight: 650;
  line-height: 1;
  text-transform: uppercase;
}

.piece-level-marker strong {
  color: var(--level-secondary-color, var(--level-color, #7bb7ff));
  font-size: 31px;
  font-weight: 600;
  line-height: 0.96;
}

.piece-copy {
  transform: translateX(-45px);
}

.piece-title {
  display: block;
  margin-bottom: 2px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.piece-meta {
  color: rgba(190, 201, 215, 0.82);
  font-size: 13px;
  font-weight: 400;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.piece-unknown-composer-warning {
  color: #f5a623;
  font-size: 11px;
  font-weight: 500;
  margin-left: 6px;
  opacity: 0.9;
}

.piece-row--unknown-composer .piece-level-marker {
  border-left-color: #f5a623;
}

.piece-meta strong {
  color: rgba(232, 238, 246, 0.94);
  font-weight: 500;
}

.piece-composer-link {
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: #74adff;
  cursor: pointer;
  font: inherit;
  font-weight: 650;
  text-align: left;
  box-shadow: none;
  transition: color 150ms var(--ease-out), text-shadow 150ms var(--ease-out);
}

.piece-composer-link:hover {
  color: #9ccfff;
  text-shadow: 0 0 12px rgba(123, 183, 255, 0.28);
}

.piece-composer-separator {
  color: rgba(190, 201, 215, 0.64);
}

.pill {
  justify-self: start;
  padding: 5px 9px;
  border: none;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.07);
  font-size: 12px;
  font-weight: 700;
}

.level-pill {
  background: color-mix(in srgb, var(--level-color, #7bb7ff) 18%, rgba(255, 255, 255, 0.06));
  color: var(--level-text, #fff);
}

.stage-status {
  display: inline-flex;
  align-items: center;
  justify-self: end;
  justify-content: flex-start;
  gap: 7px;
  width: 86px;
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
}

.stage-status i {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: currentColor;
  opacity: 0.9;
}

.stage-status.Recorded {
  color: #4f8dff;
  text-shadow: none;
  transform: none;
  justify-self: end;
  width: 86px;
  font-size: 0;
}

.stage-status.Recorded i {
  display: none;
}

.stage-status.Ready {
  color: var(--green);
}

.stage-status.Working {
  color: var(--amber);
}

.stage-status.Assigned {
  color: var(--cyan);
}

.piece-open-icon {
  display: grid;
  width: 58px;
  height: 100%;
  min-height: 54px;
  place-items: center;
  justify-self: end;
  color: rgba(190, 201, 215, 0.7);
  opacity: 0.82;
  cursor: pointer;
  transition: color 150ms var(--ease-out), opacity 150ms var(--ease-out), transform 150ms var(--ease-out);
}

.piece-open-icon svg {
  width: 24px;
  height: 24px;
  overflow: visible;
}

.piece-open-icon path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.piece-row:hover .piece-open-icon {
  color: rgba(230, 238, 248, 0.86);
  opacity: 1;
  transform: translateX(2px);
}

.piece-row:has(.stage-status.Recorded) .piece-open-icon {
  color: #f0c040;
  filter: drop-shadow(0 0 4px rgba(240, 192, 64, 0.55));
}

.piece-row:has(.stage-status.Recorded) .piece-open-icon path {
  stroke-width: 2.4;
  stroke: url(#goldShine);
}

@keyframes goldShineSlide {
  0%   { x1: -60%; x2: -20%; }
  100% { x1: 140%; x2: 180%; }
}

.piece-row:has(.stage-status.Recorded):hover .piece-open-icon {
  filter: drop-shadow(0 0 7px rgba(255, 210, 80, 0.85));
}

.preview-open-icon {
  visibility: hidden;
}

.level-bars {
  display: grid;
  gap: 4px;
  padding-left: 32px;
  margin: auto 0;
}

.level-bar-header {
  display: grid;
  grid-template-columns: 82px 1fr;
  gap: 12px;
}

.level-bar-header span {
  color: var(--muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.level-bar {
  display: grid;
  grid-template-columns: 82px 1fr;
  align-items: center;
  gap: 12px;
}

.level-bar strong {
  color: rgba(190, 201, 215, 0.78);
  font-size: 17px;
  font-weight: 700;
}

.bar-track {
  position: relative;
  height: 9px;
  overflow: visible;
  border-radius: 8px;
  background: transparent;
}

.bar-fill {
  position: relative;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.34));
}

.bar-fill span {
  position: absolute;
  top: 50%;
  right: -26px;
  min-width: 18px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 750;
  line-height: 1;
  text-align: left;
  transform: translateY(-50%);
}

.bar-fill.empty {
  width: 0 !important;
  background: transparent !important;
}

.bar-fill.empty span {
  right: auto;
  left: 0;
}

.select,
.form-stack select {
  height: 36px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #1b2028;
  color: var(--text);
}

.accordion-item {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.045);
}

.accordion-toggle {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  align-items: center;
  width: 100%;
  min-height: 58px;
  padding: 0 14px;
  border: 0;
  background: transparent;
  cursor: pointer;
  text-align: left;
}

.chevron {
  position: relative;
  display: inline-block;
  width: 12px;
  height: 12px;
  flex: 0 0 12px;
  color: var(--muted);
  font-size: 0;
  transition: transform 140ms var(--ease-out);
}

.chevron::before {
  content: "";
  position: absolute;
  inset: 1px 1px 3px 3px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(-45deg);
}

.accordion-item.open .chevron {
  transform: rotate(90deg);
}

.accordion-title strong {
  display: block;
}

.accordion-title span,
.accordion-count {
  color: var(--muted);
  font-size: 13px;
}

.accordion-body {
  display: grid;
  gap: 8px;
  max-height: 0;
  padding: 0 12px;
  overflow: hidden;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out);
}

.accordion-item.open .accordion-body {
  max-height: none;
  padding: 0 12px 12px;
  overflow: visible;
  opacity: 1;
  transform: translateY(0);
}

.practice-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 54px;
  padding: 12px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.05);
}

.spotlight {
  display: flex;
  min-height: 260px;
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

.spotlight strong {
  display: block;
  margin: 12px 0;
  font-size: 58px;
}

.empty-state {
  display: grid;
  min-height: 240px;
  place-items: center;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  color: var(--muted);
}

.practice-month-title {
  margin-top: 0;
  color: var(--dim);
  font-size: 32px;
  font-weight: 720;
  line-height: 0.95;
}

.practice-month.open .practice-month-title {
  color: var(--text);
  font-size: 48px;
}

.practice-year {
  display: grid;
  gap: 22px;
}

.practice-settings {
  display: grid;
  align-items: center;
  justify-content: end;
  justify-items: end;
  gap: 12px;
  position: absolute;
  top: -92px;
  right: 0;
  margin: 0;
}

.practice-settings label,
.default-practice-setting {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 650;
}

.practice-settings input,
.practice-settings select {
  height: 34px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  outline: 0;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
}

.practice-settings input:focus,
.practice-settings select:focus {
  border-color: rgba(123, 183, 255, 0.68);
  box-shadow: 0 0 0 3px rgba(123, 183, 255, 0.12);
}

.practice-year-control {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 18px;
  margin: 40px 0 14px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 650;
}

.custom-select {
  position: relative;
}

.custom-select-button {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 38px;
  padding: 0 14px 0 18px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  cursor: pointer;
}

.custom-select-button strong {
  font-size: 15px;
}

.custom-select-button .chevron {
  width: 10px;
  height: 10px;
  flex: 0 0 10px;
  transform: rotate(90deg);
}

.custom-select.open .custom-select-button {
  border-color: rgba(123, 183, 255, 0.72);
  box-shadow: 0 0 0 3px rgba(123, 183, 255, 0.12);
}

.custom-select.open .custom-select-button .chevron {
  transform: rotate(-90deg);
}

.custom-select-menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  min-width: 100%;
  padding: 6px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: var(--modal-surface);
  backdrop-filter: blur(20px) saturate(1.08);
  -webkit-backdrop-filter: blur(20px) saturate(1.08);
  box-shadow: var(--shadow);
  z-index: 6;
  display: none;
}

.custom-select.open .custom-select-menu {
  display: grid;
  gap: 3px;
}

.custom-select-option {
  height: 32px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  text-align: left;
}

.custom-select-option:hover,
.custom-select-option.active {
  background: rgba(123, 183, 255, 0.16);
  color: var(--text);
}

.form-stack select.customized-select,
.composer-edit-form select.customized-select {
  display: none;
}

.form-stack .custom-select,
.composer-edit-form .custom-select {
  width: 100%;
}

.form-stack .custom-select-button,
.composer-edit-form .custom-select-button {
  width: 100%;
  height: 42px;
  justify-content: space-between;
  border-radius: 8px;
  background: #1b2028;
}

.piece-create-form .custom-select-button,
.piece-create-form .date-select-button,
.piece-create-form .priority {
  min-height: 54px;
  border: 0;
  border-radius: var(--dashboard-card-radius);
  background: rgba(0, 0, 0, 0.18);
  box-shadow: none;
}

.piece-create-form .custom-select.open .custom-select-button {
  border: 0;
  box-shadow: none;
}

.piece-create-form .custom-select-button {
  padding: 0 18px;
}

.piece-create-form .date-select-button {
  height: 54px;
  padding: 0 18px;
  color: var(--text);
}

.form-stack .custom-select-button strong,
.composer-edit-form .custom-select-button strong {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.form-stack .custom-select-menu,
.composer-edit-form .custom-select-menu {
  right: 0;
  max-height: 240px;
  overflow-y: auto;
}

.composer-multi-select .custom-select-menu {
  gap: 6px;
  max-height: 300px;
  overflow-y: auto;
}

.composer-multi-search {
  position: sticky;
  top: 0;
  z-index: 1;
  display: block;
  padding: 4px;
  background: var(--modal-surface);
}

.composer-multi-search input {
  width: 100%;
  height: 34px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  outline: 0;
  background: rgba(0, 0, 0, 0.18);
  color: var(--text);
}

.composer-multi-options {
  display: grid;
  gap: 3px;
}

.composer-multi-option {
  display: flex;
  align-items: center;
  gap: 9px;
  min-height: 34px;
  padding: 0 9px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  text-align: left;
  font-weight: 750;
}

.composer-multi-option[hidden] {
  display: none;
}

.composer-multi-option:hover,
.composer-multi-option.active {
  background: rgba(123, 183, 255, 0.16);
  color: var(--text);
}

.composer-multi-select.required-empty .custom-select-button {
  border-color: rgba(255, 143, 163, 0.5);
}

.composer-multi-check {
  display: grid;
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  place-items: center;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.04);
}

.composer-multi-option.active .composer-multi-check {
  border-color: rgba(123, 183, 255, 0.72);
  background: rgba(123, 183, 255, 0.85);
}

.composer-multi-option.active .composer-multi-check::before {
  content: "";
  width: 8px;
  height: 4px;
  border-left: 2px solid #102033;
  border-bottom: 2px solid #102033;
  transform: rotate(-45deg) translateY(-1px);
}

.composer-multi-option span:last-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.practice-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(160px, 1fr));
  gap: 12px;
  margin-bottom: 14px;
}

.practice-stat-card {
  padding: 16px;
  border: 0;
  border-radius: var(--dashboard-card-radius);
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

.practice-stat-card span {
  display: block;
  margin-bottom: 8px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 750;
  text-transform: uppercase;
}

.practice-stat-card strong {
  font-size: 32px;
}

.hours-goal {
  width: min(1120px, 100%);
  margin: 30px 0 18px;
}

.hours-goal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 8px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 750;
  text-transform: uppercase;
}

.hours-goal-head strong {
  color: var(--text);
  font-size: 12px;
}

.hours-goal-track {
  height: 12px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.045);
}

.hours-goal-fill {
  width: 0%;
  min-width: 0;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #174b91 0%, #4f83c2 34%, #9ccfff 50%, #4f83c2 66%, #174b91 100%);
  background-size: 200% 100%;
  animation: goalGlowFlow 3.4s linear infinite;
  transition: width 220ms var(--ease-out);
}

.hours-goal-fill.visible-progress {
  min-width: 34px;
}

@keyframes goalGlowFlow {
  0% {
    background-position: 0% 50%;
    filter: brightness(1);
  }
  100% {
    background-position: -200% 50%;
    filter: brightness(1);
  }
}

.default-practice-setting > span {
  color: var(--muted);
}

.default-practice-setting label {
  gap: 5px;
}

.default-practice-setting input {
  width: 62px;
  text-align: center;
}

.practice-month {
  margin-top: 8px;
}

.practice-month-toggle {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

.practice-month-toggle .chevron {
  transform: rotate(90deg);
}

.practice-month:not(.open) .practice-month-toggle .chevron {
  transform: rotate(0deg);
}

.practice-month-body {
  margin-top: 18px;
}

.practice-month:not(.open) .practice-month-body {
  display: none;
}

.practice-day-grid {
  display: grid;
  grid-template-columns: repeat(7, 132px);
  gap: 8px;
}

.practice-day-label,
.practice-day-square {
  display: grid;
  place-items: center;
}

.practice-day-label {
  height: 22px;
  color: var(--dim);
  font-size: 12px;
  font-weight: 750;
}

.practice-day-square {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 132px;
  height: 42px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.045);
  color: var(--muted);
  cursor: pointer;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  transition: transform 140ms var(--ease-out), border-color 140ms var(--ease-out), background 140ms var(--ease-out);
}

.practice-day-square:not(.empty):hover {
  transform: scale(1.04);
  z-index: 1;
}

.practice-day-square.practice-level-1 {
  border-color: transparent;
  background: rgba(178, 218, 255, 0.16);
  color: #f7fbff;
}

.practice-day-square.practice-level-2 {
  border-color: transparent;
  background: rgba(137, 195, 255, 0.24);
  color: #f7fbff;
}

.practice-day-square.practice-level-3 {
  border-color: transparent;
  background: rgba(94, 165, 240, 0.34);
  color: #f7fbff;
}

.practice-day-square.practice-level-4 {
  border-color: transparent;
  background: rgba(48, 126, 212, 0.46);
  color: #f7fbff;
}

.practice-day-square.practice-level-5 {
  border-color: transparent;
  background: rgba(22, 82, 164, 0.64);
  color: #f7fbff;
}

.practice-day-square small {
  color: inherit;
  opacity: 0.78;
  font-size: 11px;
}

.practice-day-square.empty {
  visibility: hidden;
}

.inspector {
  position: fixed;
  top: 18px;
  right: 18px;
  bottom: 18px;
  display: flex;
  flex-direction: column;
  width: 360px;
  padding: 22px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: rgba(24, 29, 36, 0.88);
  box-shadow: var(--shadow);
  backdrop-filter: blur(20px) saturate(1.08);
  transform: translateX(calc(100% + 30px));
  transition: transform 180ms var(--ease-out);
  will-change: transform;
  z-index: 10;
}

.inspector.open {
  transform: translateX(0);
}

.close-inspector {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  font-size: 0;
  line-height: 0;
  padding: 0;
}

.close-inspector::before,
.close-inspector::after {
  content: "";
  position: absolute;
  left: 9px;
  top: 14px;
  width: 12px;
  height: 2px;
  border-radius: 999px;
  background: currentColor;
}

.close-inspector::before {
  transform: rotate(45deg);
}

.close-inspector::after {
  transform: rotate(-45deg);
}

.inspector h3 {
  margin: 8px 28px 6px 0;
  line-height: 1.15;
}

.form-stack {
  display: grid;
  gap: 12px;
  flex: 1;
  min-height: 0;
  margin-top: 24px;
  overflow-y: auto;
  padding-right: 4px;
}

.form-stack label {
  display: grid;
  gap: 7px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
}

.inspector-actions {
  display: grid;
  gap: 10px;
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

.inspector-actions .primary-button,
.inspector-actions .danger-button {
  width: 44px;
}

.danger-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-height: 44px;
  padding: 0;
  border: 1px solid rgba(255, 59, 48, 0.38);
  border-radius: 999px;
  background: rgba(255, 59, 48, 0.1);
  color: #ff6b60;
  cursor: pointer;
  font-size: 0;
}

.danger-button::before {
  content: "";
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ff6b60' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 3h6'/%3E%3Cpath d='M3 6h18'/%3E%3Cpath d='M5 6l1.5 13a2 2 0 0 0 2 1.8h7a2 2 0 0 0 2-1.8L19 6'/%3E%3Cpath d='M10 11v5M14 11v5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: contain;
}

.danger-button:hover {
  border-color: rgba(255, 59, 48, 0.58);
  background: rgba(255, 59, 48, 0.18);
}

.danger-button:hover::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ff8077' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 3h6'/%3E%3Cpath d='M3 6h18'/%3E%3Cpath d='M5 6l1.5 13a2 2 0 0 0 2 1.8h7a2 2 0 0 0 2-1.8L19 6'/%3E%3Cpath d='M10 11v5M14 11v5'/%3E%3C/svg%3E");
}

.danger-button.solid {
  width: auto;
  padding: 0 18px;
  font-size: inherit;
  border-color: rgba(255, 59, 48, 0.55);
  background: rgba(255, 59, 48, 0.22);
  color: #ffb0a8;
}

.danger-button.solid::before {
  display: none;
}

.check-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: #007AFF !important;
  border: none !important;
  color: #fff !important;
  border-radius: 50% !important;
}

.check-btn:hover {
  background: #0A84FF !important;
}

.check-btn svg {
  flex-shrink: 0;
  color: #fff;
  width: 22px;
  height: 22px;
}

.field-clear-btn,
.select-clear-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.15) !important;
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.6);
  cursor: pointer;
  flex-shrink: 0;
}

.field-clear-btn:hover,
.select-clear-btn:hover {
  background: rgba(255, 255, 255, 0.22);
  color: var(--text);
}

.piece-create-date-group label {
  position: relative;
}

.field-clear-btn {
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
}

.custom-select-button strong {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.supporting-rating-field > span {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.piece-create-form .supporting-rating-field {
  position: relative;
}

.piece-create-form .supporting-rating-field .rating-star-button {
  position: absolute;
  right: 14px;
  top: 50%;
  z-index: 2;
  transform: translateY(-50%);
}

.piece-create-form .supporting-rating-field .custom-select-button {
  padding-right: 52px;
}

.rating-star-button {
  display: inline-grid;
  width: 24px;
  height: 24px;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--muted);
  cursor: pointer;
  font-size: 0;
  line-height: 0;
}

.rating-star-button::before {
  content: "";
  width: 16px;
  height: 16px;
  background: currentColor;
  mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolygon points='12,2.5 15.09,8.76 22,9.77 17,14.64 18.18,21.52 12,18.27 5.82,21.52 7,14.64 2,9.77 8.91,8.76' fill='black' stroke='black' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E");
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpolygon points='12,2.5 15.09,8.76 22,9.77 17,14.64 18.18,21.52 12,18.27 5.82,21.52 7,14.64 2,9.77 8.91,8.76' fill='black' stroke='black' stroke-width='2' stroke-linejoin='round'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  opacity: 0.85;
}

.rating-star-button.active {
  border-color: rgba(255, 209, 102, 0.5);
  background: rgba(255, 209, 102, 0.14);
  color: var(--amber);
}

.rating-star-button.active::before {
  opacity: 1;
}

.form-stack select {
  width: 100%;
  padding: 0 10px;
}

.date-select-button {
  width: 100%;
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #1b2028;
  color: var(--text);
  cursor: pointer;
  text-align: left;
}

.form-stack .priority {
  padding: 12px;
  border: 1px solid rgba(123, 183, 255, 0.24);
  border-radius: var(--radius);
  background: rgba(123, 183, 255, 0.08);
}

.date-select-button:hover {
  border-color: var(--line-strong);
}

.piece-create-form .date-select-button:hover {
  border-color: transparent;
}

.piece-create-form.form-stack label {
  gap: 0;
}

.piece-create-form.form-stack .priority {
  padding: 14px 18px;
  border: 0;
  border-radius: var(--dashboard-card-radius);
  background: rgba(0, 0, 0, 0.18);
}

.overall-level-display {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 4px 0 2px;
}

.hidden-by-search {
  display: none;
}

.config-stack {
  display: grid;
  gap: 16px;
}

.library-page {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.library-header {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 18px;
}

/* The shared toggle style pushes itself right (margin-left: auto); here it
   leads the header, with the count beside it. */
.library-header .composer-sort-toggles {
  margin: 0;
}

/* Composers table */
.library-composers-list {
  min-width: 1000px;
}

.library-row.library-composer-row {
  /* Name takes a double share; every short-value column shares the rest
     evenly so the gaps between them stay consistent at any width. */
  grid-template-columns: 90px minmax(200px, 2fr) minmax(110px, 1fr) minmax(110px, 1fr) minmax(110px, 1fr) minmax(110px, 1fr) minmax(100px, 0.8fr) 64px;
}

.library-portrait-cell {
  justify-content: center;
  padding-top: 6px;
  padding-bottom: 6px;
}

/* Keep the header label over the centred thumbnails. */
.library-row.header .library-portrait-cell,
.library-row.library-composer-row.header .library-cell:first-child {
  text-align: center;
}

/* Sized to sit inside the 44px row without making it taller. */
.library-portrait-thumb {
  display: block;
  width: 30px;
  height: 30px;
  border-radius: 6px;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.06);
}

.library-portrait-upload {
  height: 28px;
  padding: 0 12px;
  border: 1px solid rgba(90, 169, 255, 0.45);
  border-radius: 999px;
  background: rgba(90, 169, 255, 0.14);
  color: #c9e4ff;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background 150ms, border-color 150ms;
}

.library-portrait-upload:hover:not(:disabled) {
  background: rgba(90, 169, 255, 0.24);
  border-color: rgba(90, 169, 255, 0.65);
}

.library-portrait-upload:disabled {
  opacity: 0.6;
  cursor: default;
}

.library-portrait-upload.error {
  border-color: rgba(255, 107, 107, 0.6);
  background: rgba(255, 107, 107, 0.18);
  color: #ffc9c9;
}

.library-edit-cell {
  justify-content: center;
}

.library-row.header .library-cell:last-child {
  text-align: center;
}

.library-header strong {
  font-size: 22px;
  font-weight: 700;
  color: rgba(232, 238, 246, 0.95);
}

.library-count {
  font-size: 13px;
  color: var(--muted);
}

.library-table-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding-bottom: 8px;
  scroll-behavior: smooth;
  /* Firefox */
  scrollbar-width: thin;
  scrollbar-color: rgba(140, 170, 210, 0.28) transparent;
}

.library-table-scroll::-webkit-scrollbar {
  width: 11px;
  height: 11px;
}

.library-table-scroll::-webkit-scrollbar-track {
  background: transparent;
}

.library-table-scroll::-webkit-scrollbar-thumb {
  /* transparent border + padding-box clip makes a slim floating pill */
  border: 3px solid transparent;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(150, 180, 222, 0.36), rgba(120, 150, 200, 0.3));
  background-clip: padding-box;
  transition: background 200ms var(--ease-out);
}

.library-table-scroll::-webkit-scrollbar-thumb:hover {
  background: linear-gradient(180deg, rgba(170, 200, 245, 0.6), rgba(140, 175, 230, 0.52));
  background-clip: padding-box;
}

.library-table-scroll::-webkit-scrollbar-thumb:active {
  background: linear-gradient(180deg, rgba(190, 215, 255, 0.78), rgba(160, 195, 245, 0.7));
  background-clip: padding-box;
}

/* Column labels stay put while the rows scroll under them. */
.library-row.header {
  position: sticky;
  top: 0;
  z-index: 2;
}

.library-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 1446px;
  /* One continuous table surface; rows are divided by hairlines. */
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.045);
  overflow: hidden;
}

/* Each row is one continuous surface — cells are fused, with the level
   colour carried by the row's left accent rather than any cell border. */
/* .library-row sets display: grid after the shared .hidden-by-search rule,
   so it needs its own, more specific hide. */
.library-row.hidden-by-search {
  display: none;
}

/* Sortable column headers — buttons styled to look like the plain labels. */
.library-sort-header {
  display: flex !important;
  align-items: center;
  gap: 6px;
  width: 100%;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: color 150ms;
}

.library-row.header .library-sort-header:hover {
  color: #fff;
}

.library-sort-arrow {
  font-size: 8px;
  opacity: 0.8;
}

.library-row {
  display: grid;
  grid-template-columns: 48px 104px minmax(150px, 0.9fr) 120px minmax(220px, 1.6fr) minmax(154px, 1fr) repeat(3, minmax(118px, 1fr)) minmax(110px, 0.9fr) 88px 64px;
  align-items: stretch;
  gap: 0;
}

/* Pieces table: breathing room between Title and the first rating column.
   The RCM column is widened by the same amount so its pills keep their space. */
.library-row:not(.library-composer-row):not(.library-import-row) > .library-cell:nth-child(6) {
  padding-left: 48px;
}

.library-row + .library-row {
  border-top: 1px solid var(--line);
}

.library-cell {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  min-height: 44px;
  padding: 10px 12px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
}

.library-row.header {
  background: rgba(255, 255, 255, 0.08);
}

.library-row.header .library-cell {
  display: block;
  min-height: 34px;
  color: var(--text);
  font-size: 11px;
  font-weight: 750;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Truncated catalog UUID — full value available via the cell's title tooltip. */
.library-added-by-cell {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
}

.library-id-cell {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  color: var(--dim);
  white-space: nowrap;
  cursor: default;
}

.library-level-cell {
  color: var(--level-color);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.library-composer-cell {
  color: #f0c040;
  font-weight: 600;
}

.library-era-cell {
  font-size: 12px;
  color: #fff;
  white-space: nowrap;
}

.library-title-cell {
  color: var(--text);
  font-weight: 600;
}

.library-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex: 1;
  gap: 12px;
  padding: 80px 24px;
  text-align: center;
  color: var(--muted);
}

.library-empty-state svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.5;
  margin-bottom: 4px;
}

.library-empty-state h3 {
  font-size: 18px;
  font-weight: 600;
  color: rgba(232, 238, 246, 0.92);
  margin: 0;
}

.library-empty-state p {
  font-size: 13px;
  line-height: 1.6;
  max-width: 380px;
  margin: 0;
}

/* Imports tab */
/* Sized to fit beside the sidebar on a 1440px screen without scrolling sideways. */
.library-imports-list {
  min-width: 1080px;
}

.library-row.library-import-row {
  grid-template-columns: 48px 96px minmax(150px, 1fr) minmax(230px, 2fr) 128px 84px minmax(200px, 1.4fr) 128px;
}

/* Last column: centred under its header, like the other tables' last column. */
.library-import-row .library-added-by-cell {
  justify-content: center;
}

.library-import-check {
  justify-content: center;
  cursor: pointer;
}

.library-import-check input {
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: #007AFF;
  cursor: pointer;
}

.library-import-check input:disabled {
  cursor: default;
}

.library-row.library-import-row.is-blocked .library-title-cell,
.library-row.library-import-row.is-blocked .library-level-cell {
  opacity: 0.55;
}

.import-needs-composer {
  flex-basis: 100%;
  font-size: 11px;
  font-weight: 500;
  color: rgba(255, 196, 120, 0.9);
}

/* Pill (and Not the same) on top, the catalog piece's title on its own line
   below, so a long title never squeezes out. */
.library-import-match-cell {
  flex-wrap: wrap;
  row-gap: 4px;
  min-width: 0;
}

.import-match {
  flex: 0 0 auto;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

.import-match--new { background: rgba(90, 169, 255, 0.16); color: #9ccbff; }
.import-match--fill { background: rgba(80, 200, 140, 0.16); color: #8fe0b4; }
.import-match--ambiguous { background: rgba(255, 180, 90, 0.16); color: #ffc98a; }
.import-match--probably { background: rgba(255, 180, 90, 0.16); color: #ffc98a; }

.import-undo {
  margin-left: 8px;
  padding: 3px 12px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.import-undo:hover {
  background: rgba(255, 255, 255, 0.16);
}

.import-not-same {
  order: 3;
  flex: 0 0 auto;
  padding: 3px 9px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--muted);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.import-not-same:hover {
  color: var(--text);
}

/* Library add/edit: "Looks like … already in the library." */
.piece-create-similar {
  flex: 1;
  margin: 0;
  font-size: 13px;
  color: #ffc98a;
}
.import-match--added { background: rgba(80, 200, 140, 0.16); color: #8fe0b4; }
.import-match--rejected { background: rgba(255, 255, 255, 0.08); color: var(--dim); }

.import-match-title {
  order: 2;
  flex-basis: 100%;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  color: var(--muted);
}

/* Where a catalog piece came from, when it was an import rather than a person. */
.library-source-pill {
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(232, 238, 246, 0.85);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

.import-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.import-toolbar .composer-sort-toggles {
  margin: 0;
}

.import-actions {
  display: flex;
  gap: 10px;
}

/* Pieces tab: the delete sits on the right, like Imports' actions. */
.catalog-toolbar {
  justify-content: flex-end;
}

.catalog-toolbar .import-actions {
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.catalog-delete-warning {
  font-size: 13px;
  color: #ffc9c9;
}

.import-filters {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Filter to the imports flagged for review; amber like the flag itself. */
.import-flag-filter {
  height: 34px;
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 180, 90, 0.12);
  color: #ffc98a;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 150ms;
}

.import-flag-filter:hover {
  background: rgba(255, 180, 90, 0.2);
}

.import-flag-filter.active {
  background: #ffb45a;
  color: #14171d;
}

.import-review-note {
  flex-basis: 100%;
  font-size: 11px;
  font-weight: 500;
  color: #ffc98a;
}

.import-message {
  margin: 0 0 14px;
  font-size: 13px;
  color: var(--text);
}

.import-composers {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 16px;
  padding: 14px 16px;
  border-radius: 10px;
  background: rgba(255, 180, 90, 0.07);
}

.import-composers-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.import-composer-search {
  flex: 0 1 260px;
  min-width: 0;
  height: 34px;
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  font: inherit;
  font-size: 13px;
}

.import-composer-search::placeholder {
  color: var(--muted);
}

.import-composer-search:focus {
  outline: 2px solid rgba(0, 122, 255, 0.6);
  outline-offset: 0;
}

.import-composers-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
  color: var(--muted);
}

.import-composers-text strong {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

.import-composer-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.import-composer {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 6px 6px 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
}

.import-composer-name {
  font-size: 13px;
  font-weight: 600;
  color: #f0c040;
}

.import-composer-count {
  font-size: 12px;
  color: var(--muted);
}

/* "Ludovico Einaudi?" — the existing composer this import name probably is. */
.import-composer-guess {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.import-composer-assign {
  height: 30px;
  max-width: 170px;
  padding: 0 10px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}

.import-composer-new {
  height: 30px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.import-composer-new:hover {
  color: var(--text);
}

.import-composer-more {
  align-self: center;
  padding: 0 6px;
  font-size: 12px;
  color: var(--muted);
}

.modal-btn.import-composer-add {
  height: 30px;
  padding: 0 14px;
  font-size: 13px;
}

.config-panel.full {
  min-height: 0;
  padding: 0;
  overflow: hidden;
}

.config-panel:first-child {
  border-color: transparent;
  background: transparent;
  box-shadow: none;
}

.config-panel-toggle {
  display: grid;
  grid-template-columns: 28px 1fr auto;
  align-items: center;
  width: 100%;
  min-height: 66px;
  padding: 0 18px;
  border: 0;
  background: transparent;
  cursor: pointer;
  text-align: left;
}

.config-panel-toggle strong {
  display: block;
  margin-top: 3px;
  font-size: 20px;
}

.config-panel-toggle .chevron {
  transform: rotate(90deg);
}

.config-panel.collapsed .config-panel-toggle .chevron {
  transform: rotate(0deg);
}

.config-panel-body {
  display: grid;
  padding: 0 18px 18px;
  overflow: hidden;
  transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out);
  opacity: 1;
  transform: translateY(0);
}

.config-panel.collapsed .config-panel-body {
  display: none;
  padding-top: 0;
  padding-bottom: 0;
  opacity: 0;
  transform: translateY(-4px);
}

.config-intro {
  margin: -4px 0 18px;
  max-width: 720px;
  color: var(--muted);
  line-height: 1.55;
}

.level-config-list {
  display: grid;
  gap: 6px;
}

.config-control {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  min-height: 72px;
  margin-bottom: 16px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.045);
}

.config-control strong {
  display: block;
  margin-bottom: 4px;
}

.config-control span {
  color: var(--muted);
  font-size: 13px;
}

.theme-control {
  align-items: center;
}

.ios-toggle {
  position: relative;
  display: inline-block;
  width: 51px;
  height: 31px;
  flex-shrink: 0;
}
.ios-toggle input {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
}
.ios-toggle-track {
  position: absolute;
  inset: 0;
  background: #3A3A3C;
  border-radius: 31px;
  transition: background 220ms;
  cursor: pointer;
}
.ios-toggle input:checked + .ios-toggle-track {
  background: #34C759;
}
.ios-toggle-track::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 6px rgba(0,0,0,0.35);
  transition: transform 220ms;
}
.ios-toggle input:checked + .ios-toggle-track::after {
  transform: translateX(20px);
}

.theme-toggle {
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

.theme-toggle button {
  height: 32px;
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 750;
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out), box-shadow 150ms var(--ease-out);
}

.theme-toggle button:hover {
  color: var(--text);
}

.theme-toggle button.active {
  background: rgba(255, 255, 255, 0.16);
  color: var(--text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

.range-control {
  display: grid;
  grid-template-columns: 190px 48px;
  align-items: center;
  gap: 12px;
}

.range-control input {
  accent-color: var(--blue);
}

.range-control output {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.level-config-preview-row:hover {
  transform: none;
}

.level-config-preview-row .mock-composer {
  color: #74adff;
  font-weight: 650;
}

.correspondence-table {
  display: grid;
  gap: 8px;
}

.correspondence-row {
  display: grid;
  grid-template-columns: 150px repeat(4, minmax(150px, 1fr));
  align-items: stretch;
  gap: 8px;
}

.correspondence-row.header {
  position: sticky;
  top: 0;
  z-index: 1;
}

.correspondence-cell {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 7px;
  min-height: 48px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.045);
  color: var(--muted);
  font-size: 13px;
}

.correspondence-row.header .correspondence-cell {
  display: block;
  min-height: 38px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  font-size: 11px;
  font-weight: 750;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.correspondence-cell.level-cell {
  display: flex;
  align-items: center;
  background:
    linear-gradient(90deg, color-mix(in srgb, var(--level-color) var(--degrade-strong), transparent), transparent 66%),
    rgba(255, 255, 255, 0.045);
}

.correspondence-cell.level-cell .level-pill {
  min-width: 92px;
  text-align: center;
}

.correspondence-cell strong {
  color: var(--text);
}

.map-pill {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 5px 9px;
  border: none;
  border-radius: 8px;
  background: var(--pill-color, rgba(255, 255, 255, 0.07));
  color: var(--pill-text, var(--text));
  font-size: 12px;
  font-weight: 720;
  white-space: nowrap;
}

.map-pill:not(.empty) {
  cursor: pointer;
  transition: transform 120ms var(--ease-out), filter 120ms var(--ease-out), background 120ms var(--ease-out);
}

.map-pill:not(.empty):hover {
  transform: translateY(-1px);
}

.map-pill.filterable:hover {
  filter: brightness(1.35) saturate(1.15);
  background: color-mix(in srgb, var(--pill-color, rgba(255,255,255,0.07)) 100%, white 22%);
  transform: translateY(0);
}

.map-pill.empty {
  color: var(--dim);
  font-weight: 650;
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, 0.34);
  z-index: 20;
}

.modal-backdrop[hidden] {
  display: none;
}

#composerEditModal {
  z-index: 22;
}

/* The standard dialog animation. openModal() / closeModal() add
   .modal-entering / .modal-closing to the backdrop, and these three rules turn
   that into the fade and scale. Every dialog panel belongs in this list: a
   panel that is not .mini-modal (the practice-day editor was one) must be
   named here too, or it opens and closes with no animation at all. */
.mini-modal,
.practice-day-editor {
  transition: opacity 260ms cubic-bezier(0.16, 1, 0.3, 1), transform 260ms cubic-bezier(0.16, 1, 0.3, 1);
}

.modal-backdrop.modal-entering .mini-modal,
.modal-backdrop.modal-entering .practice-day-editor {
  opacity: 0;
  transform: scale(0.95);
  transition: none;
}

.modal-backdrop.modal-closing .mini-modal,
.modal-backdrop.modal-closing .practice-day-editor {
  opacity: 0;
  transform: scale(0.95);
  transition-duration: 180ms;
  transition-timing-function: ease-in;
}

#pieceDateModal {
  z-index: 30;
}

#pieceDeleteModal {
  z-index: 25;
}

.mini-modal {
  position: relative;
  width: 340px;
  padding: 22px;
  border: 1px solid var(--line-strong);
  border-radius: var(--dashboard-card-radius);
  background: var(--modal-surface);
  box-shadow: var(--dashboard-glass-shadow);
}

.mini-modal h3 {
  margin: 8px 28px 6px 0;
}

.mini-modal.piece-create-modal {
  width: min(900px, calc(100vw - 48px));
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}

.mini-modal.composer-edit-modal {
  width: min(1120px, calc(100vw - 48px));
  max-height: calc(100vh - 48px);
  overflow-x: hidden;
  overflow-y: auto;
}

.piece-create-modal .piece-create-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 0.9fr);
  align-items: start;
  column-gap: 22px;
  row-gap: 0;
  margin-top: 18px;
}

.calendar-modal {
  width: 390px;
  height: 440px;
  padding: 28px 22px 22px;
}

.calendar-action-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 28px;
}

.calendar-action-button {
  position: relative;
  display: grid;
  width: 38px;
  height: 38px;
  place-items: center;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--muted);
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition: border-color 150ms var(--ease-out), background 150ms var(--ease-out), color 150ms var(--ease-out);
}

.calendar-action-button:hover {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.09);
  color: var(--text);
}

.calendar-modal .close-inspector.calendar-action-button {
  position: relative;
  top: auto;
  right: auto;
}

.calendar-modal .close-inspector.calendar-action-button::before,
.calendar-modal .close-inspector.calendar-action-button::after {
  left: 12px;
  top: 18px;
  width: 14px;
}

.mini-modal .close-inspector.modal-close-pill {
  width: 38px;
  height: 38px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.055);
  color: var(--muted);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition: border-color 150ms var(--ease-out), background 150ms var(--ease-out), color 150ms var(--ease-out);
}

.mini-modal .close-inspector.modal-close-pill:hover {
  border-color: var(--line-strong);
  background: rgba(255, 255, 255, 0.09);
  color: var(--text);
}

.mini-modal .close-inspector.modal-close-pill::before,
.mini-modal .close-inspector.modal-close-pill::after {
  left: 12px;
  top: 18px;
  width: 14px;
}

.calendar-confirm-button {
  border-color: rgba(123, 183, 255, 0.38);
  color: var(--blue);
}

.calendar-confirm-button:hover {
  border-color: rgba(123, 183, 255, 0.62);
  background: rgba(123, 183, 255, 0.12);
  color: #a9d0ff;
}

.calendar-confirm-button svg {
  width: 21px;
  height: 21px;
}

.calendar-confirm-button path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.calendar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin: 4px 0 0;
  padding: 0 17px;
}

.calendar-title-button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  cursor: pointer;
  font-size: 24px;
  font-weight: 640;
  line-height: 1.2;
  text-align: left;
  white-space: nowrap;
}

.calendar-title-button svg {
  width: 13px;
  height: 13px;
  color: var(--blue);
  transition: transform 150ms var(--ease-out), color 150ms var(--ease-out);
}

.calendar-title-button path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.calendar-title-button:hover svg {
  color: #a9d0ff;
}

.calendar-title-button.open svg {
  transform: rotate(180deg);
}

.calendar-nav-group {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}

.calendar-head .calendar-nav-button {
  background: transparent;
  color: var(--blue);
}

.calendar-head .calendar-nav-button svg {
  width: 24px;
  height: 24px;
}

.calendar-head .calendar-nav-button path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.calendar-head .calendar-nav-button:hover {
  background: transparent;
  color: #a9d0ff;
}

.circle-button {
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text);
  cursor: pointer;
  font-size: 22px;
}

.circle-button:hover {
  background: rgba(255, 255, 255, 0.12);
}

.start-calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  min-height: 260px;
  margin-top: 22px;
}

.start-calendar-grid.month-selector-grid {
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  align-content: start;
  padding: 4px 17px 0;
}

.start-calendar-grid.calendar-fade {
  animation: calendarFade 160ms var(--ease-out) both;
}

@keyframes calendarFade {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.calendar-month-option {
  display: grid;
  height: 42px;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 750;
}

.calendar-month-option:hover {
  color: var(--blue);
}

.calendar-month-option.selected {
  background: rgba(123, 183, 255, 0.12);
  color: var(--blue);
}

.start-calendar-label,
.start-calendar-day {
  display: grid;
  min-height: 34px;
  place-items: center;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 750;
  font-variant-numeric: tabular-nums;
}

.start-calendar-label {
  min-height: 20px;
  color: var(--dim);
}

.start-calendar-day {
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  justify-self: center;
}

.start-calendar-day:hover {
  color: var(--blue);
}

.start-calendar-day.selected {
  border: 0;
  background: rgba(123, 183, 255, 0.12);
  color: var(--blue);
  box-shadow: none;
  text-shadow: none;
}

.start-calendar-day.empty {
  visibility: hidden;
}

.modal-field {
  display: grid;
  gap: 8px;
  margin-top: 18px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
}

.time-fields {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
}

.time-fields .modal-field {
  min-width: 0;
  width: 100%;
  display: grid;
  gap: 8px;
}

.time-fields .modal-field span {
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.time-fields input {
  min-width: 0;
  width: 100%;
  height: 80px;
  padding: 0 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  outline: 0;
  background: rgba(0, 0, 0, 0.22);
  color: var(--text);
  font-size: 38px;
  font-weight: 700;
  text-align: center;
  box-sizing: border-box;
}

.time-fields input:focus {
  border-color: rgba(123, 183, 255, 0.7);
  box-shadow: 0 0 0 3px rgba(123, 183, 255, 0.14);
}

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 18px;
}

.composer-edit-form .modal-actions .danger-button {
  margin-right: auto;
}

.practice-editor-backdrop {
  background: rgba(0, 0, 0, 0.42);
}

.practice-day-editor {
  position: relative;
  width: 420px;
  min-height: 210px;
  padding: 24px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--modal-surface);
  backdrop-filter: blur(20px) saturate(1.08);
  -webkit-backdrop-filter: blur(20px) saturate(1.08);
  box-shadow: var(--dashboard-glass-shadow);
  animation: practiceZoom 180ms var(--ease-out) both;
}

.practice-day-editor h3 {
  margin: 8px 28px 8px 0;
  font-size: 34px;
}

.modal-field input[type="number"] {
  height: 42px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  outline: 0;
  background: rgba(0, 0, 0, 0.18);
  color: var(--text);
  font-size: 18px;
}

.time-fields .modal-field input[type="number"] {
  height: 80px;
  padding: 0 18px;
  border-radius: 12px;
  font-size: 38px;
  font-weight: 700;
  text-align: center;
}

.modal-field input[type="number"]:focus {
  border-color: rgba(123, 183, 255, 0.7);
  box-shadow: 0 0 0 3px rgba(123, 183, 255, 0.14);
}

/* Practice day: Apple-timer style. No boxes; big heavy numerals with the
   unit beside them, centred. A faint tint marks the field only while it is
   being typed in. ID-scoped with !important because the mobile no-zoom rule
   forces every field to 16px with !important (anything 16px or larger is
   safe from zoom, so this is too). */
#practiceDayModal .time-fields {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 18px;
  margin: 26px 0 6px;
}

#practiceDayModal .time-fields .modal-field {
  display: flex;
  align-items: baseline;
  gap: 4px;
  width: auto;
  margin: 0;
}

#practiceDayModal .time-fields .modal-field span {
  color: var(--muted);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

#practiceDayModal .time-fields input[type="number"] {
  /* Fitted to the digits by fitTimeInput in app.js; this is the fallback. */
  width: 2ch;
  height: auto;
  padding: 0 4px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  box-shadow: none;
  color: var(--text);
  font-size: 64px !important;
  font-weight: 800;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
  box-sizing: content-box;
}

#practiceDayModal .time-fields input[type="number"]::-webkit-inner-spin-button,
#practiceDayModal .time-fields input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

#practiceDayModal .time-fields input[type="number"]:focus {
  border: 0;
  background: rgba(255, 255, 255, 0.07);
  box-shadow: none;
}

/* Quick-duration pills beside the save check: two rows of three, equal
   width, so all six are visible at once (a single row did not fit, and
   hid 2h and 3h behind a sideways scroll). The check sits level with the
   bottom row. */
#practiceDayModal .practice-day-actions {
  align-items: flex-end;
  gap: 14px;
}

.practice-presets {
  display: grid;
  flex: 1;
  min-width: 0;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.practice-preset {
  height: 38px;
  padding: 0 8px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.09);
  color: var(--text);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out);
}

.practice-preset:hover {
  background: rgba(255, 255, 255, 0.14);
}

.practice-preset.is-active {
  background: #007AFF;
  color: #fff;
}

@keyframes practiceZoom {
  from {
    opacity: 0;
    transform: scale(0.88) translateY(12px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

.dashboard-wallpaper {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-size: cover;
  background-position: center;
  display: none;
}

.app-shell:has(#dashboard.active) .dashboard-wallpaper.has-wallpaper {
  display: block;
}

.app-shell:has(.dashboard-wallpaper.has-wallpaper):has(#dashboard.active) .workspace {
  background: radial-gradient(ellipse 80% 60% at 85% 10%, rgba(50, 90, 200, 0.12), transparent);
}

.wallpaper-setting {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 4px 0;
}

.wallpaper-preview {
  width: 100%;
  height: 160px;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background-size: cover;
  background-position: center;
  background-color: rgba(255, 255, 255, 0.04);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.wallpaper-preview-empty {
  color: var(--dim);
  font-size: 13px;
}

.wallpaper-actions {
  display: flex;
  gap: 10px;
}

/* ── Exercises page ───────────────────────────────────────────────── */
#exercises {
  scrollbar-width: none;
}

#exercises::-webkit-scrollbar {
  display: none;
}

.exercise-filter-row {
  padding: 4px 0 12px;
}

.exercises-page {
  padding-top: 8px;
  padding-bottom: 40px;
}

.exercise-collection {
  margin-bottom: 16px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.025);
  padding: 18px 18px 16px;
  /* Don't render/paint collections that are scrolled out of view — with many
     collections this slashes the style-recalc/paint cost of every interaction. */
  content-visibility: auto;
  contain-intrinsic-size: auto 220px;
}

.exercise-item {
  /* Scope each box's layout/paint so hovering/checking one doesn't invalidate
     the whole grid of (potentially hundreds of) buttons. */
  contain: layout paint;
}

.exercise-collection-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 12px;
}

.exercise-collection-info {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.exercise-collection-title {
  font-size: 20px;
  font-weight: 600;
  color: var(--text);
}

[data-completed="true"] .exercise-collection-title {
  color: var(--dim);
  font-weight: 500;
}

.exercise-author {
  font-size: 13px;
  font-weight: 650;
  color: #74adff;
}

.exercise-header-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.exercise-completed-pill {
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.02em;
  color: #4f8dff;
  background: rgba(79, 141, 255, 0.13);
  border: 1px solid rgba(79, 141, 255, 0.26);
  border-radius: 999px;
  padding: 2px 9px;
  white-space: nowrap;
}

.exercise-collection-count {
  font-weight: 700;
  color: var(--muted);
  opacity: 0.7;
  display: flex;
  align-items: baseline;
  gap: 1px;
}

.exercise-count-done {
  font-size: 18px;
  color: var(--text);
}

.exercise-count-done.completed {
  color: #4f8dff;
}

.exercise-count-sep {
  font-size: 13px;
}

.exercise-count-total {
  font-size: 15px;
}

.exercise-section-divider {
  margin: 22px 0 16px;
}

.exercise-section-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--dim);
  font-size: 14px;
  font-weight: 650;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 0;
  width: 100%;
}

.exercise-section-toggle::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

.exercise-section-label {
  white-space: nowrap;
}

.exercise-section-count {
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  font-size: 16px;
}

.exercise-completed-wrapper.collapsed {
  display: none;
}

.exercise-star-btn {
  background: none;
  border: none;
  padding: 2px 4px;
  cursor: pointer;
  color: var(--muted);
  opacity: 0;
  transition: opacity 150ms ease, color 150ms ease;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.exercise-collection-header:hover .exercise-star-btn,
.exercise-star-btn.starred {
  opacity: 1;
}

.exercise-star-btn.starred {
  color: #f5c542;
}

.exercise-star-btn:hover {
  color: #f5c542;
}

.exercise-collapse-btn {
  background: none;
  border: none;
  color: var(--muted);
  padding: 4px;
  cursor: pointer;
  opacity: 0.45;
  transition: opacity 0.15s, transform 0.2s var(--ease-out);
  display: flex;
  align-items: center;
}

.exercise-collection-header:hover .exercise-collapse-btn {
  opacity: 0.7;
}

.exercise-collapse-btn:hover {
  opacity: 1 !important;
}

.exercise-collection.collapsed .exercise-collapse-btn {
  transform: rotate(-90deg);
}

.exercise-items-wrapper {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.exercise-collection.collapsed .exercise-items-wrapper {
  grid-template-rows: 0fr;
}

.exercise-items-wrapper > .exercise-items {
  overflow: hidden;
  min-height: 0;
}

.exercise-edit-collection-btn {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 14px;
  line-height: 1;
  padding: 2px 4px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s;
}

.exercise-collection-header:hover .exercise-edit-collection-btn {
  opacity: 0.45;
}

.exercise-edit-collection-btn:hover {
  opacity: 1 !important;
}

.exercise-edit-actions {
  justify-content: space-between;
}

.exercise-edit-right-actions {
  display: flex;
  gap: 8px;
}

.exercise-delete-confirm-text {
  margin: 16px 0 12px;
  font-size: 14px;
  color: var(--muted);
}

#exerciseEditComposerMenu {
  position: fixed !important;
  min-width: unset;
  z-index: 200;
  max-height: 220px;
  overflow-y: auto;
  display: none;
}

#exerciseEditComposerCustomSelect.open #exerciseEditComposerMenu {
  display: block;
}

.exercise-progress-bar {
  height: 3px;
  background: rgba(255, 255, 255, 0.07);
  border-radius: 2px;
  margin: 0 0 14px 0;
  overflow: hidden;
}

.exercise-progress-fill {
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, #1a6fd4, #4f9eff);
  transition: width 0.45s cubic-bezier(0.34, 1.3, 0.64, 1);
}

.exercise-collection[data-completed="true"] .exercise-progress-fill {
  background: linear-gradient(90deg, #1a9a6a, #34c889);
}


.exercise-items {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.exercise-item {
  width: var(--exercise-item-w, 66px);
  height: 36px;
  border-radius: 8px;
  outline: none;
  border: 1.5px solid transparent;
  background: rgba(255, 255, 255, 0.06);
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: none;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

/* .exercise-item:hover {
  color: var(--text);
  background: rgba(255, 255, 255, 0.11);
} */

.exercise-item.active {
  background: rgba(0, 0, 0, 0.5);
  border: none;
  box-shadow:
    inset 0 2px 5px rgba(0, 0, 0, 0.45),
    inset 0 1px 2px rgba(0, 0, 0, 0.3);
  color: rgba(255, 255, 255, 0.08);
  /* No bg fade so the centre-fill animation hands off to the final state cleanly. */
  transition: none;
}

.exercise-item.active:not(.pending-undo)::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23e8f1ff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.4 4.2L19 7.3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 22px 22px;
  border-radius: 8px;
}

/* .exercise-item.active:not(.pending-undo):hover::after {
  background-color: rgba(0, 0, 0, 0.6);
} */

/* V1 UNDO ANIMATION — deactivated for performance testing
@keyframes ex-undo-timer {
  from { width: calc(100% - 6px); }
  to   { width: 0%; }
}

.exercise-item.pending-undo {
  border-color: rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.07);
  color: var(--text);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.exercise-item.pending-undo::after {
  content: "";
  position: absolute;
  bottom: 3px;
  left: 3px;
  height: 2px;
  border-radius: 1px;
  background: rgba(255, 255, 255, 0.45);
  animation: ex-undo-timer 1s linear forwards;
  font-size: 0;
  top: unset;
  right: unset;
  opacity: 1;
}
*/

@keyframes ex-pop {
  0%   { transform: scale(1); }
  18%  { transform: scale(0.86); }
  48%  { transform: scale(1.18); }
  68%  { transform: scale(0.96); }
  84%  { transform: scale(1.06); }
  100% { transform: scale(1); }
}

@keyframes ex-glow {
  0%   { box-shadow: 0 0 0 0   rgba(79, 141, 255, 0.7); }
  40%  { box-shadow: 0 0 0 7px rgba(79, 141, 255, 0.22); }
  100% { box-shadow: 0 0 0 14px rgba(79, 141, 255, 0); }
}

@keyframes ex-check-in {
  0%   { opacity: 0; transform: scale(0) rotate(-40deg); }
  55%  { opacity: 1; transform: scale(1.6) rotate(8deg); }
  100% { opacity: 0.7; transform: scale(1) rotate(0deg); }
}

@keyframes ex-particle-fly {
  0%   { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  100% { transform: translate(calc(-50% + var(--tx)), calc(-50% + var(--ty))) scale(0); opacity: 0; }
}

.exercise-item.active.just-checked {
  overflow: hidden;
  background: rgba(255, 255, 255, 0.06);
  box-shadow: none;
  animation: ex-stretch 0.32s cubic-bezier(0.34, 1.3, 0.64, 1) forwards;
}

@keyframes ex-stretch {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.25); }
  100% { transform: scale(1); }
}

.exercise-item.active.just-checked::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 110px;
  height: 110px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.5);
  transform: translate(-50%, -50%) scale(0);
  animation: ex-fill 0.26s ease-out forwards;
}

@keyframes ex-fill {
  to { transform: translate(-50%, -50%) scale(1); }
}


.exercise-particle {
  position: fixed;
  border-radius: 50%;
  pointer-events: none;
  z-index: 9999;
  transform: translate(-50%, -50%);
  will-change: transform, opacity;
  animation: ex-particle-fly 0.52s cubic-bezier(0, 0.9, 0.57, 1) forwards;
}

.exercise-add-area {
  margin-bottom: 28px;
}

/* Exercise collection modal fields */
#exerciseCollectionForm input[type="text"],
#exerciseCollectionForm input[type="number"],
#exerciseEditForm input[type="text"],
#exerciseEditForm input[type="number"] {
  width: 100%;
  height: 40px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.22);
  color: var(--text);
  font: inherit;
  outline: none;
  transition: border-color 0.15s;
}

#exerciseCollectionForm input[type="text"]:focus,
#exerciseCollectionForm input[type="number"]:focus,
#exerciseEditForm input[type="text"]:focus,
#exerciseEditForm input[type="number"]:focus {
  border-color: rgba(116, 173, 255, 0.45);
}

.exercise-composer-btn {
  width: 100%;
  height: 40px;
  padding: 0 12px 0 12px;
  border: 1px solid var(--line) !important;
  border-radius: 8px !important;
  background: rgba(0, 0, 0, 0.22) !important;
  box-shadow: none !important;
  justify-content: space-between;
  transition: border-color 0.15s;
}

.exercise-composer-btn:focus,
#exerciseComposerCustomSelect.open .exercise-composer-btn {
  border-color: rgba(116, 173, 255, 0.45) !important;
}

.exercise-composer-btn strong {
  font-size: 14px !important;
  font-weight: 400;
  color: var(--muted);
}

#exerciseComposerCustomSelect.open .exercise-composer-btn .chevron {
  transform: rotate(180deg);
}

#exerciseComposerMenu {
  position: fixed !important;
  min-width: unset;
  z-index: 200;
  max-height: 220px;
  overflow-y: auto;
  display: none;
}

#exerciseComposerCustomSelect.open #exerciseComposerMenu {
  display: block;
}

#exerciseCountInput,
#exerciseEditCountInput {
  height: 72px !important;
  font-size: 42px !important;
  font-weight: 800 !important;
  text-align: center;
  padding: 0 !important;
  letter-spacing: -1px;
}

.exercise-add-btn {
  height: 38px;
  padding: 0 20px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  color: var(--muted);
  font-size: 13px;
  font-weight: 750;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.exercise-add-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.2);
  color: var(--text);
}



.exercises-empty {
  color: var(--muted);
  font-size: 15px;
  padding: 16px 0;
}

/* === Codex restoration layer, May 25 === */

.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: unset;
  padding: 7px 12px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--muted);
  font-size: 14px;
}

.nav-icon {
  display: grid;
  place-items: center;
  flex: 0 0 28px;
  width: 28px;
  height: 28px;
  color: #2d83ff;
}

.nav-icon svg {
  width: 24px;
  height: 24px;
  display: block;
}

.nav-item:hover .nav-icon {
  color: #5fa8ff;
}

.nav-item.active .nav-icon {
  color: #2d83ff;
}

.piece-create-form .piece-create-identity-group,
.piece-create-form .piece-create-date-group {
  display: grid !important;
  gap: 0 !important;
  overflow: hidden !important;
  border: 0 !important;
  border-radius: var(--dashboard-card-radius) !important;
  background: rgba(0, 0, 0, 0.18) !important;
  box-shadow: none !important;
}

.piece-create-form .piece-create-identity-group label,
.piece-create-form .piece-create-date-group label,
.piece-create-form .piece-create-identity-group .custom-select,
.piece-create-form .piece-create-date-group .custom-select {
  display: block !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
}

.piece-create-form .piece-create-identity-group label + label,
.piece-create-form .piece-create-date-group label + label {
  border-top: 1px solid var(--line) !important;
}

.piece-create-form .piece-create-identity-group input,
.piece-create-form .piece-create-identity-group .custom-select-button,
.piece-create-form .piece-create-date-group .date-select-button {
  width: 100% !important;
  height: 68px !important;
  min-height: 68px !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

.piece-create-form .piece-create-identity-group .custom-select.open .custom-select-button,
.piece-create-form .piece-create-date-group .date-select-button:focus {
  box-shadow: none !important;
}

.mini-modal.piece-create-modal,
.piece-create-modal {
  overflow: visible !important;
}

.piece-create-level-column,
.piece-create-level-column .supporting-rating-field,
.piece-create-level-column .custom-select {
  overflow: visible !important;
}

.piece-create-level-column .custom-select-menu {
  position: absolute !important;
  z-index: 80 !important;
  max-height: none !important;
  overflow: visible !important;
}

.piece-create-level-column .supporting-rating-field:nth-of-type(4) .custom-select-menu,
.piece-create-level-column .supporting-rating-field:nth-of-type(5) .custom-select-menu {
  top: auto !important;
  bottom: calc(100% + 8px) !important;
}

.custom-select-option.stage-status-option .stage-status.Recorded,
.piece-create-form .custom-select-button .stage-status.Recorded {
  width: auto !important;
  font-size: 13px !important;
  transform: none !important;
}

.custom-select-option.stage-status-option .stage-status.Recorded i,
.piece-create-form .custom-select-button .stage-status.Recorded i {
  display: inline-block !important;
}

.mini-modal.piece-create-modal,
.piece-create-modal {
  overflow: visible !important;
}

.piece-create-level-column,
.piece-create-level-column .supporting-rating-field,
.piece-create-level-column .custom-select {
  overflow: visible !important;
}

.piece-create-level-column .custom-select-menu {
  position: absolute !important;
  z-index: 80 !important;
  max-height: none !important;
  overflow: visible !important;
}

.piece-create-level-column .supporting-rating-field:nth-of-type(4) .custom-select-menu,
.piece-create-level-column .supporting-rating-field:nth-of-type(5) .custom-select-menu {
  top: auto !important;
  bottom: calc(100% + 8px) !important;
}

.piece-create-form .supporting-rating-field .rating-star-button {
  right: 20px !important;
}

.piece-create-form .supporting-rating-field .custom-select-button {
  padding-right: 86px !important;
}

.piece-create-form .supporting-rating-field .custom-select-button .chevron {
  margin-left: auto;
  margin-right: 44px;
}

.supporting-rating-field .rating-star-button {
  z-index: 3;
}

.piece-create-form .piece-create-identity-group,
.piece-create-form .piece-create-date-group {
  display: grid !important;
  gap: 0 !important;
  overflow: hidden !important;
  border: 0 !important;
  border-radius: var(--dashboard-card-radius) !important;
  background: rgba(0, 0, 0, 0.18) !important;
  box-shadow: none !important;
}

.piece-create-form .piece-create-identity-group label,
.piece-create-form .piece-create-date-group label,
.piece-create-form .piece-create-identity-group .custom-select,
.piece-create-form .piece-create-date-group .custom-select {
  display: block !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
}

.piece-create-form .piece-create-identity-group label + label,
.piece-create-form .piece-create-date-group label + label {
  border-top: 1px solid var(--line) !important;
}

.piece-create-form .piece-create-identity-group input,
.piece-create-form .piece-create-identity-group .custom-select-button,
.piece-create-form .piece-create-date-group .date-select-button {
  width: 100% !important;
  height: 68px !important;
  min-height: 68px !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

.piece-create-form .piece-create-identity-group .custom-select.open .custom-select-button {
  box-shadow: none !important;
}

.level-filter-row {
  display: grid !important;
  /* pills + count grouped on the left, flexible spacer, controls on the right */
  grid-template-columns: minmax(0, auto) auto 1fr auto auto auto !important;
  align-items: center !important;
  gap: 16px !important;
}

.level-filter-row .level-filter-pills {
  grid-column: 1;
}

.level-filter-row .level-filter-count {
  grid-column: 2;
  justify-self: start;
}

.level-filter-row .composer-sort-toggles {
  grid-column: 4;
  justify-self: end;
  width: auto !important;
  margin: 0 !important;
}

.level-filter-row .recent-sort-toggle {
  grid-column: 5;
  justify-self: end;
  width: auto !important;
  min-width: 154px;
  max-width: max-content;
}

.level-filter-row #piecesViewToggle {
  grid-column: 6;
  justify-self: end;
  width: auto !important;
  margin: 0 !important;
}

.piece-row {
  grid-template-columns: 86px minmax(0, 1fr) 200px 108px max-content 38px !important;
  gap: 14px !important;
  min-height: 70px;
  padding: 7px 20px 7px 34px !important;
}

.piece-level-marker {
  justify-self: start;
  transform: none !important;
}

.piece-copy {
  min-width: 0;
  transform: none !important;
}

.piece-source {
  justify-self: center;
  max-width: 200px;
  white-space: nowrap;
}

.stage-status {
  justify-self: end;
}

.piece-open-icon {
  width: 38px !important;
}

.piece-create-identity-group,
.piece-create-date-group {
  display: grid !important;
  overflow: hidden !important;
  gap: 0 !important;
  border-radius: var(--dashboard-card-radius) !important;
  background: rgba(0, 0, 0, 0.18) !important;
}

.piece-create-identity-group label,
.piece-create-date-group label {
  margin: 0 !important;
  border-radius: 0 !important;
}

.piece-create-identity-group label + label,
.piece-create-date-group label + label {
  border-top: 1px solid var(--line) !important;
}

.piece-create-identity-group input,
.piece-create-identity-group .custom-select-button,
.piece-create-date-group .date-select-button {
  border-radius: 0 !important;
  background: transparent !important;
}

.piece-create-identity-group input,
.piece-create-identity-group .custom-select-button,
.piece-create-date-group .date-select-button,
.piece-create-column > label > .custom-select .custom-select-button {
  min-height: 68px !important;
  height: 68px !important;
}

.piece-create-date-group .date-select-content {
  justify-content: flex-start;
}

.piece-create-date-group .date-select-value {
  margin-left: 16px;
}

.level-select-field .custom-select-menu,
.piece-create-level-column .custom-select-menu {
  grid-template-columns: repeat(4, max-content) !important;
  align-items: center;
  justify-content: start;
  gap: 10px 12px !important;
  width: max-content;
  max-width: min(760px, calc(100vw - 80px));
  padding: 14px !important;
}

.level-select-field .custom-select-option.source-tag-option,
.piece-create-level-column .custom-select-option.source-tag-option {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-width: 0;
  height: auto;
  min-height: 34px;
  padding: 0;
  border-radius: 999px;
  background: transparent;
}

.level-select-field .custom-select-option.source-tag-option.empty,
.piece-create-level-column .custom-select-option.source-tag-option.empty {
  min-width: 88px;
  height: 34px;
  padding: 0 18px;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--text);
  font-weight: 750;
}

.level-select-field .custom-select-option.source-tag-option.active.empty,
.piece-create-level-column .custom-select-option.source-tag-option.active.empty {
  background: rgba(123, 183, 255, 0.16);
}

.level-select-field .custom-select-option.source-tag-option:hover,
.level-select-field .custom-select-option.source-tag-option.active,
.piece-create-level-column .custom-select-option.source-tag-option:hover,
.piece-create-level-column .custom-select-option.source-tag-option.active {
  background: transparent;
}

.custom-select-button .map-pill,
.source-tag-option .map-pill {
  margin: 0;
}

.custom-select-button .map-pill {
  display: inline-flex;
}

.sidebar-card {
  border-radius: var(--dashboard-card-radius);
}

.sidebar-card strong {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
}

.sidebar-card strong small {
  color: rgba(166, 175, 188, 0.72);
  font-size: 0.55em;
  font-weight: 750;
}

.sidebar-month-progress {
  display: block;
  width: 100%;
  height: 7px;
  margin: 12px 0 10px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
}

.sidebar-month-progress span {
  display: block !important;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #2d83ff, #7bb7ff);
}

.workspace > .topbar,
.workspace > .view {
  transition: opacity 90ms var(--ease-out), transform 90ms var(--ease-out);
  transform-origin: center 42%;
}

/* Fade out: topbar just fades; the view fades while easing slightly back. */
.workspace.page-fading-out > .topbar {
  opacity: 0;
}

.workspace.page-fading-out > .view.active {
  opacity: 0;
  transform: scale(0.985);
}

/* Fade in (Apple TV style): subtle zoom-in as the page fades up. */
.workspace.page-fading-in > .topbar {
  animation: pageFadeIn 150ms var(--ease-out) both;
}

.workspace.page-fading-in > .view.active {
  animation: pageZoomIn 170ms cubic-bezier(0.22, 0.7, 0.3, 1) both;
}

/* Composer detail holds a position:fixed portrait; a transform on this view
   would re-anchor that portrait and make it flick into place. Fade only, no
   zoom/transform, for this page. */
.workspace.page-fading-out > #composer-detail.active {
  transform: none;
}

.workspace.page-fading-in > #composer-detail.active {
  animation: pageFadeIn 150ms var(--ease-out) both;
}

@keyframes pageFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes pageZoomIn {
  from {
    opacity: 0;
    transform: scale(0.97);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.modal-backdrop:not([hidden]):not(.modal-closing) .mini-modal,
.modal-backdrop:not([hidden]):not(.modal-closing) .practice-day-editor {
  animation: modalPop 180ms var(--ease-out) both;
}

.modal-backdrop.modal-closing {
  pointer-events: none;
}

.modal-backdrop.modal-closing .mini-modal,
.modal-backdrop.modal-closing .practice-day-editor {
  animation: modalPopOut 180ms var(--ease-out) both;
}

@keyframes modalPopOut {
  from {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  to {
    opacity: 0;
    transform: translateY(10px) scale(0.94);
  }
}

.mini-modal,
.practice-day-editor {
  border-radius: var(--dashboard-card-radius);
  background: var(--modal-surface, #1c2027);
  box-shadow: var(--dashboard-glass-shadow, 0 22px 70px rgba(0, 0, 0, 0.4));
}

.mini-modal .close-inspector.modal-close-pill,
.calendar-action-button {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--muted);
}

.mini-modal .close-inspector.modal-close-pill::before,
.mini-modal .close-inspector.modal-close-pill::after,
.calendar-modal .close-inspector.calendar-action-button::before,
.calendar-modal .close-inspector.calendar-action-button::after {
  left: 12px;
  top: 18px;
  width: 14px;
}

.practice-stat-card {
  position: relative;
}

.practice-objective-card strong {
  display: inline-flex !important;
  align-items: baseline;
  gap: 6px;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  white-space: nowrap;
}

.practice-objective-card strong .objective-period {
  display: inline !important;
  margin: 0 !important;
  line-height: 1;
  text-transform: none !important;
  white-space: nowrap;
}

.practice-objective-card strong .objective-period {
  color: rgba(166, 175, 188, 0.72) !important;
  font-size: 0.68em !important;
  font-weight: 750;
}

.objective-edit-button {
  position: absolute !important;
  right: 14px;
  bottom: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 54px;
  height: 28px;
  padding: 0 12px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px !important;
  background: rgba(255, 255, 255, 0.06);
  color: var(--muted);
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 750;
  line-height: 1;
}

.objective-edit-button:hover {
  border-color: rgba(90, 169, 255, 0.42);
  background: rgba(90, 169, 255, 0.16);
  color: #9ccfff;
}

.practice-objective-modal {
  width: min(440px, calc(100vw - 48px));
}

.practice-objective-modal h3 {
  margin: 0 58px 22px 8px;
  font-size: 26px;
}

.objective-time-fields {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
}

.objective-time-fields label {
  display: grid;
  gap: 8px;
  min-width: 0;
}

.objective-time-fields span {
  color: var(--muted);
  font-size: 14px;
  font-weight: 700;
  text-transform: none;
}

.objective-time-fields input {
  width: 100%;
  min-width: 0;
  height: 54px;
  padding: 0 18px;
  border: 0;
  border-radius: var(--dashboard-card-radius);
  outline: 0;
  background: rgba(0, 0, 0, 0.18);
  color: var(--text);
  font-size: 22px;
  font-weight: 700;
}

.objective-period-toggle {
  display: inline-flex;
  gap: 3px;
  width: 100%;
  margin-top: 14px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
}

.objective-period-toggle button {
  flex: 1;
  height: 38px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 750;
}

.objective-period-toggle button.active {
  background: rgba(255, 255, 255, 0.16);
  color: #74adff;
}

.objective-save-button,
#saveComposerEdit.ready,
#saveComposerEdit:not(:disabled) {
  border: 1px solid rgba(90, 169, 255, 0.58) !important;
  border-radius: 999px !important;
  background: rgba(90, 169, 255, 0.24) !important;
  color: #c9e4ff !important;
}

.recent-sort-toggle {
  height: 38px;
  padding: 0 22px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--muted);
  cursor: pointer;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 13px;
  font-weight: 500;
  transition: border-color 150ms var(--ease-out), background 150ms var(--ease-out), color 150ms var(--ease-out), opacity 250ms ease;
}

.recent-sort-toggle:disabled {
  opacity: 0.3;
  cursor: default;
}

.recent-sort-toggle.active {
  border-color: #007AFF;
  background: #007AFF;
  color: #fff;
}

.recent-sort-toggle:not(:disabled):active,
.recent-sort-toggle.tap {
  transform: scale(0.93);
}

@keyframes recent-sort-press {
  0%   { transform: scale(0.93); }
  55%  { transform: scale(1.04); }
  100% { transform: scale(1); }
}

.recent-sort-toggle.tap {
  animation: recent-sort-press 320ms cubic-bezier(0.34, 1.3, 0.64, 1) forwards;
}

.recent-sort-toggle:disabled,
.recent-sort-toggle.disabled,
.recent-sort-toggle:disabled:hover,
.recent-sort-toggle.disabled:hover {
  border-color: rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.035);
  color: rgba(166, 175, 188, 0.45);
  cursor: default;
}

.level-filter-row {
  align-items: center;
}

.piece-added-backdrop {
  inset: 0 auto auto 0;
  display: none;
  width: 100vw;
  height: 100vh;
  min-width: 0;
  align-items: center;
  justify-content: center;
  background: rgba(7, 10, 16, 0.42);
}

.piece-added-backdrop:not([hidden]) {
  display: flex;
}

.piece-added-modal {
  display: grid;
  justify-items: center;
  width: min(420px, calc(100vw - 36px));
  min-height: 0;
  padding: 34px 36px 30px;
  gap: 14px;
  text-align: center;
}

.piece-added-mark {
  display: grid;
  place-items: center;
  width: 82px;
  height: 82px;
  border: 1px solid rgba(90, 169, 255, 0.6);
  border-radius: 999px;
  background: rgba(90, 169, 255, 0.18);
  color: #8fc7ff;
}

.piece-added-mark svg {
  width: 42px;
  height: 42px;
}

.piece-added-mark path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.piece-added-modal h3 {
  margin: 8px 0 0;
  font-size: 30px;
}

.piece-added-modal p {
  margin: 0;
  color: var(--muted);
  font-size: 16px;
}

.piece-added-close {
  min-width: 140px;
  margin-top: 10px;
}

.mini-modal.piece-create-modal,
.piece-create-modal {
  width: min(900px, calc(100vw - 48px)) !important;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}

.piece-create-head {
  display: flex;
  align-items: center;
  gap: 22px;
  margin: 0 58px 24px 12px;
}

.piece-create-head h3,
.piece-create-modal #pieceCreateTitle {
  margin: 0;
  font-size: 28px;
  line-height: 1.1;
}

.piece-create-level-preview {
  flex: 0 0 auto;
}

.piece-create-form {
  display: grid !important;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 0.9fr);
  align-items: start;
  column-gap: 22px;
  row-gap: 0;
  margin-top: 0;
}

.piece-create-column {
  display: grid;
  gap: 12px;
  min-width: 0;
}

.piece-create-level-column {
  display: grid;
  gap: 12px;
  padding-left: 22px;
  border-left: 1px solid var(--line);
}

.piece-create-level-header {
  display: flex;
  align-items: center;
  gap: 16px;
  color: var(--muted);
}

.piece-create-level-header h4 {
  margin: 0;
  color: var(--muted);
  font-size: 18px;
}

.piece-create-form .modal-actions {
  grid-column: 1 / -1;
}

.piece-create-form label,
.exercise-collection-form label,
.composer-edit-form label {
  position: relative;
}

.piece-create-form .field-label,
.exercise-collection-form .field-label,
.composer-edit-form label > span:not(.portrait-upload-label),
.activity-period > span,
.composer-era-field > span {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.piece-create-form input,
.piece-create-form .custom-select-button,
.piece-create-form .date-select-button,
.composer-edit-form input,
.composer-edit-form .custom-select-button,
.composer-edit-form .portrait-upload-button,
.exercise-collection-form input,
.exercise-composer-field {
  width: 100%;
  height: 54px !important;
  padding: 0 18px !important;
  border: 0 !important;
  border-radius: var(--dashboard-card-radius) !important;
  outline: 0;
  background: rgba(0, 0, 0, 0.18) !important;
  color: var(--text);
  font-size: 16px;
  font-weight: 600;
  box-shadow: none;
}

.piece-create-form input::placeholder,
.piece-create-form .custom-select-button strong,
.date-select-label,
.composer-edit-form input::placeholder,
.composer-edit-form .custom-select-button strong,
.exercise-collection-form input::placeholder,
.exercise-composer-field strong {
  color: var(--muted);
  font-size: 16px;
  font-weight: 400;
  opacity: 1;
}

.piece-identity-group,
.piece-date-group,
.composer-name-group,
.exercise-collection-identity-group {
  display: grid;
  overflow: hidden;
  border-radius: var(--dashboard-card-radius);
  background: rgba(0, 0, 0, 0.18);
}

.piece-identity-group label + label,
.piece-date-group label + label,
.composer-name-group label + label,
.exercise-collection-identity-group label + label {
  border-top: 1px solid var(--line);
}

.piece-identity-group input,
.piece-identity-group .custom-select-button,
.piece-date-group .date-select-button,
.composer-name-group input,
.exercise-collection-identity-group input,
.exercise-collection-identity-group .exercise-composer-field {
  border-radius: 0 !important;
  background: transparent !important;
}

.date-select-content {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  width: 100%;
}

.date-select-value {
  color: #74adff;
  font-weight: 700;
}

.piece-create-submit:disabled,
.piece-create-submit.disabled,
#saveComposerEdit:disabled {
  border-color: rgba(255, 255, 255, 0.1) !important;
  background: rgba(255, 255, 255, 0.055) !important;
  color: rgba(166, 175, 188, 0.58) !important;
  cursor: default;
}

.source-level-card {
  display: inline-grid;
  place-items: center;
  min-width: 72px;
  min-height: 66px;
  padding: 8px 12px;
  border-radius: 8px;
  background: rgba(90, 169, 255, 0.16);
  color: #2d83ff;
  line-height: 1;
}

.source-level-card span {
  color: var(--muted);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
}

.source-level-card strong {
  font-size: 36px;
  font-weight: 760;
}

.rating-star-button {
  width: 30px !important;
  height: 30px !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  color: rgba(166, 175, 188, 0.75) !important;
  box-shadow: none !important;
}

.rating-star-button::before {
  width: 19px;
  height: 19px;
}

.rating-star-button.active,
.rating-star-button.is-active {
  color: #74adff !important;
}

.custom-select-button:focus,
.custom-select.open .custom-select-button,
.date-select-button:focus {
  outline: none !important;
}

.level-select-field .custom-select-menu,
.piece-create-level-column .custom-select-menu {
  display: none;
  grid-template-columns: repeat(4, max-content);
  align-items: center;
  justify-content: start;
  gap: 8px 10px;
  width: max-content;
  max-width: min(760px, calc(100vw - 80px));
  max-height: none;
  overflow: visible;
  padding: 10px;
  border-radius: 8px;
  background: var(--modal-surface, #1c2027);
}

.level-select-field .custom-select.open .custom-select-menu,
.piece-create-level-column .custom-select.open .custom-select-menu {
  display: grid;
}

.level-select-field .custom-option,
.piece-create-level-column .custom-option {
  width: auto;
  min-width: 0;
  min-height: 38px;
  padding: 0;
  background: transparent;
}

.source-tag-option .source-tag,
.custom-option.source-tag-option .source-tag {
  transform: none;
}

.stage-status-option {
  justify-content: flex-start;
}

.stage-status-pill,
.stage-status-option .stage-status-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 30px;
  padding: 0 14px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  color: var(--muted);
  font-size: 13px;
  font-weight: 750;
}

.stage-status-pill.recorded {
  border: 1px solid rgba(90, 169, 255, 0.42);
  background: rgba(90, 169, 255, 0.18);
  color: #9ccfff;
}

.calendar-modal {
  width: 390px;
  height: 440px;
  padding: 28px 22px 22px;
}

.calendar-action-row,
.calendar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.calendar-action-row {
  margin-bottom: 26px;
}

.calendar-title-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 24px;
  font-weight: 750;
  cursor: pointer;
}

.calendar-title-button svg {
  width: 13px;
  color: #74adff;
}

.calendar-nav-group {
  display: flex;
  gap: 14px;
}

.calendar-nav-button {
  border: 0;
  background: transparent;
  color: #74adff;
}

.calendar-nav-button svg {
  width: 22px;
  height: 22px;
}

.start-calendar-grid {
  animation: calendarFade 140ms var(--ease-out);
}

@keyframes calendarFade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.calendar-day {
  border-radius: 999px;
  background: transparent;
}

.calendar-day.selected {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  background: rgba(90, 169, 255, 0.24);
  color: #74adff;
  box-shadow: none;
}

.composer-picker-modal {
  width: min(900px, calc(100vw - 48px)) !important;
}

.composer-picker-modal h3 {
  margin-left: 12px;
}

.composer-picker-list,
.composer-picker-results {
  scrollbar-width: thin;
  scrollbar-color: rgba(166, 175, 188, 0.55) rgba(255, 255, 255, 0.07);
}

.composer-picker-list::-webkit-scrollbar,
.composer-picker-results::-webkit-scrollbar,
.composer-edit-modal::-webkit-scrollbar,
.exercise-collection-modal::-webkit-scrollbar {
  width: 8px;
}

.composer-picker-list::-webkit-scrollbar-track,
.composer-picker-results::-webkit-scrollbar-track,
.composer-edit-modal::-webkit-scrollbar-track,
.exercise-collection-modal::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.06);
  border-radius: 999px;
}

.composer-picker-list::-webkit-scrollbar-thumb,
.composer-picker-results::-webkit-scrollbar-thumb,
.composer-edit-modal::-webkit-scrollbar-thumb,
.exercise-collection-modal::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: rgba(166, 175, 188, 0.5);
}

.mini-modal.composer-edit-modal,
.composer-edit-modal {
  width: min(900px, calc(100vw - 48px)) !important;
  max-height: calc(100vh - 48px);
  overflow-x: hidden;
  overflow-y: auto;
}

.composer-edit-modal #composerEditTitle {
  margin: 0 58px 24px 12px;
  font-size: 26px;
  line-height: 1.1;
}

.composer-edit-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
  align-items: start;
  column-gap: 24px;
  row-gap: 0;
  margin-top: 0;
}

.composer-edit-column {
  display: grid;
  gap: 12px;
  min-width: 0;
}

.composer-edit-secondary {
  padding-left: 24px;
  border-left: 1px solid var(--line);
}

.composer-edit-form label,
.activity-period,
.composer-major-toggle-field {
  display: grid;
  gap: 7px;
  color: var(--muted);
  font-size: 14px;
  font-weight: 700;
  text-transform: none;
}

.composer-era-field .custom-select-menu {
  display: none;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: 8px;
  padding: 10px;
  border-radius: var(--dashboard-card-radius);
  background: rgba(0, 0, 0, 0.18);
}

.composer-era-field .custom-select.open .custom-select-menu {
  display: grid;
}

.composer-era-field .custom-option {
  min-height: 38px;
  border-radius: 999px;
  text-align: center;
}

.activity-period > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 10px;
}

.portrait-upload-block {
  display: grid;
  gap: 8px;
}

.portrait-upload-label,
.composer-major-toggle-field > span {
  color: var(--muted);
  font-size: 14px;
  font-weight: 700;
  text-transform: none;
}

.portrait-upload-field small {
  display: none;
}

.composer-edit-form .portrait-upload-button {
  justify-content: flex-start;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.composer-major-toggle {
  display: inline-grid;
  grid-template-columns: 1fr 1fr;
  width: min(320px, 100%);
  gap: 3px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
}

.composer-major-toggle button {
  height: 34px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  font-weight: 750;
}

.composer-major-toggle button.active {
  background: rgba(255, 255, 255, 0.16);
  color: #74adff;
  box-shadow: none;
}

#saveComposerEdit {
  height: 40px;
  padding: 0 22px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
  color: rgba(166, 175, 188, 0.58);
  cursor: default;
  font-size: 15px;
  font-weight: 750;
}

.exercise-collection-modal {
  width: min(520px, calc(100vw - 48px)) !important;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}

.exercise-collection-modal h3,
.exercise-collection-modal #exerciseCollectionTitle,
.exercise-collection-modal #exerciseEditTitle {
  margin: 0 58px 24px 12px;
  font-size: 26px;
}

.exercise-collection-form {
  display: grid;
  gap: 12px;
}

.exercise-composer-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  text-align: left;
}

.exercise-composer-field .chevron {
  width: 10px;
  height: 10px;
  flex: 0 0 10px;
  transform: rotate(-90deg);
}

.exercise-composer-field strong.selected-composer-name {
  color: #74adff;
  font-weight: 650;
}

#exerciseCollectionForm input[type="text"],
#exerciseCollectionForm input[type="number"],
#exerciseEditForm input[type="text"],
#exerciseEditForm input[type="number"] {
  height: 54px !important;
  padding: 0 18px !important;
  border: 0 !important;
  border-radius: var(--dashboard-card-radius) !important;
  background: rgba(0, 0, 0, 0.18) !important;
  color: var(--text) !important;
  font-size: 16px !important;
  font-weight: 600 !important;
}

#exerciseCollectionForm .exercise-count-field input,
#exerciseEditForm .exercise-count-field input,
#exerciseCollectionForm #exerciseCountInput,
#exerciseEditForm #exerciseEditCountInput {
  height: 72px !important;
  padding: 0 18px !important;
  letter-spacing: -1px !important;
  text-align: center !important;
  font-size: 52px !important;
  font-weight: 760 !important;
}

.exercise-edit-actions {
  justify-content: space-between;
}

.exercise-edit-actions .danger-button {
  margin-right: auto;
}

.exercise-add-btn,
.exercise-add-area {
  display: none !important;
}

.piece-row {
  grid-template-columns: auto minmax(0, 1fr) auto auto auto auto;
}

.piece-finished-date {
  justify-self: end;
  color: var(--muted);
  font-size: 14px;
  font-weight: 400;
  opacity: 0;
  white-space: nowrap;
  transform: translateX(4px);
  transition: opacity 150ms var(--ease-out), transform 150ms var(--ease-out);
}

.piece-row:hover .piece-finished-date {
  opacity: 1;
  transform: translateX(0);
}

.piece-finished-date:empty {
  display: none;
}

.nav-icon svg {
  overflow: visible;
}

/* Filled dock glyphs are phone-only; the desktop sidebar keeps the outline set. */
.nav-icon .nav-icon-filled {
  display: none;
}

.dock-indicator {
  display: none;
}

/* Phone-only profile button in the Dashboard header (shown from the mobile
   block). A plain circle: the photo when there is one, else a person glyph. */
.topbar-avatar-btn {
  display: none;
  place-items: center;
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  margin-left: auto;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 50%;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.92);
  cursor: pointer;
}

.topbar-avatar {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.topbar-avatar-placeholder {
  width: 24px;
  height: 24px;
  fill: currentColor;
}

.topbar-avatar:not([hidden]) + .topbar-avatar-placeholder {
  display: none;
}

.nav-icon svg circle {
  fill: currentColor !important;
  stroke: none !important;
}

.nav-icon svg path {
  fill: none !important;
  stroke: currentColor !important;
  stroke-width: 2 !important;
  stroke-linecap: round !important;
  stroke-linejoin: round !important;
}

.piece-create-form .piece-create-identity-group,
.piece-create-form .piece-create-date-group {
  display: grid !important;
  gap: 0 !important;
  overflow: hidden !important;
  border: 0 !important;
  border-radius: var(--dashboard-card-radius) !important;
  background: rgba(0, 0, 0, 0.18) !important;
  box-shadow: none !important;
}

.piece-create-form .piece-create-identity-group label,
.piece-create-form .piece-create-date-group label,
.piece-create-form .piece-create-identity-group .custom-select,
.piece-create-form .piece-create-date-group .custom-select {
  display: block !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
}

.piece-create-form .piece-create-identity-group label + label,
.piece-create-form .piece-create-date-group label + label {
  border-top: 1px solid var(--line) !important;
}

.piece-create-form .piece-create-identity-group input,
.piece-create-form .piece-create-identity-group .custom-select-button,
.piece-create-form .piece-create-date-group .date-select-button {
  width: 100% !important;
  height: 68px !important;
  min-height: 68px !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}

.piece-create-form .piece-create-identity-group .custom-select.open .custom-select-button,
.piece-create-form .piece-create-date-group .date-select-button:focus {
  box-shadow: none !important;
}

/* Final overlay dropdown fix: keep level menus from creating modal scrollbars. */
.mini-modal.piece-create-modal,
.piece-create-modal {
  overflow: visible !important;
}

.piece-create-level-column,
.piece-create-level-column .supporting-rating-field,
.piece-create-level-column .custom-select {
  overflow: visible !important;
}

.piece-create-level-column .custom-select-menu {
  position: absolute !important;
  z-index: 80 !important;
  max-height: none !important;
  overflow: visible !important;
}

.piece-create-level-column .supporting-rating-field:nth-of-type(4) .custom-select-menu,
.piece-create-level-column .supporting-rating-field:nth-of-type(5) .custom-select-menu {
  top: auto !important;
  bottom: calc(100% + 8px) !important;
}

/* Final new-piece field height alignment with composer modal. */
.piece-create-form .piece-create-identity-group input,
.piece-create-form .piece-create-identity-group .custom-select-button,
.piece-create-form .piece-create-date-group .date-select-button,
.piece-create-form .piece-create-column > label > .custom-select .custom-select-button,
.piece-create-form .supporting-rating-field .custom-select-button {
  height: 54px !important;
  min-height: 54px !important;
}

/* Final fixed overlay level dropdowns: no blank None option and no modal scrollbars. */
.piece-create-level-column .custom-select.fixed-menu .custom-select-menu {
  position: fixed !important;
  top: var(--select-menu-top) !important;
  left: var(--select-menu-left) !important;
  bottom: auto !important;
  z-index: 9999 !important;
  max-height: none !important;
  overflow: visible !important;
}

.piece-create-level-column .custom-select-menu .custom-select-option.empty {
  display: none !important;
}

/* Final composer picker modal restore. */
#pieceComposerPickerModal:not([hidden]) {
  display: flex;
  align-items: center;
  justify-content: center;
}

.composer-picker-modal {
  width: min(900px, calc(100vw - 48px)) !important;
  max-height: min(720px, calc(100vh - 48px));
  overflow: hidden !important;
  padding: 30px 34px 34px;
  border-radius: var(--dashboard-card-radius) !important;
  background: var(--modal-surface, #1c2027) !important;
}

.composer-picker-modal .calendar-action-row {
  margin-bottom: 28px;
}


.composer-picker-modal h3 {
  margin: 0 0 20px 12px !important;
  font-size: 30px;
  line-height: 1.1;
}

.composer-picker-search {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  height: 54px;
  margin-bottom: 14px;
  padding: 0 18px;
  border: 0;
  border-radius: var(--dashboard-card-radius);
  background: rgba(0, 0, 0, 0.18);
}

.composer-picker-search .search-icon {
  flex: 0 0 22px;
  opacity: 0.75;
}

.composer-picker-search input {
  width: 100%;
  min-width: 0;
  height: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 18px;
}

.composer-picker-search input::placeholder {
  color: var(--muted);
  opacity: 0.85;
}

.composer-picker-selected {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 38px;
  margin: 0 0 14px;
  align-items: center;
}

.composer-picker-empty {
  color: var(--muted);
  font-size: 15px;
}

.composer-picker-chip {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: rgba(116, 173, 255, 0.14);
  color: #74adff;
  cursor: pointer;
  font: inherit;
  font-weight: 750;
}

.composer-picker-list {
  display: grid;
  gap: 8px;
  max-height: min(380px, calc(100vh - 330px));
  overflow-y: auto;
  padding-right: 6px;
  scrollbar-width: thin;
  scrollbar-color: rgba(166, 175, 188, 0.55) rgba(255, 255, 255, 0.07);
}

.composer-picker-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 58px;
  padding: 0 18px;
  border: 0;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.16);
  color: var(--text);
  cursor: pointer;
  text-align: left;
  font: inherit;
}

.composer-picker-option:hover,
.composer-picker-option.active {
  background: rgba(116, 173, 255, 0.16);
}

.composer-picker-option span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 20px;
  font-weight: 760;
}

.composer-picker-option small {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 15px;
}

.composer-picker-option.active span {
  color: #74adff;
}

.piece-create-identity-group [data-proxy-for="pieceCreateComposerSelect"] .custom-select-button {
  cursor: pointer;
}

.piece-create-identity-group [data-proxy-for="pieceCreateComposerSelect"] .custom-select-menu {
  display: none !important;
}

.selected-composer-name {
  color: #74adff;
  font-weight: 650;
}

/* Final level dropdown placement and icon order fix. */
.piece-create-level-column .custom-select.fixed-menu .custom-select-menu,
.piece-create-level-column .custom-select-menu {
  position: absolute !important;
  top: calc(100% + 8px) !important;
  left: 0 !important;
  right: auto !important;
  bottom: auto !important;
  z-index: 120 !important;
  max-height: none !important;
  overflow: visible !important;
}

.piece-create-level-column .supporting-rating-field:nth-of-type(4) .custom-select-menu,
.piece-create-level-column .supporting-rating-field:nth-of-type(5) .custom-select-menu {
  top: auto !important;
  bottom: calc(100% + 8px) !important;
}

.piece-create-form .supporting-rating-field {
  position: relative !important;
}

.piece-create-form .supporting-rating-field .custom-select-button {
  position: relative !important;
  padding-right: 98px !important;
}

.piece-create-form .supporting-rating-field .rating-star-button {
  right: 52px !important;
  top: 50% !important;
  transform: translateY(-50%) !important;
}

.piece-create-form .supporting-rating-field .custom-select-button .chevron {
  position: absolute !important;
  right: 22px !important;
  margin: 0 !important;
}

/* Final composer picker proportions. */
.composer-picker-modal {
  width: min(620px, calc(100vw - 48px)) !important;
  max-height: min(620px, calc(100vh - 48px)) !important;
  padding: 28px 30px 30px !important;
}

.composer-picker-modal .calendar-action-row {
  margin-bottom: 22px !important;
}

.composer-picker-modal h3 {
  margin: 0 0 18px 4px !important;
  font-size: 26px !important;
}

.composer-picker-search {
  height: 46px !important;
  margin-bottom: 12px !important;
  padding: 0 15px !important;
}

.composer-picker-search .search-icon {
  flex-basis: 18px !important;
  transform: scale(0.86);
}

.composer-picker-search input {
  font-size: 15px !important;
}

.composer-picker-selected {
  min-height: 30px !important;
  margin-bottom: 10px !important;
}

.composer-picker-empty {
  font-size: 14px !important;
}

.composer-picker-chip {
  height: 28px !important;
  padding: 0 10px !important;
  font-size: 13px !important;
}

.composer-picker-list {
  gap: 7px !important;
  max-height: min(330px, calc(100vh - 300px)) !important;
}

.composer-picker-option {
  min-height: 48px !important;
  padding: 0 15px !important;
  border-radius: 8px !important;
}

.composer-picker-option span {
  font-size: 17px !important;
  font-weight: 740 !important;
}

.composer-picker-option small {
  font-size: 13px !important;
}

/* Final composer picker action button alignment. */
.composer-picker-modal {
  position: relative !important;
  padding-top: 88px !important;
}

.composer-picker-modal .calendar-action-row {
  position: absolute !important;
  top: 28px !important;
  left: 30px !important;
  right: 30px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  margin: 0 !important;
  height: 38px !important;
}

.composer-picker-modal .calendar-action-button {
  position: relative !important;
  top: auto !important;
  right: auto !important;
  left: auto !important;
  width: 38px !important;
  height: 38px !important;
  border: 1px solid var(--line) !important;
  border-radius: 999px !important;
  background: rgba(255, 255, 255, 0.055) !important;
  color: var(--muted) !important;
}

.composer-picker-modal .calendar-confirm-button {
  border-color: rgba(123, 183, 255, 0.38) !important;
  color: #8fc7ff !important;
}

.composer-picker-modal .close-inspector.calendar-action-button::before,
.composer-picker-modal .close-inspector.calendar-action-button::after {
  left: 11px !important;
  top: 18px !important;
  width: 15px !important;
}

.composer-picker-modal h3 {
  margin-top: 0 !important;
}

/* Final blue checkmark action buttons. */
.calendar-confirm-button,
.composer-picker-modal .calendar-confirm-button {
  border-color: rgba(90, 169, 255, 0.68) !important;
  background: rgba(90, 169, 255, 0.22) !important;
  color: #7bb7ff !important;
}

.calendar-confirm-button:hover,
.composer-picker-modal .calendar-confirm-button:hover {
  border-color: rgba(90, 169, 255, 0.88) !important;
  background: rgba(90, 169, 255, 0.32) !important;
  color: #b7dcff !important;
}

/* Final selected composer field styling mirrors piece rows. */
.piece-create-identity-group [data-proxy-for="pieceCreateComposerSelect"] .custom-select-button strong {
  display: flex;
  align-items: baseline;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
}

.piece-create-identity-group [data-proxy-for="pieceCreateComposerSelect"] .selected-composer-name {
  color: #74adff !important;
  font-size: 16px !important;
  font-weight: 650 !important;
  line-height: 1;
}

.piece-create-identity-group [data-proxy-for="pieceCreateComposerSelect"] .piece-composer-separator {
  color: rgba(190, 201, 215, 0.64) !important;
  font-size: 16px !important;
  font-weight: 400 !important;
  margin-right: 4px;
}

/* Absolute final guard: no None pills in level selector grids. */
.piece-create-level-column .custom-select-option.source-tag-option.empty,
.piece-create-level-column .custom-select-option.source-tag-option[data-select-value=""],
.piece-create-level-column .custom-select-option.source-tag-option[data-select-value="None"],
.level-select-field .custom-select-option.source-tag-option.empty,
.level-select-field .custom-select-option.source-tag-option[data-select-value=""],
.level-select-field .custom-select-option.source-tag-option[data-select-value="None"] {
  display: none !important;
}

/* Final level grid containment: dropdowns must never resize or scroll the modal. */
.mini-modal.piece-create-modal,
.piece-create-modal {
  overflow: visible !important;
  overflow-x: visible !important;
  overflow-y: visible !important;
}

.piece-create-level-column .custom-select {
  position: relative !important;
  overflow: visible !important;
}

.piece-create-level-column .custom-select-menu,
.piece-create-level-column .custom-select.fixed-menu .custom-select-menu {
  position: absolute !important;
  top: calc(100% + 8px) !important;
  left: 0 !important;
  right: auto !important;
  bottom: auto !important;
  z-index: 500 !important;
  display: none;
  width: max-content !important;
  min-width: 100% !important;
  max-width: none !important;
  box-sizing: border-box !important;
  grid-template-columns: repeat(3, max-content) !important;
  justify-content: start !important;
  align-items: center !important;
  gap: 10px !important;
  padding: 12px !important;
  overflow: visible !important;
}

.piece-create-level-column .custom-select.open .custom-select-menu {
  display: grid !important;
}

.piece-create-level-column .custom-select-option.source-tag-option {
  display: inline-flex !important;
  justify-content: center !important;
  width: auto !important;
  min-width: 0 !important;
  overflow: visible !important;
}

.piece-create-level-column .custom-select-option.source-tag-option .map-pill {
  white-space: nowrap !important;
}

.piece-create-level-column .supporting-rating-field:nth-of-type(4) .custom-select-menu,
.piece-create-level-column .supporting-rating-field:nth-of-type(5) .custom-select-menu {
  top: auto !important;
  bottom: calc(100% + 8px) !important;
}

/* Final new-piece date field typography alignment. */
.piece-create-form .piece-create-date-group .date-select-button,
.piece-create-form .piece-create-date-group .date-select-label {
  color: var(--muted) !important;
  font-size: 16px !important;
  font-weight: 400 !important;
  line-height: 1 !important;
}

.piece-create-form .piece-create-date-group .date-select-value {
  color: var(--text) !important;
  font-size: 16px !important;
  font-weight: 400 !important;
  margin-left: 18px !important;
}

.piece-create-date-group .date-select-button {
  padding-right: 40px !important;
}

/* Final new-piece header level marker. */
.piece-create-header {
  display: flex !important;
  align-items: center !important;
  gap: 22px !important;
  margin: 0 58px 24px 12px !important;
}

.piece-create-header h3 {
  margin: 0 !important;
  font-size: 28px !important;
  line-height: 1.1 !important;
}

.piece-create-level-preview {
  flex: 0 0 auto !important;
  min-width: 72px;
}

.piece-create-level-card {
  display: inline-grid !important;
  place-items: center !important;
  width: 72px !important;
  height: 66px !important;
  padding: 7px 10px !important;
  border-radius: 8px !important;
  background: rgba(90, 169, 255, 0.13) !important;
  color: #2d83ff !important;
  line-height: 1 !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04) !important;
}

.piece-create-level-card span {
  color: var(--muted) !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  text-transform: uppercase !important;
}

.piece-create-level-card strong {
  color: #2d83ff !important;
  font-size: 36px !important;
  font-weight: 760 !important;
  line-height: 0.95 !important;
}

/* Final dropdown radius alignment. */
.custom-select-menu,
.piece-create-level-column .custom-select-menu,
.composer-era-field .custom-select-menu,
.level-select-field .custom-select-menu {
  border-radius: var(--dashboard-card-radius) !important;
}

/* Final no-scroll modal dropdown behavior. */
#pieceCreateModal,
#pieceCreateModal .mini-modal,
#pieceCreateModal .piece-create-modal {
  overflow: visible !important;
}

#pieceCreateModal .piece-create-level-column .supporting-rating-field:nth-of-type(3) .custom-select-menu,
#pieceCreateModal .piece-create-level-column .supporting-rating-field:nth-of-type(4) .custom-select-menu,
#pieceCreateModal .piece-create-level-column .supporting-rating-field:nth-of-type(5) .custom-select-menu,
#pieceEditModal .piece-create-level-column .supporting-rating-field:nth-of-type(3) .custom-select-menu,
#pieceEditModal .piece-create-level-column .supporting-rating-field:nth-of-type(4) .custom-select-menu,
#pieceEditModal .piece-create-level-column .supporting-rating-field:nth-of-type(5) .custom-select-menu {
  top: auto !important;
  bottom: calc(100% + 8px) !important;
}

#pieceCreateModal .piece-create-level-column .custom-select-menu,
#pieceEditModal .piece-create-level-column .custom-select-menu {
  max-height: none !important;
  overflow: visible !important;
}

#pieceCreateModal .piece-create-column,
#pieceCreateModal .piece-create-level-column,
#pieceCreateModal .piece-create-form,
#pieceCreateModal .supporting-rating-field,
#pieceCreateModal .custom-select,
#pieceEditModal .piece-create-column,
#pieceEditModal .piece-create-level-column,
#pieceEditModal .piece-create-form,
#pieceEditModal .supporting-rating-field,
#pieceEditModal .custom-select {
  overflow: visible !important;
}

/* Final composer picker search icon matches global search icon. */
.composer-picker-search .search-icon {
  position: relative !important;
  width: 15px !important;
  height: 15px !important;
  flex: 0 0 15px !important;
  border: 2px solid var(--dim) !important;
  border-radius: 999px !important;
  opacity: 1 !important;
  transform: none !important;
}

.composer-picker-search .search-icon::after {
  content: "" !important;
  position: absolute !important;
  right: -5px !important;
  bottom: -4px !important;
  width: 7px !important;
  height: 2px !important;
  border-radius: 999px !important;
  background: var(--dim) !important;
  transform: rotate(45deg) !important;
}

/* Final new-piece marker uses settings marker style. */
.piece-create-header .piece-create-level-card.piece-level-marker {
  display: grid !important;
  width: 74px !important;
  height: 56px !important;
  align-content: center !important;
  justify-items: center !important;
  padding: 8px 8px 7px !important;
  border: 0 !important;
  border-radius: 9px !important;
  background: color-mix(in srgb, var(--level-color, #7bb7ff) 5%, rgba(255, 255, 255, 0.026)) !important;
  color: var(--level-secondary-color, var(--level-color, #7bb7ff)) !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.035), 0 8px 22px rgba(0, 0, 0, 0.08) !important;
  transform: none !important;
}

.piece-create-header .piece-create-level-card.piece-level-marker span {
  color: rgba(190, 201, 215, 0.82) !important;
  font-size: 11px !important;
  font-weight: 650 !important;
  line-height: 1 !important;
  text-transform: uppercase !important;
}

.piece-create-header .piece-create-level-card.piece-level-marker strong {
  color: var(--level-secondary-color, var(--level-color, #7bb7ff)) !important;
  font-size: 31px !important;
  font-weight: 600 !important;
  line-height: 0.96 !important;
}

/* Absolute final guard: no None rows in any custom dropdown. */
.custom-select-option.empty,
.custom-select-option[data-select-value=""],
.custom-select-option[data-select-value="None"] {
  display: none !important;
}

/* Absolute final: New Piece marker must use the exact site marker styling. */
.piece-create-header .piece-create-level-card.piece-level-marker {
  display: grid !important;
  width: 74px !important;
  height: 56px !important;
  align-content: center !important;
  overflow: hidden !important;
  justify-items: center !important;
  justify-self: start !important;
  padding: 8px 8px 7px !important;
  border: 0 !important;
  border-radius: 9px !important;
  background: color-mix(in srgb, var(--level-color, #7bb7ff) 5%, rgba(255, 255, 255, 0.026)) !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.035), 0 8px 22px rgba(0, 0, 0, 0.08) !important;
  transform: none !important;
}

.piece-create-header .piece-create-level-card.piece-level-marker span {
  color: rgba(190, 201, 215, 0.82) !important;
  font-size: 11px !important;
  font-weight: 650 !important;
  line-height: 1 !important;
  text-transform: uppercase !important;
}

.piece-create-header .piece-create-level-card.piece-level-marker strong {
  color: var(--level-secondary-color, var(--level-color, #7bb7ff)) !important;
  font-size: 31px !important;
  font-weight: 600 !important;
  line-height: 0.96 !important;
}

/* Absolute final: New Piece level marker uses source-level-card exactly. */
.piece-create-header .piece-create-level-card.source-level-card {
  display: inline-grid !important;
  place-items: center !important;
  min-width: 72px !important;
  min-height: 66px !important;
  width: auto !important;
  height: auto !important;
  padding: 8px 12px !important;
  border-radius: 8px !important;
  background: rgba(90, 169, 255, 0.16) !important;
  color: #2d83ff !important;
  line-height: 1 !important;
  transform: none !important;
}

.piece-create-header .piece-create-level-card.source-level-card span {
  color: var(--muted) !important;
  font-size: 11px !important;
  font-weight: 800 !important;
  text-transform: uppercase !important;
  line-height: 1 !important;
}

.piece-create-header .piece-create-level-card.source-level-card strong {
  color: #2d83ff !important;
  font-size: 36px !important;
  font-weight: 760 !important;
  line-height: 1 !important;
}

/* Absolute final: New Piece header marker inherits the exact piece-row marker. */
.piece-create-level-preview .piece-level-marker {
  /* Do not restyle this marker. Keep the established piece-row marker dimensions, font, and colors. */
}

/* Absolute final: New Piece marker must inherit the exact piece-row font stack. */
.piece-create-level-preview .piece-level-marker,
.piece-create-level-preview .piece-level-marker span,
.piece-create-level-preview .piece-level-marker strong {
  font-family: Inter, -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", sans-serif !important;
}

/* Absolute final: New Piece marker exact piece-row dimensions. */
.piece-create-level-preview .piece-level-marker {
  width: 74px !important;
  height: 56px !important;
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 8px 8px 7px !important;
  border-radius: 9px !important;
  align-content: center !important;
  justify-items: center !important;
  box-sizing: border-box !important;
}

/* Final piece row column normalization. */
.piece-row {
  grid-template-columns: 86px minmax(0, 1fr) 180px 118px 190px 38px !important;
  align-items: center !important;
  gap: 14px !important;
}

.piece-row .piece-source {
  grid-column: 3 !important;
  justify-self: center !important;
  max-width: 180px !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}

.piece-row .stage-status {
  grid-column: 4 !important;
  justify-self: end !important;
  width: 108px !important;
}

.piece-row .piece-finished-date {
  grid-column: 5 !important;
  justify-self: end !important;
  width: 190px !important;
  max-width: 190px !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
  text-align: right !important;
  opacity: 1 !important;
  visibility: visible !important;
  transform: translateX(0) !important;
}

.piece-row:hover .piece-finished-date:not(:empty) {
  opacity: 1 !important;
  visibility: visible !important;
  transform: translateX(0) !important;
}

.piece-row .piece-finished-date:empty {
  display: block !important;
  opacity: 0 !important;
  visibility: hidden !important;
}

.piece-row .piece-open-icon {
  grid-column: 6 !important;
  justify-self: end !important;
  width: 38px !important;
}

.piece-edit-actions {
  justify-content: space-between !important;
}

/* Exercise collection identity group — merged field appearance. */
.exercise-collection-identity-group {
  gap: 0 !important;
}

.exercise-collection-identity-group label {
  margin: 0 !important;
}

#exerciseCollectionForm .exercise-collection-identity-group input[type="text"],
#exerciseEditForm .exercise-collection-identity-group input[type="text"] {
  border-radius: 0 !important;
  background: transparent !important;
}

#exerciseCollectionForm .exercise-collection-identity-group .exercise-composer-field,
#exerciseEditForm .exercise-collection-identity-group .exercise-composer-field {
  border-radius: 0 !important;
  background: transparent !important;
}

#recordConfirmDateButton .date-select-value {
  color: var(--text) !important;
  font-weight: 400 !important;
  margin-left: 16px;
}

#recordConfirmModal .mini-modal {
  width: min(480px, calc(100vw - 48px));
}

#recordConfirmPieceInfo .piece-row {
  grid-template-columns: 86px 1fr !important;
  border-radius: var(--radius) !important;
  cursor: default;
  pointer-events: none;
}

#recordConfirmPieceInfo .piece-source,
#recordConfirmPieceInfo .stage-status,
#recordConfirmPieceInfo .piece-finished-date,
#recordConfirmPieceInfo .piece-open-icon {
  display: none !important;
}

#recordConfirmPieceInfo .piece-row {
  display: flex;
  align-items: center;
  padding: 7px 16px;
  min-width: 0;
}

#recordConfirmPieceInfo .piece-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#recordConfirmPieceInfo .piece-card-check {
  order: 99;
  margin-left: auto;
}

.record-confirm-backdrop {
  align-items: center;
  justify-content: center;
}

/* ── Rank Up Modal ── */
.rank-up-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  background: rgba(0, 0, 0, 0.75);
  backdrop-filter: blur(8px);
  animation: rankUpBackdropIn 0.4s ease forwards;
}

.rank-up-backdrop.rank-up-closing {
  animation: rankUpBackdropOut 0.4s ease forwards;
}

@keyframes rankUpBackdropIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes rankUpBackdropOut {
  from { opacity: 1; }
  to   { opacity: 0; }
}

.rank-up-modal {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 48px 56px 40px;
  background: rgba(10, 14, 28, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 28px;
  box-shadow: 0 0 80px rgba(80, 140, 255, 0.15), 0 30px 60px rgba(0,0,0,0.5);
  text-align: center;
  animation: rankUpModalIn 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
  overflow: hidden;
}

.rank-up-backdrop.rank-up-closing .rank-up-modal {
  animation: rankUpModalOut 0.35s ease-in forwards;
}

@keyframes rankUpModalIn {
  from { opacity: 0; transform: scale(0.75) translateY(24px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes rankUpModalOut {
  from { opacity: 1; transform: scale(1); }
  to   { opacity: 0; transform: scale(0.9); }
}

.rank-up-shards-canvas {
  position: fixed;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 99;
}

.rank-up-close {
  position: absolute;
  top: 16px;
  right: 16px;
  background: rgba(255,255,255,0.07);
  border: none;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  color: var(--muted);
  cursor: pointer;
}

.rank-up-close:hover { background: rgba(255,255,255,0.14); color: var(--text); }

.rank-up-glow {
  position: absolute;
  top: -60px;
  left: 50%;
  transform: translateX(-50%);
  width: 300px;
  height: 300px;
  background: radial-gradient(circle, rgba(80, 140, 255, 0.18) 0%, transparent 70%);
  pointer-events: none;
  animation: rankUpGlowPulse 2s ease-in-out infinite;
}

@keyframes rankUpGlowPulse {
  0%, 100% { opacity: 0.7; transform: translateX(-50%) scale(1); }
  50%       { opacity: 1;   transform: translateX(-50%) scale(1.15); }
}

.rank-up-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--blue);
  margin: 0;
  opacity: 0;
  animation: rankUpFadeUp 0.4s 0.3s ease forwards;
}

.rank-up-badge-wrap {
  position: relative;
  width: 180px;
  height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 8px 0;
}

.rank-up-badge-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid rgba(80, 140, 255, 0.3);
  box-shadow:
    0 0 20px rgba(80, 140, 255, 0.2),
    inset 0 0 20px rgba(80, 140, 255, 0.05);
  animation: rankUpRingSpin 6s linear infinite;
}

.rank-up-badge-ring::before {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: var(--blue);
  border-right-color: rgba(80,140,255,0.4);
  animation: rankUpRingSpin 2.5s linear infinite;
}

@keyframes rankUpRingSpin {
  to { transform: rotate(360deg); }
}

.rank-up-badge-img {
  width: 150px;
  height: 150px;
  object-fit: contain;
  position: absolute;
}

.rank-up-badge-old {
  opacity: 0.7;
  filter: brightness(0.6) saturate(0.4);
  transition: none;
}

.rank-up-badge-old.rank-up-badge-exit {
  animation: rankUpOldExit 0.5s cubic-bezier(0.4, 0, 1, 1) forwards;
}

@keyframes rankUpOldExit {
  0%   { opacity: 0.7; transform: scale(1); filter: brightness(0.6) saturate(0.4); }
  100% { opacity: 0; transform: scale(0.5) translateY(-20px); filter: brightness(0) saturate(0); }
}

.rank-up-badge-new {
  opacity: 0;
  transform: scale(0);
}

.rank-up-badge-new.rank-up-badge-enter {
  animation: rankUpNewEnter 0.6s cubic-bezier(0.34, 1.7, 0.64, 1) forwards,
             rankUpBadgeFloat 3s ease-in-out 0.8s infinite;
  filter: drop-shadow(0 0 24px rgba(80, 140, 255, 0.5)) drop-shadow(0 0 50px rgba(80, 140, 255, 0.25));
}

@keyframes rankUpNewEnter {
  0%   { opacity: 0; transform: scale(0.2); filter: brightness(3) drop-shadow(0 0 60px white); }
  60%  { opacity: 1; transform: scale(1.15); filter: brightness(1.5) drop-shadow(0 0 30px rgba(255,255,255,0.8)); }
  100% { opacity: 1; transform: scale(1); filter: drop-shadow(0 0 24px rgba(80, 140, 255, 0.5)) drop-shadow(0 0 50px rgba(80, 140, 255, 0.25)); }
}

@keyframes rankUpBadgeFloat {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(-6px); }
}

.rank-up-name {
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 36px;
  font-weight: 800;
  color: var(--text);
  margin: 4px 0 0;
  letter-spacing: -0.01em;
  opacity: 0;
  animation: rankUpFadeUp 0.5s 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

.rank-up-tier {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 12px;
  opacity: 0;
  animation: rankUpFadeUp 0.4s 0.65s ease forwards;
}

.rank-up-btn {
  margin-top: 8px;
  padding: 0 28px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.055);
  color: var(--text);
  font-size: 14px;
  font-weight: 800;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  cursor: pointer;
  transition: transform 150ms var(--ease-out), background 240ms ease, border-color 240ms ease;
  opacity: 0;
  animation: rankUpFadeUp 0.4s 0.8s ease forwards;
}
.rank-up-btn:hover {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.2);
  transform: scale(1.04);
}

@keyframes rankUpFadeUp {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes rankUpBadgeIn {
  from { opacity: 0; transform: scale(0.5); }
  to   { opacity: 1; transform: scale(1); }
}

.record-confirm-modal {
  width: 760px !important;
  display: flex;
  flex-direction: row;
  gap: 0;
  padding: 0 !important;
  overflow: hidden;
}

.record-confirm-left {
  flex: 1;
  min-width: 0;
  padding: 22px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.record-confirm-right {
  width: 220px;
  min-width: 220px;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.03);
  border-left: 1px solid rgba(255, 255, 255, 0.07);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 28px 20px;
}

.record-confirm-ring-wrap {
  position: relative;
  width: 140px;
  height: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.record-confirm-ring-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.record-confirm-ring-track {
  fill: none;
  stroke: rgba(255, 255, 255, 0.07);
  stroke-width: 6;
}

.record-confirm-ring-fill {
  fill: none;
  stroke: var(--blue);
  stroke-width: 6;
  stroke-linecap: round;
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(90deg) scaleX(-1);
  transition: stroke-dashoffset 0.9s cubic-bezier(0.2, 0.8, 0.2, 1);
  filter: drop-shadow(0 0 6px rgba(100, 170, 255, 0.5));
}

.record-confirm-ring-gain {
  fill: none;
  stroke: white;
  stroke-width: 6;
  stroke-linecap: round;
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(90deg) scaleX(-1);
  opacity: 0;
  pointer-events: none;
}

@keyframes gainPulseIn {
  0%   { opacity: 0; filter: drop-shadow(0 0 0px white); stroke-width: 6; }
  100% { opacity: 1; filter: drop-shadow(0 0 16px white) drop-shadow(0 0 30px rgba(255,255,255,0.7)); stroke-width: 8; }
}

@keyframes gainPulseLoop {
  0%   { opacity: 1; filter: drop-shadow(0 0 16px white) drop-shadow(0 0 30px rgba(255,255,255,0.7)); stroke-width: 8; }
  50%  { opacity: 0.5; filter: drop-shadow(0 0 6px rgba(255,255,255,0.5)) drop-shadow(0 0 10px rgba(255,255,255,0.2)); stroke-width: 6; }
  100% { opacity: 1; filter: drop-shadow(0 0 16px white) drop-shadow(0 0 30px rgba(255,255,255,0.7)); stroke-width: 8; }
}

.record-confirm-ring-gain.pulsing {
  animation: gainPulseIn 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) forwards, gainPulseLoop 1.4s ease-in-out 0.5s infinite;
}

.record-confirm-badge-inner {
  position: relative;
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.record-confirm-badge-img {
  width: 90px;
  height: 90px;
  object-fit: contain;
}

.record-confirm-xp-label {
  font-size: 22px;
  font-weight: 800;
  color: var(--blue);
  letter-spacing: -0.01em;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.4s 0.3s ease, transform 0.4s 0.3s ease;
}

.record-confirm-xp-label.visible {
  opacity: 1;
  transform: translateY(0);
}

.record-confirm-pct-label {
  font-size: 18px;
  font-weight: 900;
  color: var(--muted);
  letter-spacing: 0.01em;
  text-align: center;
}

.record-confirm-sweep {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    rgba(45, 105, 190, 0.08) 0%,
    rgba(45, 105, 190, 0.20) 45%,
    rgba(45, 105, 190, 0.52) 100%
  );
  transform: translateX(102%);
  z-index: 5;
  pointer-events: none;
  border-radius: inherit;
  animation: rcSweep 0.55s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

@keyframes rcSweep {
  to { transform: translateX(0); }
}

.record-confirm-checkmark {
  position: absolute;
  top: 0;
  right: 16px;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 6;
  pointer-events: none;
  opacity: 0;
  animation: rcCheckIn 0.35s 0.42s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

.record-confirm-checkmark svg {
  filter: drop-shadow(0 0 10px rgba(79, 141, 255, 0.80));
}

@keyframes rcCheckIn {
  from { opacity: 0; transform: scale(0.5); }
  to { opacity: 1; transform: scale(1); }
}

.config-select {
  appearance: none;
  background: rgba(0, 0, 0, 0.25) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4l4 4 4-4' stroke='rgba(255,255,255,0.5)' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat right 12px center;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  padding: 8px 36px 8px 14px;
  cursor: pointer;
  min-width: 148px;
}

.config-select:focus {
  outline: none;
  border-color: rgba(255, 255, 255, 0.28);
}

.config-select option {
  background: #1c1c1e;
}


/* ═══════════════════════════════════════════════════════
   MOBILE  (≤ 768 px)
   ═══════════════════════════════════════════════════════ */
@media (max-width: 768px) {

  /* ── Layout ── */
  body {
    height: 100dvh;
    min-height: 100dvh;
    overflow: hidden;
    max-width: 100vw;
    overflow-x: hidden;
  }

  /* The pieces list overlaps its own composer name on this width — dropped
     from the dashboard on mobile rather than fixed, since Pieces already has
     its own page. */
  #dashboardWorkingPanel {
    display: none;
  }

  /* Same call for the Assigned Pieces metric card. */
  .dashboard-grid .metric-card.assigned {
    display: none;
  }

  /* Pinned to the screen edges rather than sized with 100dvh. In an
     installed iOS app with the translucent status bar, 100dvh comes out one
     status-bar height (~59pt) short of the real screen, so the shell, the
     workspace and every scroller stopped that far above the bottom: content
     was cut off in a straight line partway down the floating dock, with an
     empty strip beneath it. Fixed positioning measures from the true screen
     edges (the dock, also fixed, was always placed correctly), so the shell
     now fills the screen whatever dvh reports. */
  .app-shell {
    position: fixed;
    inset: 0;
    grid-template-columns: 1fr;
    grid-template-rows: 1fr auto;
    height: auto;
    min-height: 0;
    overflow: hidden;
  }

  /* ── Bottom navigation bar ── */
  /* Floating tab bar, iOS style: a capsule inset from the edges, sitting
     just above the home indicator. --dock-clear is everything the content
     has to clear (capsule plus the gap below it) and replaces the old flat
     65px + inset everywhere the dock height is reserved. */
  :root {
    --dock-h: 62px;
    --dock-bottom: max(calc(env(safe-area-inset-bottom, 0px) - 12px), 12px);
    --dock-clear: calc(var(--dock-h) + var(--dock-bottom));
  }

  .sidebar {
    position: fixed;
    bottom: var(--dock-bottom);
    left: calc(22px + env(safe-area-inset-left, 0px));
    right: calc(22px + env(safe-area-inset-right, 0px));
    top: auto;
    height: var(--dock-h);
    width: auto;
    /* Matched to Apple's own tab bar: one flat translucent grey (no
       gradient, no rim highlights, which read as 3D), a hairline edge, and
       blur doing the rest. 0.5px renders as a true hairline on Retina. */
    border: 0.5px solid rgba(255, 255, 255, 0.12);
    border-radius: 999px;
    background: rgba(44, 46, 52, 0.38);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
    backdrop-filter: blur(24px) saturate(180%);
    -webkit-backdrop-filter: blur(24px) saturate(180%);
    padding: 4px;
    z-index: 100;
    grid-row: 2;
  }

  /* Teaching and Lessons tint the dock darker from a :has() rule that
     outranks the one above, so they need matching here or they would stay
     at the old opacity. */
  .app-shell:has(#teaching.active) .sidebar,
  .app-shell:has(#lessons.active) .sidebar {
    background: rgba(44, 46, 52, 0.38);
  }

  .brand, .sidebar-card, .sidebar-bottom { display: none; }

  .nav-list {
    position: relative;
    display: flex;
    flex-direction: row;
    gap: 0;
    height: 100%;
    justify-content: space-around;
  }

  /* Selected tab: the selector's darker capsule, slid into place by
     positionDockIndicator in app.js, instead of a static highlight. */
  .dock-indicator {
    display: block;
    position: absolute;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.34);
    pointer-events: none;
    z-index: 0;
    transition: left 300ms cubic-bezier(0.34, 1.3, 0.64, 1),
                width 300ms cubic-bezier(0.34, 1.3, 0.64, 1);
  }

  .nav-list .nav-item,
  .nav-list .nav-item.active {
    position: relative;
    z-index: 1;
    height: 100%;
    border-radius: 999px;
    background: transparent;
    box-shadow: none;
  }

  .nav-item {
    flex: 1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    /* No vertical padding: icon + gap + label (30 + 1 + 12) used to need
       more than the tab's 52px, so flexbox squeezed the label to 9px and its
       overflow: hidden cropped the text, worse with iOS's taller font. */
    gap: 1px;
    padding: 0 4px;
    border-radius: 10px;
    min-width: 0;
    height: auto;
    background: none;
    border: none;
  }

  /* Bigger glyphs, in proportion to Apple's tab bar. */
  .nav-item .nav-icon {
    flex: 0 0 30px;
    width: 30px;
    height: 30px;
  }
  .nav-icon svg {
    width: 30px;
    height: 30px;
  }

  /* Filled glyphs, as in an iOS tab bar: solid in white when idle, solid in
     the accent blue when selected (colour comes from .nav-icon, below). The
     outline SVG is kept in the markup for the desktop sidebar. The base rule
     forces fill: none / stroke on every path with !important, hence the
     !important and the extra specificity here. */
  .nav-icon > svg:not(.nav-icon-filled):not(.mobile-nav-avatar-placeholder) {
    display: none;
  }
  .nav-icon .nav-icon-filled {
    display: block;
  }
  .nav-icon svg.nav-icon-filled path,
  .nav-icon svg.mobile-nav-avatar-placeholder path {
    fill: currentColor !important;
    stroke: none !important;
  }
  /* Home is the desktop outline path filled, with the same 2px round
     stroke, so the filled shape has exactly the outline's silhouette. */
  .nav-icon svg.nav-icon-filled path.nav-fill-stroke {
    stroke: currentColor !important;
    stroke-width: 2 !important;
    stroke-linejoin: round !important;
    stroke-linecap: round !important;
  }
  .nav-item .nav-icon {
    color: rgba(255, 255, 255, 0.92);
  }
  /* Idle labels white to match the icons; the selected tab's blue comes
     from .nav-item.active .nav-label, which outranks this. */
  .nav-item .nav-label {
    color: #fff;
  }

  /* iOS tab bar label: SF Pro at 10pt, semibold. The system stack gives
     SF on the iPhone instead of the app's Inter. */
  .nav-label {
    flex: 0 0 auto;
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
    font-size: 10px;
    font-weight: 600;
    line-height: 14px;
    letter-spacing: 0;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 56px;
  }

  /* Dock shows "Practice" for the Practice Log tab. Done in CSS, not by
     renaming the label: the page title is read from the label's text. */
  .nav-item[data-view="practice"] .nav-label {
    font-size: 0;
    /* Flex row: the hidden text and the ::after share one 14px line instead
       of stacking into two. */
    display: flex;
    justify-content: center;
    height: 14px;
  }
  .nav-item[data-view="practice"] .nav-label::after {
    content: "Practice";
    display: block;
    font-size: 10px;
    line-height: 14px;
  }

  .nav-item--overview, .nav-item--config, .nav-item--library, .nav-item--mastery, .nav-item--composers { display: none; }
  /* Profile lives in the Dashboard header (avatar, top right), not the dock. */
  .nav-item--mobile-profile { display: none !important; }

  .workspace:has(#dashboard.active) .topbar-avatar-btn {
    display: grid;
  }

  .mobile-nav-avatar {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
  }

  .nav-item--mobile-profile .mobile-nav-avatar-placeholder { display: block; }
  .nav-item--mobile-profile .mobile-nav-avatar:not([hidden]) ~ .mobile-nav-avatar-placeholder { display: none; }

  .nav-item.active .nav-icon { color: #007AFF; }
  .nav-item.active .nav-label { color: #007AFF; }
  .nav-item--muted.active .nav-icon { color: var(--muted) !important; }
  .nav-item--muted.active .nav-label { color: var(--muted) !important; }

  /* ── Workspace ── */
  /* The document itself must never scroll. Nothing constrained html, so as
     Safari's toolbar collapses and 100dvh changes under it, the page could
     pick up a scroll offset of exactly that delta — which showed up as the
     title sliced by the status bar and, because the dock is fixed while the
     workspace is not, an equal dead strip above the dock. */
  html {
    height: 100dvh;
    overflow: hidden;
  }

  .workspace {
    /* Was a flat 60px of empty screen above the title. The workspace does
       not scroll, so the only thing to clear here is the status bar of an
       installed app, which the inset measures.
       No bottom padding: reserving a strip the height of the dock is what
       left content cropped against an empty band. The scroller now runs to
       the bottom of the screen and passes under the dock, which is
       translucent anyway; .view below adds the room for the last row to
       clear it. */
    /* Inset plus a small gap, as iOS apps place their large title. There
       used to be a 58px floor here, but on the installed iPhone the page
       starts below the status bar and the inset reads 0, so the floor
       stacked a second status-bar-sized gap under the real one and the
       title sat ~25pt too low. Where the page does run under the status
       bar, the inset is reported (59px) and this still clears it. */
    padding: calc(env(safe-area-inset-top, 0px) + 6px) 14px 0;
    /* The shell's height, not 100dvh (see .app-shell above). */
    height: 100%;
    overflow-x: hidden;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    box-sizing: border-box;
    max-width: 100vw;
  }

  .workspace * {
    max-width: 100%;
    box-sizing: border-box;
  }

  /* Bottom padding on the scroller itself, not empty space around it: the
     content can sit under the dock while scrolling, and the end of the list
     still comes to rest above it. */
  .view {
    padding-bottom: calc(var(--dock-clear) + 14px);
  }

  /* Pieces, Teaching and Lessons do not scroll as a whole — they are fixed
     frames with a scrolling pane inside. Padding the view there reserves the
     strip outside the pane instead of inside it, so the pane stopped short
     of the dock and the band behind the dock stayed empty, unlike every
     other page. Hand the clearance to the panes so they reach the bottom of
     the screen and their content runs under the dock like everywhere else. */
  #levels,
  #teaching,
  #lessons {
    padding-bottom: 0;
  }

  .levels-list,
  .pieces-workflow,
  .teaching-column-list,
  .teaching-detail,
  .lessons-page {
    padding-bottom: calc(var(--dock-clear) + 14px);
  }

  .topbar {
    gap: 8px;
    margin-bottom: 10px;
    flex-wrap: wrap;
  }

  #currentDateLabel,
  .topbar-actions { display: none !important; }

  /* Pieces is the one page that keeps its search and + on a phone: a full
     row under the title. levels-mode is set by openView; the extra class
     outranks the hiding rule above without depending on source order. */
  .topbar-actions.levels-mode,
  .topbar-actions.exercises-mode {
    display: flex !important;
    flex: 1 1 100%;
    width: 100%;
  }

  .topbar-actions.levels-mode .search,
  .topbar-actions.exercises-mode .search {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
  }

  .topbar-actions.levels-mode .topbar-plus-button,
  .topbar-actions.exercises-mode .topbar-plus-button {
    flex: 0 0 42px;
  }

  /* This rule used to name .top-title, which no page has, so the title kept
     its full desktop size. */
  #view-title {
    /* iOS large-title size (34pt). */
    font-size: 34px;
    line-height: 1.15;
  }

  .workspace.practice-active .topbar {
    margin-bottom: 10px;
  }

  #searchInput {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
  }

  /* ── Inspector → bottom sheet ── */
  .inspector {
    top: auto !important;
    right: 0 !important;
    left: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: 82dvh;
    border-radius: 20px 20px 0 0;
    transform: translateY(calc(100% + 30px));
    padding-bottom: calc(env(safe-area-inset-bottom) + 74px);
  }

  .inspector.open { transform: translateY(0); }

  .workspace.inspector-open {
    padding-right: 14px !important;
  }

  /* ── Modals → bottom sheet ── */
  /* The base rule is place-items: center, i.e. align-items AND justify-items
     both center. Overriding only align-items left justify-items: center
     active, so the grid item never stretched horizontally — its track sized
     to content instead of the viewport, and everything computed against
     that instead of the real width. That's what put the action buttons off
     the right edge of the screen entirely. */
  .modal-backdrop {
    /* The base rule is inset: 0 — full screen — but the bottom nav sits at
       z-index: 100, above the backdrop's 20, so a sheet flush to the true
       bottom edge had its lowest content, including its own button row,
       rendered right under the nav bar. Stopping the backdrop above it
       means flex-end now pins the sheet's bottom edge there instead. */
    bottom: var(--dock-clear);
    align-items: flex-end;
    justify-items: stretch;
    padding: 0;
  }

  /* This rule used to name .modal, which nothing in the app is — every modal
     uses .mini-modal — so none of them ever got capped, and a tall one (the
     onboarding role step, say) rendered at its full desktop height pinned to
     the bottom of the screen, opening with most of it above the fold. */
  .mini-modal,
  .practice-day-editor {
    width: 100% !important;
    max-width: 100% !important;
    /* Bottom-pinned with no floor, a short dialog sat flush against the
       bottom edge with most of the screen showing the page behind it — the
       role step in onboarding opened with 70%+ of the screen still Profile.
       A minimum height raises that floor; flex column plus margin-top: auto
       on the button row (below) sends the gap that opens up to the bottom
       of the sheet instead of leaving it stranded under the title. Content
       taller than this still scrolls under the 92dvh cap. */
    display: flex;
    flex-direction: column;
    min-height: min(55dvh, 92dvh);
    max-height: 92dvh;
    border-radius: 20px 20px 0 0 !important;
    margin: 0 !important;
    overflow-y: auto;
    padding-bottom: calc(env(safe-area-inset-bottom) + 16px);
  }

  .mini-modal .modal-actions,
  .mini-modal .onboarding-actions {
    margin-top: auto;
    padding-top: 18px;
  }

  /* Modal consistency pass (phone). Some dialogs carry their own desktop
     width with !important (Edit Piece 820, Record 760) or are not .mini-modal
     at all (Practice day, 420px), so the rule above never reached them and
     they sat inset, off-centre, or ran off the right edge. The ID scope
     beats those rules whatever their order. */
  #pieceEditModal .mini-modal,
  #recordConfirmModal .mini-modal,
  #practiceDayModal .practice-day-editor {
    width: 100% !important;
    max-width: 100% !important;
  }

  /* Piece added is a full-screen backdrop (height: 100vh) so it ran under
     the dock, unlike every other sheet. */
  .piece-added-backdrop {
    height: auto;
  }

  /* One title style for every dialog: Add a Piece's, which is the reference.
     Sizes were 15 to 34px and mostly white. */
  .modal-backdrop .mini-modal h3,
  .modal-backdrop .practice-day-editor h3,
  .avatar-crop-backdrop .avatar-crop-dialog h3 {
    font-size: 20px;
    font-weight: 640;
    line-height: 1.2;
    color: var(--blue);
  }

  /* Exercise and Edit Piece set their title size by ID, or with !important
     (shared with New Piece's header, which is left as it is), so the rule
     above cannot reach them. */
  .modal-backdrop .mini-modal :is(#exerciseEditTitle, #exerciseCollectionTitle),
  #pieceEditModal .piece-create-header h3,
  #pieceCreateModal .piece-create-header h3 {
    font-size: 20px !important;
    line-height: 1.2 !important;
  }
  .exercise-collection-modal h3,
  #pieceEditModal .piece-create-header {
    margin-left: 0 !important;
  }

  /* The backdrop is a grid whose single column sizes to the dialog, so a
     dialog set to 100% wide resolved against its own content: Record
     confirm came out 237px wide and floating. */
  #recordConfirmModal {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked under the form, the artwork panel kept its desktop 220px width
     and side border, leaving it small and left-aligned. */
  #recordConfirmModal .record-confirm-right {
    width: 100%;
    min-width: 0;
    border-left: 0;
    border-top: 1px solid rgba(255, 255, 255, 0.07);
  }

  /* Practice day is not a .mini-modal, so it never got the round close
     button the others use; its own 30px X sat half off the screen. */
  .practice-day-editor .close-inspector {
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border: 1px solid var(--line);
    background: rgba(255, 255, 255, 0.055);
    color: var(--muted);
  }
  .practice-day-editor .close-inspector::before,
  .practice-day-editor .close-inspector::after {
    left: 12px;
    top: 18px;
    width: 14px;
  }

  /* Calendar arrows and month toggle under the ~40px touch size. */
  .calendar-modal .calendar-nav-button {
    width: 40px;
    height: 40px;
  }
  .calendar-modal .calendar-title-button {
    min-height: 40px;
  }

  /* ── Dashboard ── */
  .dashboard-top-row {
    grid-template-columns: 1fr !important;
    gap: 12px;
  }

  /* Quote of the Day on a phone: the whole quote, not two lines and an
     ellipsis, at a size that fits the narrow card; a smaller quote mark
     leaves the text more of the width. */
  .hero-panel {
    min-height: 0;
    padding: 18px;
  }
  .daily-quote-layout {
    grid-template-columns: 28px minmax(0, 1fr);
    gap: 14px;
  }
  .daily-quote-icon {
    width: 28px;
    height: 28px;
    margin-top: 4px;
  }
  .hero-panel h3 {
    font-size: 20px;
    line-height: 1.3;
    display: block;
    -webkit-line-clamp: unset;
    line-clamp: none;
    overflow: visible;
  }

  /* The second row here was reserved for #dashboardWorkingPanel to stretch
     into on desktop; now that the panel is hidden on mobile, keeping the
     "auto minmax(0, 1fr)" track leaves a fr row with nothing in it — Safari
     doesn't collapse that to zero the way Chrome does, and it reads as a gap
     under the mastery card. One row is all this needs here. */
  .dashboard-left-column {
    grid-template-rows: auto;
  }

  .dashboard-main-grid {
    grid-template-columns: 1fr !important;
    gap: 12px;
  }

  .dashboard-right-column {
    grid-template-columns: 1fr !important;
    grid-template-rows: auto !important;
  }

  /* Completed Pieces sinks below Time Practiced Today and Perfect Practice on
     this width — the other two are the ones worth reaching first. */
  .dashboard-right-column .completed-pieces-panel {
    order: 1;
  }

  /* Card order on a phone. Most Played sits in the top row and Perfect
     Practice in the right column, so they cannot be reordered past each
     other while those wrappers exist. display: contents dissolves the
     wrappers on this width, making every card a direct item of the
     dashboard's own column, where order can place them freely:
     Quote, Mastery, Time Practiced, Perfect Practice, Most Played,
     Completed Pieces. */
  #dashboard.active {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  #dashboard .dashboard-top-row,
  #dashboard .dashboard-main-grid,
  #dashboard .dashboard-left-column,
  #dashboard .dashboard-right-column {
    display: contents;
  }
  #dashboard .most-played-card {
    order: 1;
  }
  /* Practice Timer clock a touch smaller on a phone, so the row fits
     without crowding the play button. */
  .stopwatch-display {
    /* Scales with the screen so the narrowest phones (320px) still fit the
       clock beside the button; 44px from about 400px up. */
    font-size: clamp(30px, 11vw, 44px);
    white-space: nowrap;
  }
  .timer-main {
    gap: 16px;
  }

  /* The narrowest phones (iPhone SE and similar): a smaller clock, narrower
     Log/Reset and tighter gaps, so nothing overlaps the play button. */
  @media (max-width: 380px) {
    .stopwatch-display {
      font-size: 9.4vw;
    }
    .timer-main {
      gap: 10px;
    }
    .timer-side-buttons {
      width: 70px;
    }
  }

  /* Metronome and Perfect Practice side by side. */
  #dashboard .dashboard-tools-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 12px;
    flex-shrink: 0;
  }
  #dashboard .completed-pieces-panel {
    order: 2;
  }
  /* Spacing comes from the column's gap alone. flex-shrink: 0 because the
     dashboard is a fixed-height scroller: flex items shrink by default, so
     once the cards outgrew the screen they were all squeezed to fit (text
     cropped) instead of the page scrolling. */
  #dashboard .hero-panel,
  #dashboard .most-played-card,
  #dashboard .dashboard-grid,
  #dashboard #todayLogCard,
  #dashboard .perfect-practice-card,
  #dashboard .completed-pieces-panel {
    flex-shrink: 0;
    margin-top: 0;
    margin-bottom: 0;
  }

  .hero-panel,
  .most-played-card,
  .metric-card,
  .completed-pieces-panel,
  #todayLogCard {
    flex-direction: column;
    align-items: stretch;
  }


  .dashboard-extra-card,
  .dashboard-left-column,
  .dashboard-right-column {
    width: 100%;
    max-width: calc(100vw - 28px);
    overflow: hidden;
    box-sizing: border-box;
  }

  .mastery-dash-card {
    width: 100%;
    max-width: calc(100vw - 28px);
    box-sizing: border-box;
    flex-direction: row !important;
    flex-wrap: nowrap;
    align-items: center !important;
    gap: 12px;
    padding: 12px 14px;
  }

  .mastery-dash-badge {
    width: 60px !important;
    height: 60px !important;
    flex-shrink: 0;
  }

  .mastery-dash-rings {
    gap: 10px;
    margin-left: 0;
    flex-shrink: 0;
  }

  .mastery-dash-mini-ring {
    width: 56px !important;
    height: 56px !important;
  }

  .mastery-dash-mini-ring svg {
    width: 56px !important;
    height: 56px !important;
  }

  .level-bars {
    padding-left: 0;
    overflow: hidden;
    width: 100%;
  }

  .level-bar,
  .level-bar-header {
    grid-template-columns: 40px 1fr;
    gap: 8px;
    width: 100%;
  }

  .bar-track {
    overflow: hidden;
    width: 100%;
  }

  .bar-fill span {
    display: none;
  }

  .piece-map-button { display: none !important; }

  .dashboard-grid {
    flex-direction: column;
  }

  .dashboard-grid .metric-card,
  .dashboard-grid .metric-card.assigned,
  .dashboard-grid .metric-card.working {
    flex: unset;
    width: 100%;
  }

  .dashboard-grid .mastery-dash-card { order: -1; }

  .dashboard-card-grid {
    grid-template-columns: 1fr !important;
    gap: 10px;
  }

  /* ── No zoom-on-focus ── */
  /* iOS Safari zooms the page in whenever a focused field's text is under
     16px, and it does not zoom back out on blur — so one tap on a search
     box leaves the whole layout skewed until the page is reloaded. Modern
     Safari ignores maximum-scale / user-scalable, so the font size is the
     only thing that actually stops it. 16px on anything typed into, only
     at this width. !important because these fields are sized by a long
     tail of their own rules, several of them further down this file. */
  input:not([type="hidden"]):not([type="file"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  textarea,
  select,
  [contenteditable="true"] {
    font-size: 16px !important;
  }

  /* ── Teaching: one pane at a time ── */
  /* Side by side needs room this width does not have, so the roster comes
     first and the student replaces it once picked — the back button in the
     detail head brings the roster back.
     Everything here is scoped under #teachingPage on purpose: the Teaching
     rules live further down this file than the mobile block, so a plain
     class selector here would lose the tie on source order. */
  #teachingPage .teaching-layout {
    grid-template-columns: 1fr;
    gap: 0;
  }

  #teachingPage .teaching-column {
    padding-right: 0;
    border-right: 0;
  }

  #teachingPage .teaching-layout.is-detail .teaching-column {
    display: none;
  }

  #teachingPage .teaching-layout:not(.is-detail) .teaching-detail {
    display: none;
  }

  #teachingPage .teaching-back {
    display: grid;
  }

  #teachingPage .teaching-detail-head {
    align-items: center;
    gap: 12px;
  }

  /* Same size as the blue + buttons. */
  #teachingPage .teaching-back {
    width: 40px;
    height: 40px;
  }

  #teachingPage .teaching-back svg {
    width: 20px;
    height: 20px;
  }

  #teachingPage .teaching-detail-avatar {
    flex-basis: 48px;
    width: 48px;
    height: 48px;
  }

  #teachingPage .teaching-detail-name {
    font-size: 22px;
  }

  /* The three figures sit across the top as tiles, above the pieces. */
  #teachingPage .teaching-overview {
    margin-top: 16px;
    gap: 16px;
  }

  #teachingPage .teaching-stats {
    gap: 8px;
  }

  #teachingPage .teaching-stat {
    min-width: 0;
    padding: 12px 10px;
    border-radius: 13px;
  }

  #teachingPage .teaching-stat-value {
    font-size: 17px;
  }

  #teachingPage .teaching-stat-label {
    font-size: 10.5px;
  }

  #teachingPage .teaching-section {
    margin-top: 22px;
  }

  /* ── Practice Log ── */
  /* Four cards at a 160px minimum need 670px of room. Two by two instead.
     (This rule used to name .practice-stat-cards, which is not a class the
     page has, so it never did anything.) */
  .practice-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 8px;
  }

  .practice-stat-card {
    padding: 12px;
  }

  .practice-stat-card span {
    margin-bottom: 4px;
    font-size: 10.5px;
  }

  .practice-stat-card strong {
    font-size: 24px;
  }

  /* Seven fixed 132px columns run to nearly 1000px, so most of the month was
     off the right edge. Equal fractions of the width that is there, and each
     day becomes a square with its hours tucked under the date. */
  .practice-day-grid {
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 4px;
  }

  .practice-day-label {
    height: 18px;
    font-size: 10px;
  }

  .practice-day-square {
    width: auto;
    height: auto;
    aspect-ratio: 1;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    padding: 0 2px;
    border-radius: 7px;
    font-size: 12.5px;
  }

  .practice-day-square small {
    font-size: 9px;
    line-height: 1;
  }

  .hero-panel-icon { display: none; }

  /* ── Piece rows ── */
  /* The level, then the title and composer. Nothing else: the status repeats
     whatever the selector above is filtering by, and the chevron only says
     the row is tappable. The wide layout pins its children to columns 3 to 6
     with !important, which is what made them pile on top of each other once
     the template lost those columns — so everything dropped here is taken
     out of flow rather than left to land in a phantom track. */
  .piece-row {
    grid-template-columns: auto minmax(0, 1fr) !important;
    gap: 12px !important;
    min-height: 52px;
    padding: 8px 12px !important;
  }

  .piece-row .stage-status,
  .piece-row .piece-open-icon,
  .piece-row .piece-source,
  .piece-row .piece-finished-date,
  /* The wide layout re-shows an empty date with :empty, which outranks a
     plain .piece-row .piece-finished-date — without matching that here it
     kept a 190px column and shoved the rest of the row inward. */
  .piece-row .piece-finished-date:empty {
    display: none !important;
  }

  /* Both of these are nudged sideways on a wide row to sit under the header;
     there is no header here, so they sit where the grid puts them. */
  .piece-row .piece-level-marker {
    width: 52px;
    height: 44px;
    padding: 6px 6px 5px;
    transform: none !important;
  }

  .piece-row .piece-level-marker span {
    font-size: 9px;
  }

  .piece-row .piece-level-marker strong {
    font-size: 22px;
  }

  .piece-row .piece-copy {
    min-width: 0;
    transform: none !important;
  }

  .piece-title { font-size: 13px; }
  .piece-composer-link { font-size: 11px; }

  /* ── Level filter ── */
  /* Fourteen level pills wrapped to three rows of circles and pushed the
     status selector off the screen. They live behind a hamburger here, which
     leaves the row to the menu button and the status selector. */
  .level-filter-row {
    position: relative;
    display: flex !important;
    flex-wrap: nowrap;
    align-items: center;
    gap: 8px;
    padding-bottom: 4px;
  }

  .level-filter-menu-btn {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 7px;
    max-width: 47%;
    padding: 8px 13px;
    border: 1px solid rgba(255, 255, 255, 0.09);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.05);
    color: var(--text);
    font-size: 12.5px;
    font-weight: 650;
    white-space: nowrap;
    cursor: pointer;
  }

  .level-filter-menu-btn span {
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .level-filter-row.levels-open .level-filter-menu-btn {
    border-color: rgba(122, 176, 255, 0.5);
    color: #cfe2ff;
  }

  /* The status selector is the one control that has to stay reachable. */
  #stageFilterPills {
    flex: 1 1 auto;
    min-width: 0;
    justify-content: center;
  }

  #stageFilterPills .composer-sort-toggle {
    padding-inline: 10px;
    font-size: 12px;
  }

  .level-filter-count { display: none; }

  /* The pills themselves: a sheet under the button, not a row of circles. */
  .level-filter-pills {
    position: absolute;
    z-index: 30;
    top: calc(100% + 6px);
    left: 0;
    display: none;
    max-width: none;
    width: min(320px, 100%);
    flex-wrap: wrap;
    gap: 6px;
    padding: 12px;
    border: 1px solid rgba(255, 255, 255, 0.09);
    border-radius: 16px;
    background: #141924;
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
  }

  .level-filter-row.levels-open .level-filter-pills {
    display: flex;
  }

  /* A collapsed pill hides its long label by holding it at max-width 0. The
     blanket ".workspace *" rule above sets max-width 100% at the same
     specificity and later, so the invisible "LEVEL 10" claimed the circle
     and pushed the number out past its edge — which is why the digits came
     out clipped. */
  .level-filter-pill:not(.active) .level-filter-full {
    max-width: 0;
  }

  #piecesViewToggle, .recent-sort-toggle { display: none; }

  /* ── Workflow ── */
  .pieces-workflow {
    overflow-x: auto;
    scrollbar-width: none;
  }

  .pieces-workflow::-webkit-scrollbar { display: none; }

  .workflow-columns {
    display: flex !important;
    flex-direction: row;
    min-width: max-content;
    gap: 10px;
    height: 100%;
  }

  .workflow-column {
    width: 78vw;
    max-width: 300px;
    flex-shrink: 0;
  }

  /* ── Composer grid ── */
  .composer-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    gap: 8px;
  }

  /* ── Exercise items ── */
  .exercise-items { gap: 6px; }

  .exercise-item {
    width: 56px !important;
    height: 32px !important;
    font-size: 11px !important;
  }

  /* ── Topbar view title row ── */
  .level-count-display { display: none; }
}

/* ── Mastery Page ──────────────────────────────────────────────────────── */

.mastery-page {
  padding: 32px 28px;
}

/* ── Loading Screen ── */
.loading-screen {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #0e0f13;
  z-index: 9999;
}
.loading-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}
.loading-logo {
  width: 64px;
  height: 64px;
  animation: loading-pulse 1.8s ease-in-out infinite;
}
.loading-label {
  font-size: 15px;
  font-weight: 500;
  color: rgba(255,255,255,0.45);
  margin: 0;
  letter-spacing: 0.01em;
}
.loading-bar {
  width: 180px;
  height: 3px;
  background: rgba(255,255,255,0.08);
  border-radius: 999px;
  overflow: hidden;
}
.loading-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #3d7eff, #7eb8ff);
  animation: loading-sweep 1.4s ease-in-out infinite;
}
@keyframes loading-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.7; transform: scale(0.97); }
}
@keyframes loading-sweep {
  0% { width: 0%; margin-left: 0%; }
  50% { width: 70%; margin-left: 15%; }
  100% { width: 0%; margin-left: 100%; }
}

/* ── Login Gate ── */
.login-gate {
  position: fixed;
  inset: 0;
  background: radial-gradient(ellipse at 30% 40%, rgba(45,131,255,0.07) 0%, transparent 60%),
              radial-gradient(ellipse at 75% 70%, rgba(150,80,255,0.06) 0%, transparent 55%),
              #0c0c0e;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  overflow: hidden;
}

.login-gate[hidden] {
  display: none;
}

/* Music note watermarks */
.login-note {
  position: absolute;
  pointer-events: none;
  filter: invert(1);
  mix-blend-mode: screen;
  user-select: none;
}

.login-note--1 { width: 150px; top: 3%;    left: 8%;    transform: rotate(-22deg); opacity: 0.09; }
.login-note--2 { width: 90px;  top: 58%;   right: 3%;   transform: rotate(15deg);  opacity: 0.08; }
.login-note--3 { width: 200px; bottom: 1%; left: 28%;   transform: rotate(6deg);   opacity: 0.07; }
.login-note--4 { width: 110px; top: 18%;   right: 18%;  transform: rotate(-28deg); opacity: 0.09; }
.login-note--5 { width: 70px;  bottom: 20%;left: 4%;    transform: rotate(14deg);  opacity: 0.07; }
.login-note--6 { width: 120px; top: 72%;   right: 22%;  transform: rotate(-10deg); opacity: 0.08; }

.login-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 48px 44px;
  background: rgba(255,255,255,0.035);
  border: none;
  border-radius: 28px;
  min-width: 340px;
  text-align: center;
  backdrop-filter: blur(12px);
  box-shadow: 0 32px 80px rgba(0,0,0,0.5);
}

/* icon.png carries its own rounded corners (transparent alpha), so no CSS radius. */
.login-logo {
  width: 96px;
  height: 96px;
  filter: drop-shadow(0 14px 28px rgba(0, 0, 0, 0.45));
}

.login-title {
  font-family: "Bodoni Moda", "Bodoni 72", Didot, Georgia, serif;
  font-size: 40px;
  font-weight: 500;
  color: #f0f0f3;
  letter-spacing: 0.01em;
  line-height: 1;
  margin: 6px 0 0;
}

.login-subtitle {
  font-size: 14px;
  color: #7a7a8e;
  margin: 0;
}

.login-google-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 26px;
  background: #1a1a1a;
  color: #f0f0f3;
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 14px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  margin-top: 10px;
  transition: background 0.15s, border-color 0.15s;
  letter-spacing: 0.1px;
}

.login-google-btn:hover {
  background: #242424;
  border-color: rgba(255,255,255,0.2);
}

/* ── Login gate — cached profile card ── */
.lg-profile-row {
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 12px;
  padding: 12px 16px;
  margin-bottom: 16px;
  text-align: left;
}

.lg-cached-avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  flex-shrink: 0;
  object-fit: cover;
}

.lg-cached-avatar--initials {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #3d7eff;
  color: #fff;
  font-size: 18px;
  font-weight: 600;
}

.lg-profile-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.lg-profile-name {
  font-size: 14px;
  font-weight: 600;
  color: rgba(255,255,255,0.9);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lg-profile-email {
  font-size: 12px;
  color: rgba(255,255,255,0.4);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lg-switch-btn {
  margin-top: 10px;
  background: none;
  border: none;
  color: rgba(255,255,255,0.35);
  font-size: 12px;
  cursor: pointer;
  padding: 4px 0;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.lg-switch-btn:hover {
  color: rgba(255,255,255,0.6);
}

/* ── Username edit modal ── */
.settings-username-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 2px 0 1px;
}

.settings-profile-info .settings-username {
  font-size: 18px;
  font-weight: 700;
  color: #f5c842;
  letter-spacing: -0.01em;
}

.settings-username-edit-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border: none;
  background: transparent;
  color: rgba(255,255,255,0.3);
  cursor: pointer;
  border-radius: 4px;
  padding: 0;
  transition: color 0.15s, background 0.15s;
}

.settings-username-edit-btn:hover {
  color: rgba(255,255,255,0.7);
  background: rgba(255,255,255,0.07);
}

.username-input-wrap {
  display: flex;
  align-items: center;
  gap: 0;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.12);
  border-radius: 10px;
  padding: 0 14px;
  width: 100%;
}

.username-at {
  color: rgba(255,255,255,0.35);
  font-size: 15px;
  font-weight: 500;
  user-select: none;
}

.username-input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  color: #fff;
  font-size: 15px;
  font-weight: 500;
  padding: 11px 6px;
  font-family: inherit;
}

.username-input::placeholder {
  color: rgba(255,255,255,0.2);
}

.username-hint {
  font-size: 12px;
  color: rgba(255,255,255,0.3);
  margin: 0;
  align-self: flex-start;
}

.username-status {
  font-size: 13px;
  min-height: 18px;
  margin: 0;
  align-self: flex-start;
}

.username-status--ok { color: #4caf82; }
.username-status--error { color: #ff6b6b; }
.username-status--checking { color: rgba(255,255,255,0.4); }

/* ── Modal buttons (reusable default) ── */
/* Solid and borderless, sharing the empty-state pill's type so the app has one
   button voice: grey to dismiss, the action blue to commit. */
.modal-btn {
  height: 40px;
  padding: 0 22px;
  border: 0;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out), transform 150ms var(--ease-out);
}

.modal-btn:active:not(:disabled) {
  transform: scale(0.97);
}

.modal-btn:disabled,
.modal-btn.disabled {
  background: rgba(255,255,255,0.06) !important;
  color: rgba(166,175,188,0.45) !important;
  cursor: default;
}

.modal-btn--cancel {
  background: rgba(255,255,255,0.1);
  color: rgba(255,255,255,0.82);
}

.modal-btn--cancel:hover:not(:disabled) {
  background: rgba(255,255,255,0.16);
  color: #fff;
}

.modal-btn--primary {
  background: #007AFF;
  color: #fff;
}

/* Destructive confirms are the same pill in red — blue would hide what the
   button is about to do. */
.modal-btn--danger {
  background: #e5484d;
  color: #fff;
}

.modal-btn--danger:hover:not(:disabled) {
  background: #f05257;
}

.modal-btn--primary:hover:not(:disabled) {
  background: #0A84FF;
}

/* ── Avatar crop modal ── */
.avatar-crop-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.72);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  backdrop-filter: blur(4px);
}

.avatar-crop-dialog {
  background: #1c1d22;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 20px;
  padding: 28px 28px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  width: 340px;
}

.avatar-crop-title {
  font-size: 15px;
  font-weight: 600;
  color: rgba(255,255,255,0.9);
  margin: 0;
}

.avatar-crop-canvas {
  border-radius: 12px;
  cursor: grab;
  background: #111;
  display: block;
}

.avatar-crop-canvas:active {
  cursor: grabbing;
}

.avatar-crop-hint {
  font-size: 12px;
  color: rgba(255,255,255,0.3);
  margin: 0;
}

.avatar-crop-actions {
  display: flex;
  gap: 10px;
  width: 100%;
}

.avatar-crop-btn {
  flex: 1;
}

.avatar-crop-error {
  font-size: 12px;
  color: #ff6b6b;
  margin: 0;
  text-align: center;
}

/* ── Settings Page ── */
.settings-page {
  padding: 32px 28px;
}

.settings-profile-card {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 20px;
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 16px;
  max-width: 480px;
}

.settings-avatar-wrap {
  position: relative;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  flex-shrink: 0;
  cursor: pointer;
}

.settings-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

.settings-avatar-overlay {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  opacity: 0;
  transition: opacity 0.15s;
}

.settings-avatar-wrap:hover .settings-avatar-overlay {
  opacity: 1;
}

.settings-profile-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}

.settings-profile-name-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.settings-profile-info strong {
  color: #f0f0f3;
  font-size: 15px;
}

.settings-profile-info span {
  color: #7a7a8e;
  font-size: 13px;
}

.settings-admin-tag {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #4a9eff;
  background: rgba(74, 158, 255, 0.12);
  border: 1px solid rgba(74, 158, 255, 0.3);
  border-radius: 4px;
  padding: 2px 6px;
  line-height: 1.4;
}

.settings-signout-btn {
  padding: 8px 16px;
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 10px;
  color: #f0f0f3;
  font-size: 13px;
  cursor: pointer;
  transition: background 0.15s;
  white-space: nowrap;
}

.settings-signout-btn:hover {
  background: rgba(255,255,255,0.13);
}

.settings-export-section {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-top: 16px;
  padding: 18px 20px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 16px;
  max-width: 480px;
}

.settings-export-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.settings-export-title {
  font-size: 14px;
  font-weight: 600;
  color: rgba(232,238,246,0.92);
}

.settings-export-desc {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
}

.settings-export-btn {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-shrink: 0;
  height: 36px;
  padding: 0 16px;
  border-radius: 999px;
  border: 1px solid rgba(90,169,255,0.45);
  background: rgba(90,169,255,0.14);
  color: #c9e4ff;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 150ms, border-color 150ms;
}

.settings-export-btn:hover {
  background: rgba(90,169,255,0.24);
  border-color: rgba(90,169,255,0.65);
}

.settings-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 80px 32px;
  color: var(--text-muted, #7a7a8e);
  text-align: center;
}

.settings-placeholder svg {
  width: 48px;
  height: 48px;
  fill: currentColor;
  opacity: 0.3;
}

.settings-placeholder p {
  font-size: 18px;
  font-weight: 700;
  color: var(--text-secondary, #b0b0c0);
  margin: 0;
}

.settings-placeholder span {
  font-size: 13px;
  opacity: 0.6;
}

/* View switcher nav */
.mastery-view-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-bottom: 28px;
}

.mastery-view-arrow {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  background: rgba(255, 255, 255, 0.07);
  border: 0;
  border-radius: 999px;
  color: var(--text);
  cursor: pointer;
  transition: background 150ms, transform 150ms;
}

.mastery-view-arrow:hover {
  background: rgba(255, 255, 255, 0.13);
  transform: scale(1.08);
}

.mastery-view-arrow svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

.mastery-view-label {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  min-width: 70px;
  text-align: center;
}

.mastery-split {
  display: grid;
  grid-template-columns: 280px 220px 1fr;
  column-gap: 100px;
  row-gap: 24px;
  align-items: start;
  width: 100%;
}

/* Help button */
.mastery-help {
  position: absolute;
  top: 12px;
  right: 12px;
}

.mastery-help-btn {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: var(--muted);
  font-size: 11px;
  font-weight: 800;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background 150ms, color 150ms;
}

.mastery-help-btn:hover {
  background: rgba(255, 255, 255, 0.15);
  color: var(--text);
}

.mastery-help-tooltip {
  display: none;
  position: absolute;
  right: 0;
  top: 28px;
  width: 220px;
  background: rgb(20, 22, 30);
  border: none;
  border-radius: 12px;
  padding: 14px 16px;
  z-index: 10;
  text-align: left;
}

.mastery-help:hover .mastery-help-tooltip {
  display: block;
}

.mastery-help-tooltip strong {
  font-size: 12px;
  font-weight: 800;
  color: var(--text);
  display: block;
  margin-bottom: 8px;
}

.mastery-help-tooltip p {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
  margin: 0 0 6px;
}

.mastery-help-tooltip p:last-child {
  margin-bottom: 0;
}

/* Left panel */
.mastery-left-wrap {
  align-self: stretch;
  position: relative;
}

.mastery-left {
  position: sticky;
  top: calc(50vh - 120px);
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 28px 40px 32px;
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-radius: 20px;
  text-align: center;
}

.mastery-badge-wrap {
  margin-bottom: -4px;
  padding: 12px;
}

.mastery-badge-ring {
  position: relative;
  width: 120px;
  height: 120px;
}

.mastery-ring-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.mastery-ring-track {
  fill: none;
  stroke: rgba(255, 255, 255, 0.07);
  stroke-width: 6;
}

.mastery-ring-fill {
  fill: none;
  stroke: var(--blue);
  stroke-width: 6;
  stroke-linecap: round;
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(90deg) scaleX(-1);
  transition: stroke-dashoffset 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
  filter: drop-shadow(0 0 6px rgba(100, 170, 255, 0.5));
}

.mastery-badge-inner {
  position: absolute;
  inset: 12px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.05);
  display: flex;
  align-items: center;
  justify-content: center;
}

.mastery-badge-num {
  font-size: 36px;
  font-weight: 800;
  color: var(--blue);
  line-height: 1;
}

.mastery-badge-inner-img {
  width: 80px;
  height: 80px;
  object-fit: contain;
}

.mastery-tier-name {
  font-size: 28px;
  font-weight: 600;
  color: #e8eaf2;
  margin: 0;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}

.mastery-tier-sub {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}

.mastery-total-pts {
  font-size: 20px;
  font-weight: 400;
  color: var(--text);
  margin: 0;
  letter-spacing: normal;
  text-transform: none;
}

.mastery-recorded-count {
  font-size: 13px;
  font-weight: 600;
  color: var(--blue);
  margin: 4px 0 0;
  background: rgba(77, 166, 255, 0.12);
  border-radius: 999px;
  padding: 4px 14px;
  display: inline-block;
}

.mastery-recorded-count span {
  font-size: 13px;
  font-weight: 600;
  color: var(--blue);
}

.mastery-total-pts span {
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.18em;
  color: var(--muted);
}

.mastery-next-label {
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 2px 0 0;
}

.mastery-next-label strong {
  font-weight: 300;
  color: var(--text);
}

.mastery-next-label.mastery-max {
  color: var(--blue);
  font-weight: 700;
}

.mastery-next-reqs {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 8px;
}

.mastery-mini-ring {
  position: relative;
  width: 90px;
  height: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mastery-mini-ring svg {
  position: absolute;
  inset: 0;
}

.mastery-mini-ring-label {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
}

.mastery-mini-ring-val {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
}

.mastery-mini-ring-sub {
  font-size: 10px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Right panel — tier list */
.mastery-right {
  padding-left: 8px;
  padding-right: 24px;
}

.mastery-tier-list {
  display: flex;
  flex-direction: column;
}

.mastery-tier-row {
  display: grid;
  grid-template-columns: 28px 20px 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 14px 20px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
  transition: background 150ms;
}

.mastery-tier-row:last-child {
  border-bottom: 0;
}

.mastery-tier-row.unlocked {
  opacity: 0.45;
}

.mastery-tier-row.active {
  background: rgba(100, 170, 255, 0.1);
  border-bottom-color: rgba(100, 170, 255, 0.08);
}

.mastery-tier-row.locked {
  opacity: 0.5;
}

.mastery-tier-num {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--muted);
  text-align: right;
}

.mastery-tier-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

.mastery-tier-row.unlocked .mastery-tier-icon { color: #5de896; }
.mastery-tier-row.active   .mastery-tier-icon { color: var(--blue); }
.mastery-tier-row.locked   .mastery-tier-icon { color: rgba(255,255,255,0.2); }

.mastery-tier-row-name {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
}

.mastery-tier-row.active .mastery-tier-row-name {
  color: var(--blue);
}

.mastery-tier-req {
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  padding: 2px 9px;
  white-space: nowrap;
}

.mastery-tier-req-plus {
  font-size: 9px;
  vertical-align: super;
}

.mastery-tier-pts {
  font-size: 13px;
  font-weight: 700;
  color: var(--muted);
  text-align: right;
  white-space: nowrap;
}

/* ── Mastery config table ── */

.mastery-config-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.mastery-config-table th {
  text-align: left;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0 12px 10px;
}

.mastery-config-table td {
  padding: 9px 12px;
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  color: var(--text);
  font-weight: 600;
}

.mastery-config-table td:first-child {
  color: var(--muted);
  font-size: 11px;
  width: 28px;
}

.mastery-config-table td:nth-child(3) {
  color: var(--muted);
}

.mastery-config-table td:last-child {
  color: var(--muted);
  font-size: 12px;
}

/* Editable tier requirements: the inputs carry their own colour. */
.mastery-tier-edit .mastery-xp-input {
  width: 96px;
}

.mastery-tier-edit .mastery-tier-count {
  width: 64px;
}

.mastery-tier-level {
  height: 30px;
  padding: 0 8px;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  color: var(--text);
  font: inherit;
  font-size: 13px;
}

.mastery-tier-level:focus {
  outline: none;
  border-color: var(--blue);
}

.mastery-tier-save {
  justify-content: flex-end;
  align-items: center;
  gap: 14px;
  margin-top: 16px;
}

.mastery-tier-status {
  font-size: 13px;
  color: var(--muted);
}

.mastery-tier-status.is-error {
  color: #ffc9c9;
}

.mastery-config-table tr.mastery-config-zero td {
  color: var(--muted);
  opacity: 0.5;
}

.mastery-xp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 10px;
  margin-top: 12px;
}

.mastery-xp-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: rgba(255,255,255,0.04);
  border-radius: 10px;
  padding: 8px 12px;
}

.mastery-xp-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  min-width: 44px;
}

.mastery-xp-input {
  width: 64px;
  background: rgba(0,0,0,0.2);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 6px;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  padding: 4px 8px;
  text-align: right;
}

.mastery-xp-input:focus {
  outline: none;
  border-color: var(--blue);
}

.mastery-xp-unit {
  font-size: 11px;
  color: var(--blue);
  font-weight: 600;
}

.mastery-badge-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 12px;
  padding: 20px 16px 28px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  margin-bottom: 8px;
}

.mastery-badge-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.mastery-badge-img {
  width: 80px;
  height: 80px;
  display: block;
  object-fit: contain;
}

.mastery-badge-placeholder {
  width: 80px;
  height: 80px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px dashed rgba(255, 255, 255, 0.12);
}

.mastery-badge-cell-num {
  font-size: 10px;
  font-weight: 800;
  color: var(--muted);
  letter-spacing: 0.06em;
}

.mastery-badge-cell-name {
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  text-align: center;
  line-height: 1.2;
}

/* ── Trophy grid ── */

.mastery-trophy {
  overflow: hidden;
}

.mastery-trophy-grid {
  margin-top: 0;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 6px;
  padding: 8px 4px 32px;
}

/* Row 1: tier 0 + tier 1 */
.mastery-trophy-card:nth-child(1),
.mastery-trophy-card:nth-child(2) { grid-column: span 6; }

/* Row 2: tiers 2–5 */
.mastery-trophy-card:nth-child(3),
.mastery-trophy-card:nth-child(4),
.mastery-trophy-card:nth-child(5),
.mastery-trophy-card:nth-child(6) { grid-column: span 3; }

/* Row 3: tiers 6–8 */
.mastery-trophy-card:nth-child(7),
.mastery-trophy-card:nth-child(8),
.mastery-trophy-card:nth-child(9) { grid-column: span 4; }

/* Row 4: tiers 9–12 */
.mastery-trophy-card:nth-child(n+10) { grid-column: span 3; }

/* Row 5: tier 13 centered */
.mastery-trophy-card:nth-child(14) {
  grid-column: 1 / -1;
  justify-self: center;
  width: calc(25% - 5px);
}

.mastery-trophy-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 32px 8px 28px;
  border-radius: 12px;
  background: transparent;
  border: none;
  position: relative;
  isolation: isolate;
}

.mastery-trophy-card.active {
}

.mastery-trophy-card.locked {
  opacity: 0.4;
}

.mastery-trophy-card.locked .mastery-badge-img {
  filter: brightness(0);
}


.mastery-trophy-badge {
  width: 140px;
  height: 140px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.08s ease-out;
  will-change: transform;
}

.mastery-trophy-badge .mastery-badge-img {
  width: 140px;
  height: 140px;
}

.mastery-trophy-badge .mastery-badge-placeholder {
  width: 120px;
  height: 120px;
}

/* Shape-accurate drop shadow — traces the badge silhouette */
.mastery-trophy-card:not(.locked) .mastery-trophy-badge .mastery-badge-img {
  filter:
    drop-shadow(0 12px 18px rgba(0, 0, 0, 0.82))
    drop-shadow(0 5px 6px rgba(0, 0, 0, 0.6));
}

/* Cast shadow ellipse on the surface beneath the badge */
.mastery-trophy-badge {
  position: relative;
}

.mastery-trophy-badge::after {
  content: '';
  position: absolute;
  bottom: -10px;
  left: 50%;
  transform: translateX(-50%);
  width: 88px;
  height: 18px;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.6) 0%, transparent 72%);
  filter: blur(5px);
  pointer-events: none;
}

.mastery-trophy-eyebrow {
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

.mastery-trophy-name {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--text);
  text-align: center;
  word-break: break-word;
  width: 100%;
}

.mastery-trophy-card.locked .mastery-trophy-name {
  color: var(--muted);
}

/* ── Timeline view ── */

.mastery-timeline {
  max-width: 480px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

.mastery-tl-node {
  display: flex;
  gap: 18px;
  align-items: flex-start;
}

.mastery-tl-left {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
  width: 36px;
}

.mastery-tl-dot {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}

.mastery-tl-node.unlocked .mastery-tl-dot {
  background: rgba(93, 232, 150, 0.15);
  border: 2px solid rgba(93, 232, 150, 0.4);
}

.mastery-tl-node.unlocked .mastery-tl-dot svg {
  width: 16px;
  height: 16px;
  stroke: #5de896;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
}

.mastery-tl-node.active .mastery-tl-dot {
  background: rgba(100, 170, 255, 0.18);
  border: 2px solid var(--blue);
  box-shadow: 0 0 0 4px rgba(100, 170, 255, 0.12), 0 0 16px rgba(100, 170, 255, 0.3);
}

.mastery-tl-dot-pulse {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 8px rgba(100, 170, 255, 0.7);
  animation: mastery-pulse 2.4s ease-in-out infinite;
}

@keyframes mastery-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.7); }
}

.mastery-tl-node.locked .mastery-tl-dot {
  background: rgba(255, 255, 255, 0.04);
  border: 2px solid rgba(255, 255, 255, 0.1);
}

.mastery-tl-node.locked .mastery-tl-dot span {
  font-size: 11px;
  font-weight: 800;
  color: rgba(255, 255, 255, 0.2);
}

.mastery-tl-connector {
  width: 2px;
  flex: 1;
  min-height: 20px;
  background: rgba(255, 255, 255, 0.08);
  margin: 2px 0;
}

.mastery-tl-connector.lit {
  background: linear-gradient(to bottom, rgba(100, 170, 255, 0.5), rgba(100, 170, 255, 0.15));
}

.mastery-tl-content {
  padding: 6px 0 24px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.mastery-tl-node.active .mastery-tl-content {
  padding-bottom: 28px;
}

.mastery-tl-name {
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  line-height: 1.2;
  letter-spacing: normal;
  text-transform: none;
}

.mastery-tl-node.unlocked .mastery-tl-name { color: rgba(255,255,255,0.45); }
.mastery-tl-node.active   .mastery-tl-name { color: #fff; font-size: 15px; font-weight: 700; }
.mastery-tl-node.locked   .mastery-tl-name { color: rgba(255,255,255,0.25); }

.mastery-tl-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: nowrap;
  white-space: nowrap;
}

.mastery-tl-pts {
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
}

.mastery-tl-req {
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  padding: 2px 9px;
}

.mastery-tl-req.met {
  color: #5de896;
  background: rgba(93, 232, 150, 0.1);
}

.mastery-tl-here {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--blue);
  background: rgba(100, 170, 255, 0.12);
  border-radius: 999px;
  padding: 3px 10px;
  width: fit-content;
  margin-top: 2px;
}


/* Library-mode create modal: catalog entries describe the work, not anyone's
   progress, so stage and dates don't apply. */
.piece-create-modal.catalog-mode .piece-create-stage-field,
.piece-create-modal.catalog-mode .piece-create-form .piece-create-date-group {
  display: none !important;
}

.piece-create-submit.error {
  border-color: rgba(255, 107, 107, 0.6) !important;
  background: rgba(255, 107, 107, 0.18) !important;
  color: #ffc9c9 !important;
}


/* ── Add Piece wizard ─────────────────────────────────────────────────────── */
.mini-modal.piece-selector-modal {
  display: flex;
  flex-direction: column;
  width: min(820px, calc(100vw - 48px));
  /* Height is set in px by resizePieceSelectorModal(): fixed on step 1 so the
     results list scrolls inside, content-sized on later steps. */
  height: min(720px, calc(100vh - 48px));
  max-height: calc(100vh - 48px);
  padding: 26px 28px 22px;
  overflow: hidden;
  transition:
    height 320ms cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity 260ms cubic-bezier(0.16, 1, 0.3, 1),
    transform 260ms cubic-bezier(0.16, 1, 0.3, 1);
}

/* Steps size to their content, so they only scroll when clamped by the
   viewport — and then with the slim scrollbar used elsewhere, not the
   browser default. */
.piece-selector-page.is-clamped {
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(140, 170, 210, 0.28) transparent;
}

.piece-selector-page.is-clamped::-webkit-scrollbar {
  width: 11px;
}

.piece-selector-page.is-clamped::-webkit-scrollbar-track {
  background: transparent;
}

.piece-selector-page.is-clamped::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(150, 180, 222, 0.36), rgba(120, 150, 200, 0.3));
  background-clip: padding-box;
}

.piece-selector-header {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-right: 44px;
}

.piece-selector-header h3 {
  margin: 0;
}

/* Weight left to the app default for h3 (640). */
#pieceSelectorTitle {
  color: var(--blue);
}

/* Secondary to the title: white, lighter and smaller. */
.piece-selector-step {
  color: var(--text);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.01em;
}

.piece-selector-step b {
  color: inherit;
  font-weight: inherit;
}

.piece-selector-page {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.piece-selector-page[hidden] {
  display: none;
}

.piece-selector-hint {
  margin: 6px 0 16px;
  color: var(--muted);
  font-size: 13px;
}

/* Grouped search fields — same surface as the New Piece form's field groups. */
.piece-selector-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  overflow: hidden;
  border-radius: var(--dashboard-card-radius);
  background: rgba(0, 0, 0, 0.18);
}

.piece-selector-fields input {
  min-width: 0;
  height: 56px;
  padding: 0 18px;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: var(--text);
  font-size: 15px;
  outline: none;
}

.piece-selector-fields input + input {
  border-left: 1px solid var(--line);
}

.piece-selector-fields input::placeholder {
  color: var(--muted);
}

.piece-selector-results {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
  min-height: 0;
  margin-top: 14px;
  padding: 2px;
  overflow-y: auto;
}

.piece-selector-picked {
  flex: 0 0 auto;
  margin-top: 0;
}

.piece-selector-results .piece-row {
  grid-template-columns: 86px minmax(0, 1fr) 170px 96px !important;
  flex-shrink: 0;
}

.piece-selector-row[data-selector-pick] {
  cursor: pointer;
}

.piece-selector-row[data-selector-pick]:focus-visible {
  outline: 2px solid rgba(90, 169, 255, 0.6);
  outline-offset: 1px;
}

.piece-selector-row.selected {
  border-color: rgba(90, 169, 255, 0.75) !important;
  box-shadow: inset 0 0 0 1px rgba(90, 169, 255, 0.35);
}

.piece-selector-row.owned {
  opacity: 0.45;
  cursor: default !important;
}

.piece-selector-state {
  justify-self: end;
  color: var(--muted);
  font-size: 12px;
  white-space: nowrap;
}

.piece-selector-empty,
.piece-selector-placeholder {
  margin: auto;
  padding: 40px 0;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}

.piece-selector-more {
  padding: 8px 0 4px;
  color: var(--muted);
  font-size: 12px;
  text-align: center;
}

.piece-selector-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 18px;
}

/* Modal buttons: app-standard pill style (see avatar crop modal). */
@media (max-width: 768px) {
  .piece-selector-fields {
    grid-template-columns: 1fr;
  }
  .piece-selector-fields input + input {
    border-left: 0;
    border-top: 1px solid var(--line);
  }
  .piece-selector-results .piece-row {
    grid-template-columns: 64px minmax(0, 1fr) !important;
  }
  .piece-selector-results .piece-source,
  .piece-selector-results .piece-selector-state {
    display: none !important;
  }
  /* The idle prompt is redundant on a phone: the fields above already say
     Title / Composer. */
  .piece-selector-results .piece-selector-empty--idle {
    display: none;
  }
}

/* On-demand catalog: dim results while a new query runs, and the pager. */
.library-table-scroll,
.piece-selector-results {
  transition: opacity 150ms;
}

.library-table-scroll.is-loading,
.piece-selector-results.is-loading {
  opacity: 0.55;
}

.library-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 16px;
}

/* Add Piece step 2 — pick a status. Colours match the stage pills used
   throughout the app (see .stage-status.*). */
.piece-selector-stages {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  flex: 0 0 auto;
  margin-top: 18px;
}

.piece-selector-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  min-height: 230px;
  padding: 28px 20px;
  border: 0;
  border-radius: var(--dashboard-card-radius);
  /* Status colour fading down into near-black. */
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--stage-color) 15%, #141924) 0%,
    #141924 72%);
  color: var(--text);
  text-align: center;
  cursor: pointer;
  transition: border-color 150ms var(--ease-out), background 150ms var(--ease-out), transform 150ms var(--ease-out);
}

/* No outlines anywhere — hover and selection read through colour depth. */
.piece-selector-stage:hover {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--stage-color) 24%, #141924) 0%,
    #141924 74%);
  transform: translateY(-2px);
}

.piece-selector-stage.selected {
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--stage-color) 52%, #141924) 0%,
    #141924 82%);
  /* outline, not border: no layout shift and no fringe at the corners */
  outline: 3px solid var(--stage-color);
  outline-offset: -3px;
}

/* Start/end date fields land here once a status is chosen. */
.piece-selector-dates {
  flex: 0 0 auto;
  margin-top: 16px;
}

.piece-selector-stage-icon {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--stage-color) 20%, #141924);
  color: var(--stage-color);
}

.piece-selector-stage-icon svg {
  width: 32px;
  height: 32px;
}

.piece-selector-stage-name {
  color: var(--stage-color);
  font-size: 18px;
  font-weight: 750;
}

.piece-selector-stage-desc {
  max-width: 200px;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
}

.piece-selector-stage.stage-assigned  { --stage-color: var(--cyan); }
.piece-selector-stage.stage-working   { --stage-color: var(--amber); }
.piece-selector-stage.stage-recorded  { --stage-color: #4f8dff; }

@media (max-width: 768px) {
  .piece-selector-stages {
    grid-template-columns: 1fr;
    gap: 10px;
  }
  .piece-selector-stage {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    height: auto;
    text-align: left;
    padding: 14px 16px;
    gap: 14px;
  }
  .piece-selector-stages {
    flex: 0 0 auto;
  }
  .piece-selector-stage-desc {
    max-width: none;
  }

  /* Add Piece step 2 and Edit Piece on a phone (the edit form's own
     min-height: 190px is an ID rule later in the file, hence the doubled
     ID scope): a compact row per status. The rule above
     never reset the base min-height: 230px, so every card stayed desktop
     tall, and the 64px icon was a shrinkable flex child, which squashed it
     to an oval when the text was long. Icon left, name over description. */
  #pieceSelectorStages .piece-selector-stage,
  #pieceEditForm #pieceEditStages .piece-selector-stage {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas: "icon name" "icon desc";
    column-gap: 14px;
    row-gap: 2px;
    align-items: center;
    min-height: 0;
    padding: 12px 14px;
  }
  #pieceSelectorStages .piece-selector-stage-icon,
  #pieceEditForm #pieceEditStages .piece-selector-stage-icon {
    grid-area: icon;
    width: 44px;
    height: 44px;
  }
  #pieceSelectorStages .piece-selector-stage-icon svg,
  #pieceEditForm #pieceEditStages .piece-selector-stage-icon svg {
    width: 22px;
    height: 22px;
  }
  #pieceSelectorStages .piece-selector-stage-name,
  #pieceEditForm #pieceEditStages .piece-selector-stage-name {
    grid-area: name;
    align-self: end;
    font-size: 16px;
  }
  #pieceSelectorStages .piece-selector-stage-desc,
  #pieceEditForm #pieceEditStages .piece-selector-stage-desc {
    grid-area: desc;
    align-self: start;
    font-size: 12.5px;
    line-height: 1.35;
  }
}

/* Check button on wizard step 2 — dim it when no status is chosen yet. */
.check-btn:disabled {
  opacity: 0.45;
  cursor: default;
}

/* Step 2 date fields — grouped like the New Piece form's date group. */
/* Two pills side by side on one line. */
.piece-selector-date-group {
  display: flex;
  gap: 12px;
}

/* Half the row less half the gap, so two fields fill it exactly and a lone
   Start Date on Working is the same size as one of Recorded's pair rather
   than stretching across. */
.piece-selector-date-field {
  position: relative;
  display: block;
  flex: 0 1 calc(50% - 6px);
  min-width: 0;
}

.piece-selector-date-field .date-select-button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  height: 48px;
  /* room on the right for the clear button */
  padding: 0 40px 0 20px;
  border: 0;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.22);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  color: var(--text);
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
  transition: background 150ms var(--ease-out);
}

.piece-selector-date-field .date-select-button:hover {
  background: rgba(0, 0, 0, 0.3);
}

.piece-selector-date-field .date-select-value {
  overflow: hidden;
  text-overflow: ellipsis;
}

.piece-selector-date-field .date-select-button.placeholder-value {
  color: var(--muted);
}

.piece-selector-date-field .field-clear-btn {
  position: absolute;
  top: 50%;
  right: 14px;
  transform: translateY(-50%);
}

/* The Edit Piece form is a .piece-create-form, and that carries a blanket
   "padding: 0 18px !important" for every date button in it. That reclaims the
   room this field keeps for its clear button, so the date ends up printed
   under the ×. Win it back wherever the two meet, not just in that one modal. */
.piece-create-form .piece-selector-date-field .date-select-button {
  padding: 0 40px 0 20px !important;
}

.piece-selector-date-note {
  margin: 8px 0 0;
  color: var(--muted);
  font-size: 12px;
}

/* Step 2 XP preview — ring on the left, numbers on the right. */
/* Fills and centres in whatever space is left below the dates. */
.piece-selector-xp {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: center;
  gap: 26px;
  min-height: 150px;
  margin-top: 18px;
}

.piece-selector-xp[hidden] {
  display: none;
}

.piece-selector-xp-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.piece-selector-xp .record-confirm-pct-label {
  text-align: left;
}

/* Neutral round back button — same shape and stroke as .check-btn. */
.back-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  background: rgba(255, 255, 255, 0.08) !important;
  border: none !important;
  color: rgba(255, 255, 255, 0.78) !important;
  border-radius: 50% !important;
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out);
}

.back-btn:hover {
  background: rgba(255, 255, 255, 0.14) !important;
  color: #fff !important;
}

.back-btn svg {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  /* nudge for the chevron's optical centre */
  margin-right: 2px;
}

.back-btn[hidden] {
  display: none;
}

/* Back sits in the left corner, the check in the right. */
.piece-selector-actions .back-btn {
  margin-right: auto;
}

/* Confirming a status: everything but the piece line drops away, its status
   pill pops in, then the modal closes. */
.piece-selector-page.is-confirming .piece-selector-hint,
.piece-selector-page.is-confirming .piece-selector-stages,
.piece-selector-page.is-confirming .piece-selector-dates,
.piece-selector-page.is-confirming .piece-selector-xp {
  display: none;
}

.piece-selector-confirm-pill {
  animation: piece-selector-pill-in 420ms cubic-bezier(0.2, 1.3, 0.4, 1) both;
}

@keyframes piece-selector-pill-in {
  from { opacity: 0; transform: scale(0.72); }
  to   { opacity: 1; transform: scale(1); }
}

/* Room for the pill in the row's last column. */
.piece-selector-page.is-confirming .piece-selector-results .piece-row {
  grid-template-columns: 86px minmax(0, 1fr) 170px 120px !important;
}

/* Recorded celebration: status cards and dates step aside, the XP ring stays
   while the confetti plays. */
.piece-selector-page.is-celebrating .piece-selector-hint,
.piece-selector-page.is-celebrating .piece-selector-stages,
.piece-selector-page.is-celebrating .piece-selector-dates {
  display: none;
}

.piece-selector-page.is-celebrating .piece-selector-results .piece-row {
  grid-template-columns: 86px minmax(0, 1fr) 170px 120px !important;
}

/* Edit Piece: read-only line, then status and dates. The old fields stay in
   the DOM (hidden) so the existing save and date-picker wiring keeps working. */
.piece-edit-legacy {
  display: none !important;
}

#pieceEditForm {
  display: flex !important;
  flex-direction: column;
  gap: 16px;
}

#pieceEditPieceLine {
  min-height: 0;
  margin-top: 0;
  overflow: visible;
}

#pieceEditDates:empty {
  display: none;
}

#pieceEditForm .piece-selector-stage {
  min-height: 190px;
}

#pieceEditForm .modal-actions {
  margin-top: 4px;
}

/* Edit Piece: match the Add a Piece modal's width, and make the form a single
   full-width column (it inherits a two-column grid from the create form). */
#pieceEditModal .mini-modal {
  width: min(820px, calc(100vw - 48px));
}

#pieceEditForm > * {
  width: 100%;
  min-width: 0;
}

#pieceEditForm .piece-selector-date-group {
  width: 100%;
}

/* Delete on the left, save on the right. */
#pieceEditForm .modal-actions {
  display: flex;
  width: 100%;
  justify-content: space-between;
  align-items: center;
}

/* Edit Piece finishing: the status cards and dates drop away, leaving the
   piece line while its pill pops in. */
#pieceEditForm.is-confirming #pieceEditStages,
#pieceEditForm.is-confirming #pieceEditDates,
#pieceEditForm.is-celebrating #pieceEditStages,
#pieceEditForm.is-celebrating #pieceEditDates {
  display: none;
}

#pieceEditForm.is-confirming .piece-selector-results .piece-row,
#pieceEditForm.is-celebrating .piece-selector-results .piece-row {
  grid-template-columns: 86px minmax(0, 1fr) 170px 120px !important;
}

/* Status colour washing in from the right when a piece is confirmed as
   Assigned or Working — same shape as .record-confirm-sweep. */
.stage-confirm-sweep {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(
    90deg,
    color-mix(in srgb, var(--sweep-color) 8%, transparent) 0%,
    color-mix(in srgb, var(--sweep-color) 20%, transparent) 45%,
    color-mix(in srgb, var(--sweep-color) 52%, transparent) 100%
  );
  transform: translateX(102%);
  animation: stageConfirmSweep 0.75s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

@keyframes stageConfirmSweep {
  to { transform: translateX(0); }
}

/* The pill sits above the wash. */
.piece-selector-confirm-pill {
  position: relative;
  z-index: 6;
}

/* Role question: two cards, same shape as the status cards. */
.mini-modal.onboarding-modal {
  width: min(680px, calc(100vw - 48px));
  padding: 26px 28px 28px;
  transition: width 320ms var(--ease-out);
}

/* The username step needs far less room than the two role cards. */
.mini-modal.onboarding-modal--narrow {
  width: min(460px, calc(100vw - 48px));
}

/* Both steps keep the same height, so only the width animates between them. */
.onboarding-step {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 210px;
  margin-top: 4px;
}

#onboardingUsernameStep {
  justify-content: center;
}

.onboarding-step .role-options {
  margin-top: 0;
}

.role-options {
  grid-template-columns: repeat(2, 1fr);
  margin-top: 4px;
}

/* The card is a picture with a label on it, rather than an icon above two
   lines of text: the artwork sits large in the corner and fades into the
   card, and the words sit along the bottom edge out of its way. */
.role-option {
  --stage-color: #7bb7ff;
  position: relative;
  overflow: hidden;
  min-height: 230px;
  /* .piece-selector-stage switches to a row on mobile for the Add Piece
     status picker (icon beside text); this card shares that base class but
     needs its own column layout at every width, or the name lands beside
     the description instead of above it. */
  flex-direction: column;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 6px;
  padding: 22px;
  text-align: left;
}

.role-option--teacher {
  --stage-color: #b892ff;
}

.role-option--student {
  --role-art: url("./graphics/student.webp");
}

.role-option--teacher {
  --role-art: url("./graphics/teacher.webp");
}

.role-option::before {
  position: absolute;
  z-index: 0;
  top: -6%;
  right: -8%;
  width: 82%;
  height: 82%;
  background-image: var(--role-art);
  background-position: top right;
  background-repeat: no-repeat;
  background-size: contain;
  content: "";
  opacity: 0.3;
  pointer-events: none;
  /* Dissolve it into the card rather than sitting it in a box. */
  -webkit-mask-image: radial-gradient(120% 110% at 88% 12%, #000 34%, transparent 76%);
  mask-image: radial-gradient(120% 110% at 88% 12%, #000 34%, transparent 76%);
  transition: opacity 260ms var(--ease-ios), transform 320ms var(--ease-ios);
}

/* The student's portrait faces left, so it reads better pinned to that side
   instead of mirroring the teacher's placement. */
.role-option--student::before {
  right: auto;
  left: -8%;
  background-position: top left;
  -webkit-mask-image: radial-gradient(120% 110% at 12% 12%, #000 34%, transparent 76%);
  mask-image: radial-gradient(120% 110% at 12% 12%, #000 34%, transparent 76%);
}

.role-option:hover::before {
  opacity: 0.42;
  transform: scale(1.04);
}

.role-option.selected::before {
  opacity: 0.55;
}

/* The words ride above the artwork. */
.role-option .piece-selector-stage-name,
.role-option .piece-selector-stage-desc {
  position: relative;
  z-index: 1;
}

.role-option .piece-selector-stage-desc {
  max-width: 92%;
}

.role-option:disabled {
  cursor: default;
}

/* Wizard actions: two equal buttons, iOS-style. */
.onboarding-actions {
  display: flex;
  gap: 12px;
  margin-top: 22px;
}

.onboarding-btn {
  flex: 1;
  height: 50px;
  border: 0;
  border-radius: 999px;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out), opacity 150ms var(--ease-out);
}

.onboarding-btn--back {
  background: rgba(255, 255, 255, 0.09);
  color: rgba(255, 255, 255, 0.82);
}

.onboarding-btn--back:hover {
  background: rgba(255, 255, 255, 0.14);
}

/* Same blue as the confirm checkmark. */
.onboarding-btn--next {
  background: #007AFF;
  color: #fff;
}

.onboarding-btn--next:hover:not(:disabled) {
  background: #0A84FF;
}

.onboarding-btn--next:disabled {
  background: rgba(255, 255, 255, 0.07);
  color: rgba(166, 175, 188, 0.5);
  cursor: default;
}

/* ── Teaching: the Students roster ── */
/* The page owns the full height so the student column scrolls on its own. */
#teaching.active {
  display: flex;
  overflow: hidden;
}

.teaching-page {
  display: flex;
  flex: 1;
  min-height: 0;
}

.teaching-layout {
  display: grid;
  flex: 1;
  min-height: 0;
  grid-template-columns: 296px minmax(0, 1fr);
  gap: 22px;
}

.teaching-column {
  display: flex;
  min-height: 0;
  flex-direction: column;
  gap: 12px;
  padding-right: 20px;
  border-right: 1px solid rgba(255, 255, 255, 0.06);
}

.teaching-column-head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.teaching-search {
  display: flex;
  min-width: 0;
  flex: 1;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 12px;
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.28);
  color: rgba(255, 255, 255, 0.35);
  transition: border-color 150ms var(--ease-out);
}

.teaching-search svg {
  flex: 0 0 15px;
  width: 15px;
  height: 15px;
}

.teaching-search:focus-within {
  border-color: rgba(90, 169, 255, 0.5);
}

.teaching-search input {
  min-width: 0;
  flex: 1;
  border: 0;
  background: none;
  color: var(--text);
  font-size: 14px;
  outline: none;
}

.teaching-search input::placeholder {
  color: rgba(255, 255, 255, 0.28);
}

.teaching-search input::-webkit-search-cancel-button {
  display: none;
}

.teaching-add {
  display: grid;
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  border: 0;
  border-radius: 50%;
  background: #007AFF;
  color: #fff;
  cursor: pointer;
  place-items: center;
  transition: background 150ms var(--ease-out), transform 150ms var(--ease-out);
}

.teaching-add:hover {
  background: #0A84FF;
}

.teaching-add:active {
  transform: scale(0.94);
}

.teaching-column-list {
  min-height: 0;
  flex: 1;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.12) transparent;
}

.teaching-column-list::-webkit-scrollbar {
  width: 6px;
}

.teaching-column-list::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
}

.student-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border-radius: 12px;
  cursor: pointer;
  transition: background 150ms var(--ease-out);
}

.student-row:hover {
  background: rgba(255, 255, 255, 0.04);
}

.student-row.selected {
  background: rgba(255, 255, 255, 0.07);
}

/* The bar marks the selected row without shifting anything beside it. */
.student-row.selected::before {
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 0;
  width: 3px;
  border-radius: 999px;
  background: #2d83ff;
  content: "";
}

.student-avatar {
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.06);
}

.student-avatar--initial {
  display: grid;
  place-items: center;
  font-size: 15px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.5);
}

.student-name {
  overflow: hidden;
  flex: 1;
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.teaching-detail-handle {
  margin: 4px 0 0;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.35);
}

.student-status {
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(255, 209, 102, 0.14);
  color: #ffd166;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Removing is destructive, so it stays out of the way until the row is used. */
.student-remove {
  display: grid;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: rgba(255, 255, 255, 0.3);
  cursor: pointer;
  opacity: 0;
  place-items: center;
  transition: opacity 150ms var(--ease-out), background 150ms var(--ease-out), color 150ms var(--ease-out);
}

/* Phones only: the iOS-style disclosure chevron. */
.student-chevron {
  display: none;
}

.student-row:hover .student-remove,
.student-remove:focus-visible {
  opacity: 1;
}

.student-remove:hover {
  background: rgba(255, 107, 107, 0.16);
  color: #ff6b6b;
}

.teaching-note {
  margin: 0;
  padding: 18px 10px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.3);
}

.teaching-note--error {
  color: #ff6b6b;
}

.teaching-detail {
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
}

.teaching-detail::-webkit-scrollbar {
  display: none;
}

.teaching-placeholder {
  display: flex;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px;
  text-align: center;
}

.teaching-detail-name {
  margin: 0;
  font-size: 26px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.02em;
}

.mini-modal.add-student-modal {
  width: min(440px, calc(100vw - 48px));
  padding: 26px 28px 24px;
}

.add-student-modal .username-input-wrap {
  margin-top: 4px;
}

/* The field and its dropdown, so the list can hang off the field's edge. */
.add-student-field {
  position: relative;
}

.add-student-results {
  position: absolute;
  z-index: 5;
  top: calc(100% + 6px);
  right: 0;
  left: 0;
  max-height: 264px;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  background: #1b1e25;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.12) transparent;
}

.add-student-result {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 8px;
  border-radius: 10px;
  cursor: pointer;
}

.add-student-result.highlighted {
  background: rgba(255, 255, 255, 0.07);
}

/* Shown, but plainly not pickable. */
.add-student-result.unavailable {
  cursor: default;
  opacity: 0.45;
}

.add-student-avatar {
  flex: 0 0 28px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.06);
}

.add-student-avatar--initial {
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.5);
}

.add-student-result-name {
  overflow: hidden;
  flex: 1;
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.add-student-result-note {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.4);
  white-space: nowrap;
}

/* An inline action inside a sentence, e.g. the roster's "Try again". */
.link-button {
  border: 0;
  padding: 0;
  background: none;
  color: #5fa8ff;
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.link-button:hover {
  color: #8ec2ff;
}

/* The call to action in an empty state: a plain white pill, no border, and a
   step smaller than the modal buttons — it sits in open space rather than in a
   row of actions, so it does not need their weight. Margin lives here rather
   than on a container, since the two empty states it appears in (dashboard
   piece lists, Teaching's detail pane) don't share a wrapper. */
.empty-cta {
  height: 36px;
  margin-top: 18px;
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  background: #fff;
  color: #14171d;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: background 150ms var(--ease-out), transform 150ms var(--ease-out);
}

.empty-cta:hover {
  background: rgba(255, 255, 255, 0.86);
}

.empty-cta:active {
  transform: scale(0.97);
}

/* ── Teaching: a student's detail ── */
.teaching-detail-head {
  padding-bottom: 4px;
}

/* Practice and pieces answer the same question, so they share a row:
   the figures down the left, the list beside them. */
.teaching-overview {
  display: grid;
  align-items: start;
  gap: 22px;
  grid-template-columns: minmax(190px, 240px) minmax(0, 1fr);
  margin-top: 22px;
}

.teaching-overview-main {
  min-width: 0;
}

/* Stacked, since the column is narrower than three tiles across. */
.teaching-stats {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.teaching-overview .teaching-section-head {
  margin-top: -4px;
}

.teaching-stat {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px 20px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.035);
}

.teaching-stat-value {
  font-size: 24px;
  font-weight: 650;
  color: var(--text);
  letter-spacing: -0.025em;
}

.teaching-stat-label {
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.34);
}

.teaching-section {
  margin-top: 30px;
}

.teaching-section-head {
  display: flex;
  min-height: 34px;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 12px;
}

/* The app's own h3 is 20px/640; this was overriding it smaller for no reason. */
.teaching-section-title {
  margin: 0;
  font-size: 20px;
  font-weight: 640;
  color: var(--text);
  letter-spacing: -0.02em;
}

/* The count rides along inside the app's own selector button. */
.composer-sort-toggle .teaching-tab-count {
  margin-left: 5px;
  color: rgba(255, 255, 255, 0.4);
  font-variant-numeric: tabular-nums;
}

.composer-sort-toggle.active .teaching-tab-count {
  color: rgba(255, 255, 255, 0.6);
}

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

/* Read-only, so nothing about it should invite a click. */
.piece-card.teaching-piece {
  cursor: default;
}

.piece-card.teaching-piece:hover {
  transform: none;
}

/* ── Notes ── */
.teaching-notes {
  display: flex;
  flex-direction: column;
  margin-bottom: -8px;
}

.teaching-note-slot {
  margin-bottom: 8px;
}

.teaching-note {
  padding: 14px 16px 10px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.035);
}

/* The teacher's words, set apart from the student's. Both pages use it, so
   a note reads the same whichever side you are looking from. */
.teaching-note--teacher {
  border-left: 2px solid rgba(90, 169, 255, 0.45);
  background: rgba(90, 169, 255, 0.06);
}

.teaching-note-body {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.88);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.teaching-note-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}

.teaching-note-date {
  flex: 1;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.3);
}

.teaching-note-visibility {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.3);
}

.teaching-note-visibility.is-shown {
  color: #4caf82;
}

.teaching-note-btn {
  display: grid;
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: rgba(255, 255, 255, 0.4);
  cursor: pointer;
  place-items: center;
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out);
}

.teaching-note-btn:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}

.teaching-note-btn.is-on {
  color: #4caf82;
}

.teaching-note-btn--danger:hover {
  background: rgba(255, 107, 107, 0.16);
  color: #ff6b6b;
}

.teaching-composer {
  margin-bottom: 10px;
  padding: 12px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.045);
}

.teaching-composer-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.22);
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  line-height: 1.5;
  outline: none;
  resize: vertical;
}

.teaching-composer-input:focus {
  border-color: rgba(90, 169, 255, 0.5);
}

.teaching-composer-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 10px;
}

.teaching-empty {
  margin: 0;
  padding: 16px 2px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.3);
}

.teaching-empty--inline {
  padding: 18px 0 0;
}

.teaching-note-line {
  margin: 22px 0 0;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.34);
}

.teaching-note-line.teaching-note--error {
  color: #ff6b6b;
  background: none;
  border-left: 0;
  padding: 0;
}

@media (max-width: 900px) {
  .teaching-stats {
    grid-template-columns: 1fr;
  }
}

.teaching-piece-blank {
  min-height: 56px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.016);
}

.teaching-pager {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 10px;
}

.teaching-pager-btn {
  display: grid;
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.6);
  cursor: pointer;
  place-items: center;
  transition: background 150ms var(--ease-out), color 150ms var(--ease-out);
}

.teaching-pager-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

.teaching-pager-btn:disabled {
  color: rgba(255, 255, 255, 0.18);
  cursor: default;
}

.teaching-pager-info {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.34);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 1100px) {
  .teaching-overview {
    grid-template-columns: 1fr;
  }

  .teaching-stats {
    flex-direction: row;
  }

  .teaching-stat {
    flex: 1;
  }
}

/* The composer reads as it does on the pieces page, but this row is a
   read-only copy of someone else's piece, so it is not a link. */
.piece-composer-link--static {
  cursor: default;
}

.piece-composer-link--static:hover {
  color: #74adff;
  text-shadow: none;
}

/* Always rendered, so paging and tab switches never move the notes below. */
.teaching-pager-info.is-idle {
  color: rgba(255, 255, 255, 0.18);
}

/* ── Note animations ── */
/* iOS's default curve: a fast start that settles rather than easing evenly.
   Notably no overshoot — Apple springs for gestures, not for list inserts. */
:root {
  --ease-ios: cubic-bezier(0.32, 0.72, 0, 1);
}

/* The composer opens by growing its own row, so the notes under it are pushed
   down instead of being shoved. */
.teaching-composer {
  overflow: hidden;
  transition:
    max-height 320ms var(--ease-ios),
    opacity 200ms var(--ease-ios),
    margin-bottom 320ms var(--ease-ios),
    padding 320ms var(--ease-ios);
  max-height: 220px;
  opacity: 1;
}

.teaching-composer.is-entering {
  max-height: 0;
  margin-bottom: 0;
  padding-top: 0;
  padding-bottom: 0;
  opacity: 0;
}

/* A new note opens its own height from nothing — 0fr to 1fr animates to the
   row's real height, so the list below slides rather than jumping by a
   guessed max-height. */
.teaching-note-slot {
  display: grid;
  grid-template-rows: 1fr;
}

.teaching-note-slot > * {
  min-height: 0;
}

.teaching-note-slot.is-new {
  animation: teachingNoteSlot 420ms var(--ease-ios) both;
}

.teaching-note-slot.is-new > .teaching-note {
  animation: teachingNoteBody 420ms var(--ease-ios) both;
}

@keyframes teachingNoteSlot {
  from {
    grid-template-rows: 0fr;
    margin-bottom: 0;
  }
  to {
    grid-template-rows: 1fr;
    margin-bottom: 8px;
  }
}

@keyframes teachingNoteBody {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .teaching-composer,
  .teaching-note-slot.is-new,
  .teaching-note-slot.is-new > .teaching-note {
    animation: none;
    transition: none;
  }
}

/* ── Teaching: notes and tasks side by side ── */
.teaching-columns {
  display: grid;
  align-items: start;
  gap: 22px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.teaching-columns > .teaching-section {
  min-width: 0;
}

.teaching-title-count {
  margin-left: 6px;
  color: rgba(255, 255, 255, 0.32);
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* The round add button, matching the students column's. */
.teaching-round-add {
  display: grid;
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  border: 0;
  border-radius: 50%;
  background: #007AFF;
  color: #fff;
  cursor: pointer;
  place-items: center;
  transition: background 150ms var(--ease-ios), transform 150ms var(--ease-ios);
}

.teaching-round-add:hover {
  background: #0A84FF;
}

.teaching-round-add:active {
  transform: scale(0.92);
}

/* ── Tasks ── */
.task-list {
  display: flex;
  flex-direction: column;
  margin-bottom: -8px;
}

.task-slot {
  margin-bottom: 8px;
}

/* The gradient is computed per task from its own text. */
.task-card {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 14px 14px 15px;
  border-radius: 16px;
  background: var(--task-gradient, linear-gradient(135deg, #2b6f8f, #24707a));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  transition: opacity 320ms var(--ease-ios), filter 320ms var(--ease-ios);
}

/* Finishing wipes across the card left to right, the way a swipe would carry
   it. The greying lives on this veil rather than on the card, because a filter
   on the card itself can only fade the whole thing at once — a clip-path can
   be dragged across. */
.task-card::after {
  position: absolute;
  z-index: 1;
  border-radius: inherit;
  backdrop-filter: saturate(0.3);
  -webkit-backdrop-filter: saturate(0.3);
  background: rgba(9, 13, 19, 0.46);
  content: "";
  inset: 0;
  pointer-events: none;
  /* Collapsed against the left edge; it opens rightward. */
  clip-path: inset(0 100% 0 0);
  transition: clip-path 460ms var(--ease-ios);
}

.task-card.is-done::after {
  clip-path: inset(0 0 0 0);
}

.task-copy {
  position: relative;
  z-index: 2;
  display: flex;
  min-width: 0;
  flex: 1;
  flex-direction: column;
  gap: 5px;
  padding-top: 1px;
}

.task-body {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.45;
  color: #fff;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  transition: opacity 260ms var(--ease-ios);
}

.task-body {
  text-decoration: line-through;
  text-decoration-color: transparent;
  text-decoration-thickness: 1.5px;
  transition: text-decoration-color 300ms var(--ease-ios) 160ms;
}

.task-card.is-done .task-body {
  text-decoration-color: rgba(255, 255, 255, 0.5);
}

.task-done-date {
  font-size: 11.5px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.72);
}

/* An iOS-style tick: an empty ring that fills, with the mark drawn in. */
.task-check {
  position: relative;
  z-index: 2;
  display: grid;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  /* Centred on the card's height, not pinned to the first line. */
  align-self: center;
  margin-top: 0;
  padding: 0;
  border: 2px solid rgba(255, 255, 255, 0.55);
  border-radius: 50%;
  background: transparent;
  color: transparent;
  cursor: pointer;
  place-items: center;
  transition:
    background 220ms var(--ease-ios),
    border-color 220ms var(--ease-ios),
    transform 220ms var(--ease-ios);
}

.task-check:hover {
  border-color: rgba(255, 255, 255, 0.85);
}

.task-check:active {
  transform: scale(0.88);
}

.task-check svg {
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 180ms var(--ease-ios), transform 260ms var(--ease-ios);
}

.task-card.is-done .task-check {
  border-color: #fff;
  background: #fff;
  color: #14312b;
}

.task-card.is-done .task-check svg {
  opacity: 1;
  transform: scale(1);
}

/* A touch past full size, then settle. Applied on the click only, so a later
   redraw of an already-done card does not bounce it again. */
.task-card.is-ticking .task-check svg {
  animation: taskTick 340ms var(--ease-ios) both;
}

@keyframes taskTick {
  0% { transform: scale(0.5); }
  55% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

.task-remove {
  position: relative;
  z-index: 2;
  display: grid;
  /* The card is align-items: flex-start so the tick stays with the first line
     of a wrapped task; this one belongs on the row's centre line instead. */
  align-self: center;
  margin-block: auto;
  width: 22px;
  height: 22px;
  flex: 0 0 22px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: rgba(255, 255, 255, 0.5);
  cursor: pointer;
  opacity: 0;
  place-items: center;
  transition: opacity 150ms var(--ease-ios), background 150ms var(--ease-ios), color 150ms var(--ease-ios);
}

.task-card:hover .task-remove,
.task-remove:focus-visible {
  opacity: 1;
}

.task-remove:hover {
  background: rgba(0, 0, 0, 0.25);
  color: #fff;
}

/* A new task opens its own height, like a note. */
.task-slot {
  display: grid;
  grid-template-rows: 1fr;
}

.task-slot > * {
  min-height: 0;
}

.task-slot.is-new {
  animation: teachingNoteSlot 420ms var(--ease-ios) both;
}

.task-slot.is-new > .task-card {
  animation: taskCardIn 420ms var(--ease-ios) both;
}

@keyframes taskCardIn {
  from {
    opacity: 0;
    transform: translateY(-4px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .task-slot.is-new,
  .task-slot.is-new > .task-card,
  .task-card.is-ticking .task-check svg {
    animation: none;
  }

  .task-card::after,
  .task-body {
    transition: none;
  }
}

@media (max-width: 1100px) {
  .teaching-columns {
    grid-template-columns: 1fr;
  }
}

/* ── Deleting in place ── */
/* Standing in for a swipe: the first click reveals this, and only a click on
   it removes anything. It slides in from the right, the way the red button
   does behind a swiped row on iOS. */
.row-delete-confirm {
  flex: 0 0 auto;
  align-self: center;
  height: 26px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: #e5484d;
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  animation: rowDeleteReveal 260ms var(--ease-ios) both;
  transition: background 150ms var(--ease-ios);
}

.row-delete-confirm:hover {
  background: #f05257;
}

/* The student column is narrow, so this one stays compact and the name
   truncates behind it. */
.row-delete-confirm--student {
  height: 24px;
  padding: 0 10px;
  font-size: 12px;
}

.student-row.is-arming {
  background: rgba(229, 72, 77, 0.1);
}

/* On a task the card is already coloured, so the button needs its own ground. */
.row-delete-confirm--onCard {
  position: relative;
  z-index: 2;
  margin-top: -1px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}

@keyframes rowDeleteReveal {
  from {
    opacity: 0;
    transform: translateX(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

/* The row itself steps back while it is armed, so it is obvious which one is
   about to go. */
.teaching-note.is-arming,
.task-card.is-arming {
  outline: 1.5px solid rgba(229, 72, 77, 0.5);
  outline-offset: 1px;
  transition: outline-color 200ms var(--ease-ios);
}

.task-card.is-arming .task-remove,
.teaching-note.is-arming .teaching-note-btn--danger {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .row-delete-confirm {
    animation: none;
  }
}

/* ── Section tools: the Active/Archived selector beside the add button ── */
.teaching-section-tools {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* A step smaller than the Pieces selector — these sit in a narrower column
   next to a round button. */
.teaching-view-toggle .composer-sort-toggle {
  padding: 4px 11px;
  font-size: 12.5px;
}

/* Archiving: the row closes its own height and the list draws up behind it,
   rather than the row blinking out of existence. */
.teaching-note-slot.is-leaving,
.task-slot.is-leaving,
.teaching-note-slot.is-new,
.task-slot.is-new {
  overflow: hidden;
}

.teaching-note-slot.is-leaving,
.task-slot.is-leaving {
  animation: teachingRowLeave 190ms var(--ease-ios) both;
  pointer-events: none;
}

/* The done-veil re-samples what is behind it on every frame, which is real
   work to be doing while the row's geometry is changing. A row on its way out
   does not need a live filter — a flat wash looks the same in motion. */
.task-slot.is-leaving .task-card::after {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transition: none;
}



/* Opacity and transform only — nothing here forces a layout. */
@keyframes teachingRowLeave {
  from {
    opacity: 1;
    transform: none;
  }
  to {
    opacity: 0;
    transform: translateX(14px) scale(0.97);
  }
}

@media (prefers-reduced-motion: reduce) {
  .teaching-note-slot.is-leaving,
  .task-slot.is-leaving,
  .teaching-note-slot.is-leaving > *,
  .task-slot.is-leaving > * {
    animation: none;
  }
}

/* A list with more behind it gets a quiet line rather than a long scroll,
   separated from the last row the way a grouped iOS list separates its footer. */
.see-more {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 11px 0 2px;
  border: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.07);
  background: none;
  color: #5fa8ff;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: color 150ms var(--ease-ios);
}

.see-more:hover {
  color: #8ec2ff;
}

/* ── Teaching: the student's mastery badge ── */
/* Back (phones), name, their tier badge right beside it, and their photo
   at the far right. */
.teaching-detail-head {
  display: flex;
  align-items: center;
  gap: 14px;
}

.teaching-detail-who {
  flex: 0 1 auto;
  min-width: 0;
}

.teaching-detail-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.student-badge-slot {
  margin-left: auto;
}

.student-badge-slot:empty {
  display: none;
}

.teaching-detail-avatar {
  flex: 0 0 52px;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.06);
}

.teaching-detail-avatar--initial {
  display: grid;
  place-items: center;
  color: rgba(255, 255, 255, 0.5);
  font-size: 20px;
  font-weight: 600;
}

/* Only a phone shows this: there the roster and the student take turns, so
   there has to be a way back. On a wide screen both panes are on screen. */
.teaching-back {
  display: none;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  cursor: pointer;
  padding: 0;
}

.teaching-back:active {
  background: rgba(255, 255, 255, 0.12);
}

/* Their tier, next to their name. The ring shows how far into the tier they
   are, on the same 75% XP / 25% pieces split the mastery page uses. */
.student-badge {
  position: relative;
  display: grid;
  width: 48px;
  height: 48px;
  flex: 0 0 48px;
  place-items: center;
}

.student-badge-ring {
  position: absolute;
  inset: 0;
  width: 48px;
  height: 48px;
  transform: rotate(-90deg);
}

.student-badge-track {
  fill: none;
  stroke: rgba(255, 255, 255, 0.08);
  stroke-width: 3;
}

.student-badge-fill {
  fill: none;
  stroke: #5aa9ff;
  stroke-linecap: round;
  stroke-width: 3;
  transition: stroke-dashoffset 600ms var(--ease-ios);
}

.student-badge-img {
  width: 32px;
  height: 32px;
  object-fit: contain;
}

/* The name and number only when asked for, so the badge stays a glance. */
.student-badge-tip {
  position: absolute;
  z-index: 5;
  top: calc(100% + 8px);
  right: 0;
  padding: 6px 10px;
  border-radius: 8px;
  background: #1b1e25;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);
  color: var(--text);
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity 160ms var(--ease-ios), transform 160ms var(--ease-ios);
}

.student-badge:hover .student-badge-tip,
.student-badge:focus-visible .student-badge-tip {
  opacity: 1;
  transform: translateY(0);
}

/* ── Lessons: the student's side of the link ── */
/* No student column here, so the page itself is what scrolls. */
#lessons.active {
  display: flex;
  overflow: hidden;
}

.lessons-page {
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  padding-right: 6px;
}

.lessons-page::-webkit-scrollbar {
  width: 0;
}

/* A thin pill rather than a page-title-sized heading — this is a byline, not
   the point of the page. */
.lessons-head {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 22px;
  padding: 6px 16px 6px 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.07);
}

.lessons-teacher-avatar {
  flex: 0 0 30px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  object-fit: cover;
  background: rgba(255, 255, 255, 0.06);
}

.lessons-teacher-avatar--initial {
  display: grid;
  place-items: center;
  font-size: 12.5px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.55);
}

.lessons-head-text {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 13.5px;
}

/* "My Teacher" is the label, the name is the thing — so the label steps back
   rather than competing with it. */
.lessons-head-label {
  color: rgba(255, 255, 255, 0.42);
  font-weight: 600;
}

.lessons-head-name {
  color: var(--text);
  font-weight: 600;
}

.lessons-pending {
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  color: rgba(255, 255, 255, 0.5);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* Tasks take the left half; both note lists stack down the right. */
.lessons-columns {
  align-items: start;
}

.lessons-stack {
  min-width: 0;
}

/* Desktop modal titles: one style, blue, at New Exercise Collection's size.
   Phones use 20px (see the mobile block). Kept in a min-width query so it
   cannot outrank that rule by source order. */
@media (min-width: 769px) {
  .modal-backdrop .mini-modal h3,
  .modal-backdrop .practice-day-editor h3,
  .avatar-crop-backdrop .avatar-crop-dialog h3 {
    font-size: 26px;
    font-weight: 640;
    line-height: 1.2;
    color: var(--blue);
  }

  /* New Piece / Edit Piece size their title with !important. */
  .modal-backdrop .piece-create-header h3 {
    font-size: 26px !important;
    line-height: 1.2 !important;
  }
}

/* Metronome beats editor on the narrowest phones: just the number. */
@media (max-width: 380px) {
  .metronome-beats-word {
    display: none;
  }
  .metronome-beats-count {
    min-width: 36px;
  }
}

/* Metronome on a phone: bigger dots, a bigger Tap, edit and Play (nudged
   down; the row keeps its height in the layout so the dial stays put), and
   a bigger beats pill showing just the number. */
@media (max-width: 768px) {
  #metronomeBeats {
    --dot: 32px;
  }
  .metronome-controls {
    height: 54px;
    transform: translateY(18px);
  }
  #metronomeTap,
  #metronomePlay {
    flex-basis: 72px;
    width: 72px;
    height: 72px;
  }
  #metronomeTap {
    font-size: 15px;
  }
  #metronomePlay svg {
    width: 32px;
    height: 32px;
  }
  #metronomeEditBeats {
    width: 56px;
    height: 56px;
  }
  #metronomeEditBeats svg {
    width: 22px;
    height: 22px;
  }
  .metronome-beats-editor {
    gap: 6px;
    clip-path: inset(0 calc(50% - 28px) round 999px);
  }
  .metronome-step {
    width: 40px;
    height: 40px;
    font-size: 24px;
  }
  .metronome-beats-word {
    display: none;
  }
  .metronome-beats-count {
    min-width: 28px;
    padding: 0;
    font-size: 19px;
  }
}

@media (max-width: 360px) {
  .metronome-step {
    width: 36px;
    height: 36px;
  }
  .metronome-beats-count {
    min-width: 24px;
  }
}

/* Phone search bars (Pieces, Exercises, Teaching), styled like iOS: a flat
   pill a touch lighter than the background, a magnifying glass, "Search". */
@media (max-width: 768px) {
  .topbar .search,
  #teachingPage .teaching-search {
    gap: 8px;
    height: 40px;
    padding: 0 12px;
    border: 0;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.09);
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    color: rgba(235, 235, 245, 0.6);
  }
  .topbar .search .search-icon {
    display: none;
  }
  .topbar .search .search-glyph,
  #teachingPage .teaching-search svg {
    display: block;
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    color: #fff;
  }
  .topbar .search input,
  #teachingPage .teaching-search input {
    margin-left: 0;
  }
  /* 17px like iOS (still over the 16px that stops iOS zooming on focus);
     by ID and !important to beat the phone rule setting every input to 16. */
  #searchInput,
  #teachingSearch {
    font-size: 17px !important;
  }
  .topbar .search input::placeholder,
  #teachingPage .teaching-search input::placeholder {
    color: rgba(235, 235, 245, 0.6);
  }
  .topbar-actions.levels-mode .topbar-plus-button,
  .topbar-actions.exercises-mode .topbar-plus-button,
  #teachingPage .teaching-add {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
  }
  /* The + beside each search: the Teaching blue circle everywhere, with a
     bigger plus (18px long) drawn the same on all three. */
  .topbar-actions.levels-mode .topbar-plus-button,
  .topbar-actions.exercises-mode .topbar-plus-button {
    border: 0;
    background: #007AFF;
    color: #fff;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .topbar-actions.levels-mode .topbar-plus-button > span::before,
  .topbar-actions.levels-mode .topbar-plus-button > span::after,
  .topbar-actions.exercises-mode .topbar-plus-button > span::before,
  .topbar-actions.exercises-mode .topbar-plus-button > span::after {
    width: 18px;
    height: 2.6px;
  }
  #teachingPage .teaching-add svg {
    width: 31px;
    height: 31px;
    stroke-width: 2;
  }
}

/* Phone student list, iOS style: bigger avatars and names, a chevron on
   each row, hairline separators inset to the name, no highlighted row.
   The hover-only remove button has nowhere to show on touch, so it gives
   way to the chevron. */
@media (max-width: 768px) {
  #teachingPage .student-row {
    gap: 14px;
    padding: 10px 2px 10px 0;
    border-radius: 0;
  }
  #teachingPage .student-row:hover,
  #teachingPage .student-row.selected {
    background: none;
  }
  #teachingPage .student-row.selected::before {
    display: none;
  }
  #teachingPage .student-row::after {
    content: "";
    position: absolute;
    left: 58px;
    right: 0;
    bottom: 0;
    height: 1px;
    background: rgba(84, 84, 88, 0.65);
    transform: scaleY(0.5);
    transform-origin: bottom;
  }
  #teachingPage .student-row:last-child::after {
    display: none;
  }
  #teachingPage .student-avatar {
    flex-basis: 44px;
    width: 44px;
    height: 44px;
  }
  #teachingPage .student-avatar--initial {
    font-size: 18px;
  }
  #teachingPage .student-name {
    font-size: 17px;
    font-weight: 500;
  }
  #teachingPage .student-remove,
  #teachingPage .row-delete-confirm--student {
    display: none;
  }
  #teachingPage .student-chevron {
    display: block;
    flex: 0 0 9px;
    color: rgba(235, 235, 245, 0.3);
  }
}

/* Phone Teaching push/back: both panes share one cell while they slide, the
   student page on top. */
@media (max-width: 768px) {
  #teachingPage .teaching-layout.is-pushing {
    overflow: hidden;
  }
  #teachingPage .teaching-layout.is-pushing > .teaching-column,
  #teachingPage .teaching-layout.is-pushing > .teaching-detail {
    grid-area: 1 / 1;
    will-change: transform, opacity;
  }
  #teachingPage .teaching-layout.is-pushing > .teaching-column {
    display: flex;
  }
  #teachingPage .teaching-layout.is-pushing > .teaching-detail {
    position: relative;
    display: block;
    z-index: 2;
  }
  #teachingPage .teaching-layout.is-pushing > .teaching-column {
    position: relative;
    z-index: 1;
  }
}

/* Phone Pieces rows: the exact format of the student page's piece rows
   (.piece-card) — 56px tall, 8px level bar, the same level box, the stronger
   colour fade, title over an 11px composer line, and the stage on the right.
   By ID to beat the wide layout's !important grid rules. */
@media (max-width: 768px) {
  #levels .piece-row {
    display: flex !important;
    align-items: center;
    gap: 10px !important;
    min-height: 56px;
    padding: 5px 14px 5px 18px !important;
    background:
      linear-gradient(
        90deg,
        color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 20%, transparent) 0%,
        color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 10%, transparent) 30%,
        color-mix(in srgb, var(--level-tertiary-color, var(--level-color, #7bb7ff)) 4%, transparent) 52%,
        transparent 68%
      ),
      rgba(255, 255, 255, 0.045);
  }
  #levels .piece-row .piece-level-marker {
    flex: 0 0 58px;
    width: 58px;
    height: 44px;
    padding: 6px 6px 5px;
    border-radius: 7px;
  }
  #levels .piece-row .piece-level-marker strong {
    font-size: 24px;
  }
  #levels .piece-row .piece-copy {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
  }
  #levels .piece-row .piece-title {
    margin-bottom: 1px;
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #levels .piece-row .piece-meta {
    font-size: 11px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #levels .piece-row .stage-status {
    display: inline-flex !important;
    flex: 0 0 auto;
    width: auto !important;
    margin-left: auto;
  }
  /* The list's rows were at least 70px; the student page's are 56, 6 apart. */
  #levels .levels-list {
    grid-auto-rows: minmax(56px, auto);
    gap: 6px;
  }
}

/* Recorded rows on a phone: the gold tick (the row's open icon) in place of
   the stage label, as the student page shows it. */
@media (max-width: 768px) {
  #levels .piece-row:has(.stage-status.Recorded) .stage-status {
    display: none !important;
  }
  #levels .piece-row:has(.stage-status.Recorded) .piece-open-icon {
    position: relative;
    z-index: 4;
    display: grid !important;
    place-items: center;
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    margin-left: auto;
    padding-left: 12px;
    box-sizing: content-box;
    transform: none !important;
  }
  #levels .piece-row:has(.stage-status.Recorded) .piece-open-icon svg {
    width: 20px;
    height: 20px;
    overflow: visible;
    fill: none;
  }
}

/* A phone opens the status editor from anywhere on a Pieces row. */
@media (max-width: 768px) {
  #levels .piece-row {
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
}

/* Wide screens: when the level pills would wrap (fitLevelFilterPills), they
   take the phone's form — the All Levels button, the pills in a sheet. */
.level-filter-row.levels-collapsed {
  position: relative;
}

.level-filter-row.levels-collapsed .level-filter-menu-btn {
  grid-column: 1;
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: 7px;
  padding: 8px 13px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text);
  font-size: 12.5px;
  font-weight: 650;
  white-space: nowrap;
  cursor: pointer;
}

.level-filter-row.levels-collapsed.levels-open .level-filter-menu-btn {
  border-color: rgba(122, 176, 255, 0.5);
  color: #cfe2ff;
}

.level-filter-row.levels-collapsed .level-filter-pills {
  position: absolute;
  z-index: 30;
  top: calc(100% + 6px);
  left: 0;
  display: none;
  width: 320px;
  max-width: 100%;
  flex-wrap: wrap;
  gap: 6px;
  padding: 12px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 16px;
  background: #141924;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
}

.level-filter-row.levels-collapsed.levels-open .level-filter-pills {
  display: flex;
}

.level-filter-row.levels-collapsed .level-filter-pill:not(.active) .level-filter-full {
  max-width: 0;
}

/* Dashboard columns stacked (fitDashboardColumns): the piece list, then the
   right-hand cards at full width; the timer, metronome and Perfect Practice
   share a row, or the timer takes its own above the other two. */
@media (min-width: 769px) {
  #dashboard .dashboard-main-grid.is-stacked {
    grid-template-columns: minmax(0, 1fr);
  }
  #dashboard .dashboard-main-grid.is-stacked .dashboard-right-column {
    grid-template-rows: auto 164px;
  }
  #dashboard .dashboard-main-grid.tools-wrap .dashboard-right-column {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto 164px 164px;
  }
  #dashboard .dashboard-main-grid.tools-wrap #todayLogCard {
    grid-column: 1 / -1;
  }
}

/* Wide-screen piece rows (Pieces page and the dashboard's Pieces widget)
   adapt to their list's width, every row alike so the
   columns stay aligned: the full row from 1000px, the finished date dropped
   below that, and the source tag below 780px. The title column never goes
   under 220px, and the title and composer line end in "…" rather than
   running into the next column. (A phone has its own row, from 768px.) */
#levelAccordion,
#dashboard .dashboard-piece-list {
  container: pieceslist / inline-size;
}

@media (min-width: 769px) {
  :is(#levels, #dashboard) .piece-row .piece-copy {
    min-width: 0;
    overflow: hidden;
  }
  :is(#levels, #dashboard) .piece-row .piece-title,
  :is(#levels, #dashboard) .piece-row .piece-meta {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  @container pieceslist (max-width: 999px) {
    :is(#levels, #dashboard) .piece-row {
      grid-template-columns: 86px minmax(220px, 1fr) 180px 118px 38px !important;
    }
    :is(#levels, #dashboard) .piece-row .piece-finished-date,
    :is(#levels, #dashboard) .piece-row .piece-finished-date:empty {
      display: none !important;
    }
    :is(#levels, #dashboard) .piece-row .piece-open-icon {
      grid-column: 5 !important;
    }
  }

  @container pieceslist (max-width: 779px) {
    :is(#levels, #dashboard) .piece-row {
      grid-template-columns: 86px minmax(0, 1fr) 118px 38px !important;
    }
    :is(#levels, #dashboard) .piece-row .piece-source {
      display: none !important;
    }
    :is(#levels, #dashboard) .piece-row .stage-status {
      grid-column: 3 !important;
    }
    :is(#levels, #dashboard) .piece-row .piece-open-icon {
      grid-column: 4 !important;
    }
  }
}

/* Phone Teaching: the student page and the roster scroll up and down only.
   Anything wider than the screen is clipped rather than letting the pane
   (or iOS's bounce) slide sideways under a drag. */
@media (max-width: 768px) {
  #teaching,
  #teachingPage,
  #teachingPage .teaching-layout {
    overflow-x: hidden;
  }
  #teachingPage .teaching-detail,
  #teachingPage .teaching-column-list {
    overflow-x: hidden;
    overscroll-behavior-x: none;
    touch-action: pan-y;
  }
  #teachingPage .teaching-detail > * {
    min-width: 0;
    max-width: 100%;
  }
}

/* ── Practice streak card ─────────────────────────────────────────────────
   Beside Mastery, sharing the row 50/50. Blue fire: one flame design per
   milestone, each bigger and more elaborate; the big flame is the one for the
   stage reached and flickers. Along the bar, reached milestones are still,
   the latest flickers, and the ones ahead are grey outlines. */
.dashboard-grid .metric-card.mastery-dash-card,
.dashboard-grid .streak-card {
  flex: 1 1 0;
  min-width: 0;
}

.panel.streak-card {
  box-sizing: border-box;
  margin: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 12px;
  padding: 14px 20px 16px;
  cursor: pointer;
  animation: none !important;
  transition: transform 150ms ease-out, background 150ms ease-out !important;
}

.panel.streak-card:hover {
  transform: scale(1.02);
  background: rgba(255, 255, 255, 0.07);
}

/* Flame and record on the left, the current streak on the far right with
   what to do next beside it. */
.streak-top {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.streak-flame {
  flex: 0 0 52px;
  width: 52px;
  height: 52px;
  overflow: visible;
  filter: drop-shadow(0 0 10px rgba(77, 156, 255, 0.55));
}

.streak-flame-body {
  fill: url(#streakFlameGradient);
}

.streak-flame-core {
  fill: #d8ecff;
  opacity: 0.85;
}

.streak-flame-ember {
  fill: #9fd0ff;
}

.streak-flame .streak-flame-body,
.streak-marker.is-current .streak-flame-body {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: streak-flicker 1.6s ease-in-out infinite;
}

.streak-flame .streak-flame-core {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: streak-flicker-core 1.1s ease-in-out infinite;
}

.streak-flame .streak-flame-ember,
.streak-marker.is-current .streak-flame-ember {
  animation: streak-ember 1.8s ease-in-out infinite;
}

.streak-flame .streak-flame-ember:nth-of-type(2n),
.streak-marker.is-current .streak-flame-ember:nth-of-type(2n) {
  animation-delay: -0.9s;
}

@keyframes streak-flicker {
  0%, 100% { transform: scale(1, 1) skewX(0deg); }
  25% { transform: scale(0.97, 1.04) skewX(-2deg); }
  50% { transform: scale(1.02, 0.97) skewX(1.5deg); }
  75% { transform: scale(0.98, 1.03) skewX(-1deg); }
}

@keyframes streak-flicker-core {
  0%, 100% { transform: scale(1, 1); opacity: 0.85; }
  40% { transform: scale(0.9, 1.08); opacity: 1; }
  70% { transform: scale(1.05, 0.94); opacity: 0.75; }
}

@keyframes streak-ember {
  0%, 100% { opacity: 0.35; transform: translateY(0); }
  50% { opacity: 1; transform: translateY(-1.2px); }
}

/* No streak yet: an outline of the flame, nothing burning. */
.streak-card.is-empty .streak-flame {
  filter: none;
}

.streak-card.is-empty .streak-flame .streak-flame-body {
  fill: none;
  stroke: rgba(255, 255, 255, 0.22);
  stroke-width: 1.4;
  animation: none;
}

.streak-card.is-empty .streak-flame :is(.streak-flame-core, .streak-flame-ember) {
  display: none;
}

/* Today not logged yet: the streak stands, but the flame burns low. */
.streak-card.is-at-risk .streak-flame {
  opacity: 0.5;
  filter: none;
}

.streak-left {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.streak-left .dashboard-card-label {
  margin: 0;
}

.streak-best {
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
}

.streak-best strong {
  margin-left: 2px;
  color: var(--text);
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* What to do next, and Log while today is not in yet, at the right edge. */
.streak-action {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  min-width: 0;
  margin-left: auto;
}

.streak-log {
  flex: 0 0 auto;
}

.streak-days {
  display: flex;
  flex: 0 0 auto;
  align-items: baseline;
  gap: 6px;
  color: var(--muted);
  font-size: 14px;
  font-weight: 600;
}

/* Flame, the count, then "Day Streak" over the record. */
.streak-days strong {
  color: var(--text);
  font-size: 34px;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.streak-sub {
  overflow: hidden;
  color: var(--muted);
  font-size: 14px;
  text-align: right;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.streak-card.is-at-risk .streak-sub {
  color: #7bb7ff;
}

.streak-track-wrap {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.streak-markers {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  align-items: end;
}

/* Each marker sits at the right end of its own step of the bar, the flame
   centred over its number. */
.streak-marker {
  display: flex;
  justify-content: flex-end;
}

.streak-marker-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.streak-marker .streak-marker-flame {
  overflow: visible;
}

.streak-marker small {
  color: var(--muted);
  font-size: 10px;
  font-weight: 600;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.streak-marker.is-future .streak-flame-body {
  fill: none;
  stroke: rgba(255, 255, 255, 0.2);
  stroke-width: 1.6;
}

.streak-marker.is-future :is(.streak-flame-core, .streak-flame-ember) {
  display: none;
}

.streak-marker.is-future small {
  color: rgba(255, 255, 255, 0.28);
}

.streak-marker.is-current .streak-marker-flame {
  filter: drop-shadow(0 0 5px rgba(77, 156, 255, 0.7));
}

.streak-marker.is-current small {
  color: #7bb7ff;
}

.streak-track {
  height: 14px;
  overflow: hidden;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
}

.streak-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #2d83ff, #7bb7ff);
  transition: width 600ms var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  .streak-card svg :is(path, circle) {
    animation: none !important;
  }
}

/* Phone: Mastery stays near the top; the streak card follows the Metronome /
   Perfect Practice row, then Most Played and Completed Pieces. */
@media (max-width: 768px) {
  #dashboard .dashboard-grid {
    display: contents;
  }
  #dashboard .mastery-dash-card {
    order: 0;
    flex-shrink: 0;
  }
  #dashboard .streak-card {
    order: 1;
    flex-shrink: 0;
    width: 100%;
    box-sizing: border-box;
  }
  #dashboard .most-played-card {
    order: 2;
  }
  #dashboard .completed-pieces-panel {
    order: 3;
  }
}

/* The "Done!" pill is the phone's way of saying today is in; a wide card
   says it with the cheer instead. */
.streak-done {
  display: none;
}

/* Phone: one line. The hint goes; the button reads "Log today", and once
   today is logged it becomes a grey "Done!" pill. */
@media (max-width: 768px) {
  #dashboard .streak-top {
    gap: 10px;
  }
  #dashboard .streak-flame {
    flex-basis: 44px;
    width: 44px;
    height: 44px;
  }
  #dashboard .streak-sub {
    display: none;
  }
  #dashboard .streak-log-label {
    font-size: 0;
  }
  #dashboard .streak-log-label::after {
    content: "Log today";
    font-size: 13px;
  }
  #dashboard .streak-log {
    padding: 0 14px;
  }
  #dashboard .streak-done {
    display: inline-flex;
    align-items: center;
    height: 34px;
    padding: 0 14px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    color: var(--muted);
    font-size: 13px;
    font-weight: 750;
    white-space: nowrap;
  }
}

/* Streak: still until today is logged; logging from the card lights it. */
.streak-card.is-at-risk .streak-flame :is(path, circle) {
  animation: none;
}

.streak-card.is-igniting .streak-flame {
  transform-origin: 50% 90%;
  animation: streak-ignite 1000ms cubic-bezier(0.2, 0.9, 0.3, 1.15) both;
}

.streak-card.is-igniting .streak-flame :is(path, circle) {
  animation: none;
}

@keyframes streak-ignite {
  0% { opacity: 0.5; transform: scale(0.6); filter: none; }
  45% { opacity: 1; transform: scale(1.25); filter: drop-shadow(0 0 22px rgba(90, 169, 255, 0.95)); }
  100% { opacity: 1; transform: scale(1); filter: drop-shadow(0 0 10px rgba(77, 156, 255, 0.55)); }
}

.streak-days strong {
  display: inline-block;
  transition: color 1200ms ease;
}

.streak-days strong.is-lit {
  color: #5aa9ff;
  transition: color 150ms ease;
  animation: streak-number-pop 700ms cubic-bezier(0.34, 1.4, 0.64, 1);
}

@keyframes streak-number-pop {
  0% { transform: scale(1); }
  35% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* Narrowest phones (iPhone SE size): a touch smaller, so the streak row
   still fits on one line with a three-digit count. */
@media (max-width: 380px) {
  #dashboard .streak-top {
    gap: 8px;
  }
  #dashboard .panel.streak-card {
    padding-inline: 14px;
  }
  #dashboard .streak-flame {
    flex-basis: 36px;
    width: 36px;
    height: 36px;
  }
  #dashboard .streak-days {
    gap: 4px;
    font-size: 12px;
  }
  #dashboard .streak-days strong {
    font-size: 26px;
  }
  #dashboard .streak-log,
  #dashboard .streak-done {
    padding: 0 10px;
  }
  #dashboard .streak-log-label::after,
  #dashboard .streak-done {
    font-size: 12px;
  }
}

/* Phone dashboard: the Mastery card's wide-screen padding and gaps (more
   specific than its phone rule) pushed its chevron past the screen edge,
   which let the page slide sideways. These fit it inside the card, and the
   dashboard scrolls up and down only. */
@media (max-width: 768px) {
  #dashboard .metric-card.mastery-dash-card {
    gap: 10px;
    padding: 12px 14px;
  }
  #dashboard .mastery-dash-badge {
    width: 52px;
    height: 52px;
  }
  #dashboard .mastery-dash-card .mastery-dash-name {
    font-size: 23px;
  }
  #dashboard .mastery-dash-rings {
    margin-left: auto;
  }
  #dashboard .mastery-dash-chevron {
    margin-left: 0;
  }
  #dashboard {
    overflow-x: hidden;
    overscroll-behavior-x: none;
    touch-action: pan-y;
  }
}

/* Narrowest phones: smaller XP / pieces rings and no chevron (the whole card
   is the button), so Mastery fits without clipping. */
@media (max-width: 380px) {
  #dashboard .mastery-dash-mini-ring,
  #dashboard .mastery-dash-mini-ring svg {
    width: 52px;
    height: 52px;
  }
  #dashboard .mastery-dash-rings {
    gap: 6px;
  }
  #dashboard .mastery-dash-chevron {
    display: none;
  }
  #dashboard .mastery-dash-badge {
    width: 44px;
    height: 44px;
  }
  #dashboard .mastery-dash-card .mastery-dash-name {
    font-size: 20px;
  }
}
