/* ========================================
   PianoNova — homepage (index.html) only
   Loads AFTER core.css. Section mechanics that exist nowhere else:
   hero, songs rail, beta strip, scroll progress, and the per-section
   moods for the ambient orbs (the orbs themselves live in core.css).
   Anything reusable belongs in core.css instead.
   ======================================== */

/* Section moods (body[data-active] set by the scroll spy) */
body[data-active='pains'] .bg-fx__frame--1 {
  opacity: 0.35;
  transform: translate3d(-5%, 5%, 0) scale(0.85);
}

body[data-active='pains'] .bg-fx__frame--2 {
  opacity: 0.3;
  transform: translate3d(0, 8%, 0) scale(0.8);
}

body[data-active='pains'] .bg-fx__frame--3 {
  opacity: 0.5;
  transform: translate3d(0, -4%, 0);
}

body[data-active='product'] .bg-fx__frame--1 {
  opacity: 1;
  transform: translate3d(14%, 10%, 0) scale(1.15);
}

body[data-active='product'] .bg-fx__frame--2 {
  opacity: 0.9;
  transform: translate3d(-6%, -6%, 0) scale(1.1);
}

body[data-active='product'] .bg-fx__frame--3 {
  opacity: 0.7;
}

body[data-active='features'] .bg-fx__frame--1 {
  opacity: 0.75;
  transform: translate3d(0, 0, 0) scale(1);
}

body[data-active='features'] .bg-fx__frame--2 {
  opacity: 0.7;
  transform: translate3d(-4%, 4%, 0);
}

body[data-active='progress'] .bg-fx__frame--1 {
  opacity: 0.55;
  transform: translate3d(6%, -6%, 0) scale(0.9);
}

body[data-active='progress'] .bg-fx__frame--3 {
  opacity: 0.85;
  transform: translate3d(-6%, 2%, 0) scale(1.05);
}

body[data-active='songs'] .bg-fx__frame--2 {
  opacity: 1;
  transform: translate3d(-10%, -8%, 0) scale(1.2);
}

body[data-active='songs'] .bg-fx__frame--3 {
  opacity: 0.9;
  transform: translate3d(4%, -8%, 0);
}

body[data-active='pricing'] .bg-fx__frame--1 {
  opacity: 0.9;
  transform: translate3d(18%, 14%, 0) scale(1.1);
}

body[data-active='pricing'] .bg-fx__frame--2 {
  opacity: 0.85;
  transform: translate3d(-12%, 2%, 0) scale(1.05);
}

body[data-active='faq'] .bg-fx__frame--1 {
  opacity: 0.45;
}

body[data-active='faq'] .bg-fx__frame--2 {
  opacity: 0.4;
}

body[data-active='faq'] .bg-fx__frame--3 {
  opacity: 0.4;
}

body[data-active='cta'] .bg-fx__frame--1 {
  opacity: 0.3;
}

body[data-active='cta'] .bg-fx__frame--2 {
  opacity: 0.3;
}

body[data-active='cta'] .bg-fx__frame--3 {
  opacity: 0.3;
}

/* --- Scroll progress hairline --- */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 1001;
  background: linear-gradient(90deg, var(--gold-deep), var(--gold-light));
  transform: scaleX(0);
  transform-origin: left;
}

/* --- Hero --- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 150px 0 100px;
}

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  will-change: transform;
}

/* Overscaled so the scroll parallax on .hero__bg never exposes an edge.
   A Ken Burns zoom used to sit on the image too; it read as the hero slowly
   creeping in and never settling, because `ease-in-out` over 44s makes the
   return leg imperceptible. Ambient motion that gets noticed has failed. */
.hero__bg-pic {
  display: block;
  height: 100%;
  transform: scale(1.06);
}

.hero__bg-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 40%;
  filter: brightness(0.36) saturate(0.85);
}

/* Slow-drifting gold light — keeps the hero alive even when idle */
.hero__glow {
  position: absolute;
  inset: -20%;
  z-index: 1;
  background: radial-gradient(42% 38% at 58% 44%, rgba(201, 169, 98, 0.14), transparent 70%);
  animation: glowDrift 26s ease-in-out infinite alternate;
  will-change: transform;
  pointer-events: none;
}

.hero__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(10, 10, 8, 0.72) 0%,
    rgba(10, 10, 8, 0.25) 26%,
    rgba(10, 10, 8, 0.38) 62%,
    var(--bg) 100%
  );
}

/* --sy/--so set from scroll */
.hero__content {
  position: relative;
  z-index: 2;
  text-align: center;
  max-width: 880px;
  padding: 0 var(--container-x);
  transform: translate3d(0, calc(var(--sy, 0) * 1px), 0);
  opacity: var(--so, 1);
  will-change: transform;
}

.hero__badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 18px;
  border-radius: 999px;
  border: 1px solid rgba(201, 169, 98, 0.3);
  background: rgba(18, 16, 11, 0.45);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-light);
  margin-bottom: 26px;
  animation: heroIn 0.9s var(--ease-out) 0.15s both;
}

.hero__badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gold-light);
  animation: pulse 2.2s ease-out infinite;
}

.hero__title {
  font-family: var(--font-display);
  font-size: clamp(2.9rem, 7vw, 5.4rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--text);
  margin-bottom: 22px;
  text-wrap: balance;
}

/* Masked line reveal: each line slides up from behind an overflow clip */
.hero-line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.1em;
  margin-bottom: -0.1em;
}

.hero-line > span {
  display: inline-block;
  transform: translateY(112%);
  animation: lineUp 1s var(--ease-out) 0.3s forwards;
}

.hero-line:nth-child(2) > span {
  animation-delay: 0.48s;
}

.hero__title--accent {
  font-style: italic;
  color: var(--gold);
}

@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .hero__title--accent {
    background: linear-gradient(100deg, #e9cf8f 0%, #c9a962 45%, #a8843f 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
}

.hero__subtitle {
  font-size: clamp(1.05rem, 1.7vw, 1.22rem);
  color: rgba(246, 242, 233, 0.85);
  max-width: 600px;
  margin: 0 auto 30px;
  animation: heroIn 0.9s var(--ease-out) 0.45s both;
}

.hero__ctas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 18px;
  animation: heroIn 0.9s var(--ease-out) 0.58s both;
}

.hero__try {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 54px;
  padding: 0 28px;
  border: 1.5px solid rgba(245, 240, 232, 0.22);
  border-radius: var(--r-md);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition:
    border-color 0.25s var(--ease),
    color 0.25s var(--ease),
    background 0.25s var(--ease),
    transform 0.25s var(--ease);
}

.hero__try .icon {
  color: var(--gold);
  font-size: 15px;
}

.hero__try:hover {
  border-color: rgba(201, 169, 98, 0.6);
  color: var(--gold-light);
  background: var(--gold-glow);
  transform: translateY(-2px);
}

.hero__fine {
  font-size: 0.8rem;
  color: var(--text-3);
  animation: heroIn 0.9s var(--ease-out) 0.68s both;
}

.hero__points {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 12px 26px;
  margin-top: 36px;
  padding-top: 28px;
  border-top: 1px solid rgba(245, 240, 232, 0.09);
  animation: heroIn 0.9s var(--ease-out) 0.78s both;
}

.hero__points li {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--text-2);
}

.hero__points .icon,
.hero__points svg {
  color: var(--gold);
  font-size: 16px;
}

.hero__scroll {
  position: absolute;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1;
  color: var(--text-3);
  font-size: 1.05rem;
  padding: 8px;
  transition: color 0.25s var(--ease);
  animation: bounceY 2s ease infinite;
}

.hero__scroll:hover {
  color: var(--gold);
}

/* --- Pains --- */
.pains {
  padding: calc(var(--section-y) * 0.7) 0;
}

.product__wrap {
  position: relative;
  border-radius: 26px;
  padding: 1px;
  background: linear-gradient(
    160deg,
    rgba(201, 169, 98, 0.5),
    rgba(201, 169, 98, 0.07) 35%,
    rgba(245, 240, 232, 0.06) 70%,
    rgba(201, 169, 98, 0.18)
  );
  box-shadow:
    0 40px 110px -30px rgba(201, 169, 98, 0.18),
    0 30px 80px rgba(0, 0, 0, 0.45);
}

@media (max-width: 767px) {
  .product__wrap {
    border-radius: 20px;
  }
}

.product__step-card {
  position: relative;
  padding: 26px 26px 24px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  transition:
    transform 0.4s var(--ease),
    border-color 0.4s var(--ease),
    box-shadow 0.4s var(--ease);
}

.product__step-card:hover {
  transform: translateY(-3px);
  border-color: rgba(201, 169, 98, 0.28);
  box-shadow: 0 20px 50px -18px rgba(0, 0, 0, 0.5);
}

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

.product__step-head .icon {
  color: var(--gold);
  font-size: 18px;
}

.product__step-card h3 {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
  margin-bottom: 6px;
}

.product__step-card p {
  font-size: 0.88rem;
  line-height: 1.6;
  color: var(--text-3);
}

/* --- Features --- */
.features {
  padding: var(--section-y) 0;
}

.beta {
  margin-top: clamp(36px, 4vw, 52px);
  padding: clamp(26px, 3vw, 36px);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--surface);
}

.beta__founder {
  font-size: 0.94rem;
  line-height: 1.6;
  color: var(--text-2);
  padding-bottom: 22px;
  margin-bottom: 22px;
  border-bottom: 1px solid var(--line);
}

.beta__list {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
}

.beta__item {
  position: relative;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--text-2);
}

.beta__item:not(:first-child)::before {
  content: '';
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: -17px;
  width: 1px;
  background: var(--line-strong);
}

.beta__label {
  display: block;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 8px;
}

.beta__item p {
  margin: 0;
}

@media (max-width: 767px) {
  .beta__list {
    grid-template-columns: 1fr;
    gap: 20px;
  }

  .beta__item:not(:first-child)::before {
    content: none;
  }
}

/* --- Popular Songs --- */
.popular {
  padding: var(--section-y) 0;
}

.rail__head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: clamp(32px, 4vw, 48px);
}

.rail__head-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}

.rail__nav {
  display: flex;
  gap: 8px;
}

.rail__nav-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: var(--r-sm);
  border: 1.5px solid var(--line-strong);
  background: rgba(245, 240, 232, 0.02);
  color: var(--text);
  cursor: pointer;
  transition:
    border-color 0.25s var(--ease),
    background 0.25s var(--ease),
    color 0.25s var(--ease);
}

.rail__nav-btn .icon {
  font-size: 15px;
}

.rail__nav-btn--prev .icon {
  transform: scaleX(-1);
}

.rail__nav-btn:hover:not(:disabled) {
  border-color: rgba(201, 169, 98, 0.55);
  color: var(--gold-light);
  background: var(--gold-glow);
}

.rail__nav-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.rail {
  /* Line the first card up with .container's content edge at any width
     (.container is centered + max-width, so its edge drifts past 1200px). */
  --rail-x: max(var(--container-x), calc((100% - var(--container-max)) / 2 + var(--container-x)));
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  padding-inline: var(--rail-x);
  /* Without this, Chrome auto-scrolls past the entire start padding on load
     to snap the first card flush to the edge, defeating the alignment above. */
  scroll-padding-inline-start: var(--rail-x);
  padding-block: 8px;
}

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

.rail--draggable {
  cursor: grab;
}

.rail--dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
}

.rail__track {
  list-style: none;
  display: flex;
  gap: 16px;
  width: max-content;
}

.rail__track > li {
  scroll-snap-align: start;
  width: clamp(230px, 26vw, 300px);
  display: flex;
}

.rail__track .popular__card {
  width: 100%;
}

/* Keyboard users scroll the rail by focusing a card — make that focus visible
   and let the browser bring the card into view. */
.rail__track .popular__card:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

.popular__card {
  display: flex;
  flex-direction: column;
  position: relative;
  padding: 26px 26px 24px;
  border-radius: var(--r-lg);
  border: 1px solid var(--line);
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  transition:
    transform 0.4s var(--ease),
    border-color 0.4s var(--ease),
    box-shadow 0.4s var(--ease);
}

.popular__card:hover {
  transform: translateY(-4px);
  border-color: rgba(201, 169, 98, 0.3);
  box-shadow: 0 20px 50px -18px rgba(0, 0, 0, 0.5);
}

.popular__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 20px;
}

.popular__difficulty {
  font-size: 0.66rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--gold-light);
  background: var(--gold-glow);
  border: 1px solid rgba(201, 169, 98, 0.25);
  padding: 4px 11px;
  border-radius: 100px;
  white-space: nowrap;
}

.popular__arrow {
  color: var(--gold);
  font-size: 16px;
  opacity: 0;
  transform: translateX(-6px);
  transition:
    opacity 0.3s var(--ease),
    transform 0.3s var(--ease);
}

.popular__card:hover .popular__arrow {
  opacity: 1;
  transform: translateX(0);
}

.popular__card h3 {
  font-family: var(--font-display);
  font-size: 1.28rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--text);
  line-height: 1.3;
  margin-bottom: 5px;
}

.popular__composer {
  font-size: 0.86rem;
  color: var(--text-3);
}

/* --- Cursor spotlight (pointer effects set --mx/--my from script.js) --- */
.popular__card::before,
.product__step-card::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(
    340px circle at var(--mx, 50%) var(--my, 50%),
    rgba(201, 169, 98, 0.12),
    transparent 65%
  );
  opacity: 0;
  transition: opacity 0.45s var(--ease);
  pointer-events: none;
}

.popular__card:hover::before,
.product__step-card:hover::before {
  opacity: 1;
}

/* --- Animated gold border on the Yearly card (added when @property works) --- */
.pn-spin-ok .pricing-card--gold {
  background:
    linear-gradient(180deg, var(--surface-3), var(--surface-2)) padding-box,
    conic-gradient(
        from var(--pn-angle, 160deg) at 50% 50%,
        rgba(223, 194, 131, 0.95),
        rgba(201, 169, 98, 0.12) 30%,
        rgba(223, 194, 131, 0.55) 52%,
        rgba(201, 169, 98, 0.1) 74%,
        rgba(223, 194, 131, 0.95)
      )
      border-box;
  animation: pn-border-spin 6s linear infinite;
}

/* --- Reduced motion: everything dynamic goes still --- */
@media (prefers-reduced-motion: reduce) {
  .hero__badge,
  .hero__subtitle,
  .hero__ctas,
  .hero__fine,
  .hero__points,
  .hero__scroll,
  .hero__badge-dot,
  .hero__glow,
  .hero-line > span,
  .pn-spin-ok .pricing-card--gold,
  .popular__card::before,
  .product__step-card::before {
    animation: none !important;
    transition: none !important;
  }

  .hero-line > span {
    transform: none;
  }
}

@media (max-width: 480px) {
  .hero {
    padding: 130px 0 90px;
  }

  .hero__title {
    font-size: 2.7rem;
  }

  .hero__ctas {
    flex-direction: column;
    align-items: stretch;
  }

  .hero__ctas .btn,
  .hero__try {
    width: 100%;
    justify-content: center;
  }
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(223, 194, 131, 0.45);
  }
  70% {
    box-shadow: 0 0 0 9px rgba(223, 194, 131, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(223, 194, 131, 0);
  }
}

@keyframes lineUp {
  to {
    transform: translateY(0);
  }
}

@keyframes bounceY {
  0%,
  100% {
    transform: translateX(-50%) translateY(0);
  }
  50% {
    transform: translateX(-50%) translateY(8px);
  }
}

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

@keyframes pn-border-spin {
  to {
    --pn-angle: 520deg;
  }
}

/* --- Progress ledger ---------------------------------------------------
   Three rows on one gold spine. The spine is the point: these are not three
   features, they are one record read at three time scales — a run, a piece, a
   week — so the device that separates them has to be an axis, not a rule.
   Horizontal hairlines would also be `.spec__item`'s device, and features is
   the section immediately above this one. */

.progress {
  padding: var(--section-y) 0;
}

.ledger__head {
  max-width: 44rem;
  margin-bottom: clamp(44px, 5.5vw, 72px);
}

.ledger__title {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.4vw, 2.8rem);
  font-weight: 600;
  line-height: 1.14;
  letter-spacing: -0.02em;
  color: var(--text);
  text-wrap: balance;
}

.ledger__lead {
  margin-top: 20px;
  max-width: 40rem;
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--text-2);
}

.ledger {
  --spine: 3px;
  position: relative;
  display: grid;
  gap: clamp(42px, 5vw, 66px);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Fades at both ends so the axis reads as a stretch of time rather than a
   ruled box with a start and a stop. */
.ledger::before {
  content: '';
  position: absolute;
  left: var(--spine);
  top: 0.5em;
  bottom: 0.9em;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--seam) 10%, var(--seam) 82%, transparent);
}

.ledger__row {
  position: relative;
  padding-left: 26px;
}

.ledger__row::before {
  content: '';
  position: absolute;
  left: calc(var(--spine) - 3px);
  top: 0.5em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--gold);
  /* The ring is the page background, so the node punches through the spine
     instead of sitting on top of it. */
  box-shadow:
    0 0 0 4px var(--bg),
    0 0 12px var(--gold-glow);
}

.ledger__scale {
  display: block;
  margin-bottom: 10px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-3);
}

.ledger__body h3 {
  font-family: var(--font-display);
  font-size: clamp(1.24rem, 1.9vw, 1.5rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--text);
}

.ledger__body p {
  margin-top: 12px;
  max-width: 34rem;
  font-size: 0.97rem;
  line-height: 1.72;
  color: var(--text-2);
}

/* The cut-out. Each artifact sits on a lifted plate so it reads as a piece of
   the app lifted onto the page, not a diagram drawn about it — which is what
   the bare accuracy figure failed to do.
   A plate, deliberately not a card: an outline plus a radius is `.beta`'s and
   `.pricing-card`'s device, and this page's whole problem once was every
   section resolving into bordered cards. Lift by surface and shadow instead,
   and use the same plate all three times so the shade itself means "this is
   the product". */
.ledger__art {
  margin-top: clamp(22px, 2.6vw, 30px);
  max-width: 34rem;
  padding: clamp(18px, 2vw, 24px);
  border-radius: var(--r-md);
  background: var(--surface-2);
  box-shadow:
    inset 0 1px 0 rgba(245, 240, 232, 0.045),
    0 14px 34px -20px rgba(0, 0, 0, 0.9);
}

.ledger__art > :last-child {
  margin-bottom: 0;
}

.ledger__stat {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin: 0 0 18px;
}

/* The word sits to the LEFT of the figure at body size. Set as a unit beside
   the number it was too small to read — a figure this large needs a label in
   plain type, not a shrunken suffix. */
.ledger__stat-label {
  font-family: var(--font-body);
  font-size: 0.92rem;
  color: var(--text-2);
}

.ledger__figure {
  font-family: var(--font-display);
  /* Deliberately smaller than a hero figure. The mastery bar one row down is
     the section's one loud thing, and the figure now has a label beside it
     doing the naming — so it only has to read as a number, not carry the row. */
  font-size: clamp(1.55rem, 2.4vw, 1.95rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--gold);
}

/* Inside .ledger__figure, not a sibling of it: as a flex child of .ledger__stat
   the percent sign took the flex gap and floated a dozen pixels off its own
   number. */
.ledger__unit {
  font-size: 0.5em;
  letter-spacing: 0;
}

.ledger__delta {
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-3);
  margin-left: 6px;
}

.ledger__delta::before {
  content: '▲ ';
  color: var(--gold);
  font-size: 0.72em;
}

/* The run tape: one cell per bar, mirrored about a centre rule — right hand
   rises, left hand falls, in the two colours the player has been watching on
   the keys all session. Mirrored on purpose: it is the one artifact here that
   must not read as another version of the mastery bar below it. */
.ledger__tape {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 3px;
  height: 46px;
}

.ledger__tape::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: var(--line-strong);
}

.ledger__hands {
  flex: 0 0 15px;
  display: grid;
  grid-template-rows: 1fr 1px 1fr;
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-3);
}

.ledger__hands b:first-child {
  align-self: center;
}

.ledger__hands b:last-child {
  grid-row: 3;
  align-self: center;
}

/* The empty slot behind the lanes. Without it a bar that lost most of its notes
   renders as a hole in the strip — the ringed bars read as missing rather than
   as bars you got a third of. Same reason the result screen has a track. */
.ledger__take {
  flex: 1 1 0;
  display: grid;
  grid-template-rows: 1fr 1px 1fr;
  border-radius: 3px;
  background: rgba(245, 240, 232, 0.06);
}

.ledger__take::before {
  content: '';
  align-self: end;
  height: var(--r);
  border-radius: 2px 2px 0 0;
  background: #9db9e6;
}

.ledger__take::after {
  content: '';
  grid-row: 3;
  align-self: start;
  height: var(--l);
  border-radius: 0 0 2px 2px;
  background: #f2b281;
}

/* A ring, not a fill: the bar still has to show how much of it you did get, so
   the mark goes around the cell instead of over it. Gold, matching the ring the
   result screen pencils around the same bars — these are the bars worth going
   back to, and the player never colours them as failures. */
.ledger__take[data-worst] {
  outline: 1.5px solid var(--gold);
  outline-offset: 2px;
  border-radius: 4px;
}

.ledger__note {
  margin-top: 12px;
  font-size: 0.88rem;
  color: var(--text-3);
}

/* The week's one achievement, so it carries the accent while the tallies beside
   it stay quiet — same split the app's week register makes. */
.ledger__met {
  color: var(--gold);
  font-weight: 600;
}

/* The mastery bar: one cell per bar of music, height carrying how well it is
   known — the app's own instrument, same three-state alphabet. */
.ledger__bar {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 30px;
  clip-path: inset(0 0 0 0);
}

.ledger__cell {
  flex: 1 1 0;
  border-radius: 2px 2px 0 0;
  background: rgba(245, 240, 232, 0.09);
  height: 24%;
}

.ledger__cell[data-state='-'] {
  background: rgba(245, 240, 232, 0.04);
}

.ledger__cell[data-state='1'] {
  height: 56%;
  background: rgba(201, 169, 98, 0.42);
}

.ledger__cell[data-state='2'] {
  height: 100%;
  background: linear-gradient(180deg, var(--gold-light), var(--gold-deep));
}

/* The one flourish on the page's second half: the bar draws itself in when the
   row arrives, left to right, the way a piece is actually learned. Riding the
   existing .reveal observer, so no new scroll handler. */
.reveal .ledger__bar {
  clip-path: inset(0 100% 0 0);
}

.reveal--visible .ledger__bar {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1.5s 0.3s var(--ease-out);
}

.ledger__key {
  display: flex;
  flex-wrap: wrap;
  gap: 9px 22px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.83rem;
  color: var(--text-3);
}

.ledger__key li {
  display: flex;
  align-items: center;
  gap: 9px;
}

/* Reuses .ledger__cell so a swatch can never drift from the bar it explains. */
.ledger__swatch {
  display: flex;
  align-items: flex-end;
  width: 9px;
  height: 16px;
}

.ledger__swatch .ledger__cell {
  flex: 1 1 auto;
}

.ledger__week {
  display: flex;
  gap: 7px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ledger__day {
  width: 30px;
  text-align: center;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  color: var(--text-3);
}

.ledger__day::before {
  content: '';
  display: block;
  height: 24px;
  margin-bottom: 8px;
  border-radius: 5px;
  background: rgba(245, 240, 232, 0.08);
}

.ledger__day[data-on]::before {
  background: linear-gradient(180deg, var(--gold-light), var(--gold-deep));
}

@media (min-width: 880px) {
  .ledger {
    --spine: 148px;
  }

  .ledger__row {
    display: grid;
    grid-template-columns: 148px 1fr;
    gap: 34px;
    padding-left: 0;
    align-items: start;
  }

  /* Right-aligned so the label sits against the spine rather than floating a
     hundred pixels off it — the axis is what the label is labelling. */
  .ledger__scale {
    margin: 0;
    padding: 0.36em 26px 0 0;
    text-align: right;
  }
}

@media (prefers-reduced-motion: reduce) {
  .reveal .ledger__bar,
  .reveal--visible .ledger__bar {
    clip-path: none;
    transition: none;
  }
}
