/*
  Bell Composer styles.
  Do not change CSS except in the specified section.
*/

    :root {
      --tile-size: 106px;
      --gap: 10px;
      /* The bell dock sizes itself from the VIEWPORT, not from a constant.
         The chromatic piano is 15 white keys wide, and at the old fixed 96px
         that meant ~1660px of dock on a 1024px screen: two thirds of the
         bells simply off-screen (Andrea's report). The bell size is now
         whatever lets all 15 whites fit, capped at the old size on wide
         monitors, and the dock height follows the bell size (whites row +
         the raised black-key row + labels) instead of claiming 34vh. */
      --bank-note-size: clamp(44px, calc((100vw - 88px) / 15 - 17px), 96px);
      --bank-note-gap: 8px;
      --dock-height: calc(var(--bank-note-size) * 2.05 + 58px);
      --bg1: #f5fbff;
      --bg2: #fff8ee;
      --ink: #1f2b46;
      --soft-ink: #5f6b89;
      --panel: #ffffff;
      --panel-border: #e4edff;
      --teal: #009999;
      --teal-dark: #007777;
      --red: #ff5b5b;
      --red-dark: #d34545;
    }

    * { box-sizing: border-box; }
    [hidden] { display: none !important; }

    body {
      margin: 0;
      min-height: 100vh;
      font-family: "Nunito", "Avenir Next Rounded", "Trebuchet MS", "Verdana", sans-serif;
      color: var(--ink);
      background:
        radial-gradient(1200px 600px at 10% -10%, #dff3ff 0%, transparent 45%),
        radial-gradient(1000px 600px at 95% 0%, #fff0d8 0%, transparent 40%),
        linear-gradient(180deg, var(--bg1), var(--bg2));
      padding: 12px;
    }

    body.bell-composer-page .shopify-section-group-header-group,
    body.bell-composer-page #shopify-section-header,
    body.bell-composer-page [id*="shopify-section"][id*="header"],
    body.bell-composer-page .shopify-section-group-footer-group,
    body.bell-composer-page #shopify-section-footer,
    body.bell-composer-page [id*="shopify-section"][id*="footer"],
    body.bell-composer-page [id*="shopify-section"][id*="announcement"] {
      display: none !important;
    }

    body.bell-composer-page #MainContent,
    body.bell-composer-page main#MainContent {
      margin-top: 0 !important;
      padding-top: 0 !important;
      padding-bottom: 0 !important;
    }

    .app {
      width: min(1020px, 100%);
      margin: 0 auto;
      background: var(--panel);
      border: 2px solid var(--panel-border);
      border-radius: 28px;
      box-shadow:
        0 20px 45px rgba(26, 49, 99, 0.12),
        0 4px 10px rgba(26, 49, 99, 0.06);
      overflow: hidden;
      position: relative;
    }

    .screen {
      padding: 20px 14px 24px;
      position: relative;
    }

    #gameScreen {
      padding-bottom: calc(var(--dock-height) + env(safe-area-inset-bottom) + 26px);
    }

    .boot-loader {
      position: absolute;
      inset: 0;
      z-index: 120;
      display: grid;
      place-items: center;
      gap: 10px;
      background: rgba(249, 252, 255, 0.9);
      backdrop-filter: blur(1px);
      transition: opacity 0.18s ease;
    }

    .boot-loader[hidden] {
      display: none;
    }

    .boot-loader.done {
      opacity: 0;
    }

    .boot-loader-dot {
      width: 22px;
      height: 22px;
      border-radius: 50%;
      border: 3px solid #c8d7f6;
      border-top-color: #009999;
      animation: bootSpin 0.82s linear infinite;
    }

    .boot-loader-text {
      margin: 0;
      font-size: 0.88rem;
      font-weight: 800;
      color: #446196;
      letter-spacing: 0.01em;
    }

    @keyframes bootSpin {
      to { transform: rotate(360deg); }
    }

    button {
      border: 0;
      border-radius: 16px;
      padding: 12px 18px;
      font-size: 1.03rem;
      font-weight: 800;
      cursor: pointer;
      color: #fff;
      transition: transform 0.14s ease, filter 0.14s ease;
    }

    button:active {
      transform: translateY(2px);
      filter: brightness(0.98);
    }

    .teal-btn {
      background: var(--teal);
      box-shadow: 0 8px 0 var(--teal-dark), 0 12px 24px rgba(0, 122, 122, 0.28);
    }

    .red-btn {
      background: var(--red);
      box-shadow: 0 8px 0 var(--red-dark), 0 12px 24px rgba(211, 69, 69, 0.26);
    }

    .play-btn {
      min-width: 190px;
      min-height: 72px;
      font-size: 1.35rem;
    }

    .progress {
      margin: 8px 0 12px;
      text-align: center;
      font-size: 0.98rem;
      font-weight: 800;
      color: #4f6498;
    }

    /* ── Song name row ─────────────────────────────────────── */
    .composer-row {
      display: flex;
      justify-content: center;
      width: 100%;
      margin: 0 0 10px;
    }

    .composer-input {
      width: min(520px, 80vw);
      height: 38px;
      border-radius: 10px;
      border: 2px solid #e1ebff;
      padding: 0 12px;
      text-align: center;
      font-family: "Nunito", sans-serif;
      font-size: clamp(0.9rem, 2.3vw, 1.1rem);
      font-weight: 900;
      color: #17366a;
      background: #fff;
    }

    .composer-input:focus {
      outline: 3px solid rgba(0, 153, 153, 0.18);
      border-color: #8fd9d9;
    }

    /* ── Saved panel ────────────────────────────────────────── */
    .saved-panel {
      position: absolute;
      right: 0;
      top: calc(100% + 8px);
      width: min(480px, calc(100vw - 44px));
      max-height: min(56vh, 430px);
      overflow: auto;
      border: 2px solid #d9e5ff;
      border-radius: 14px;
      background: #ffffff;
      padding: 10px;
      box-shadow: 0 16px 30px rgba(29, 47, 89, 0.2);
      z-index: 32;
    }

    /* ── Settings dropdown panel ────────────────────────────── */
    .settings-panel {
      position: absolute;
      right: 0;
      top: calc(100% + 8px);
      width: min(560px, calc(100vw - 44px));
      z-index: 34;
    }

    .composer-menu-panel .settings {
      margin-bottom: 0;
    }

    .settings {
      width: 100%;
      margin: 0;
      padding: 7px 9px;
      border-radius: 12px;
      border: 2px solid #e2ecff;
      background: linear-gradient(180deg, #f8fbff, #f1f7ff);
      box-shadow: 0 16px 30px rgba(29, 47, 89, 0.16);
      display: grid;
      gap: 6px;
    }

    .setting-row {
      display: grid;
      grid-template-columns: minmax(88px, 118px) 1fr minmax(42px, 50px);
      align-items: center;
      gap: 8px;
    }

    .setting-row-modes {
      grid-template-columns: minmax(88px, 118px) 1fr;
    }

    .setting-label {
      font-weight: 900;
      color: #2a4478;
      font-size: 0.81rem;
    }

    .setting-value {
      text-align: center;
      font-weight: 900;
      color: #0f4474;
      background: #ffffff;
      border: 2px solid #d8e6ff;
      border-radius: 999px;
      padding: 1px 4px;
      font-size: 0.74rem;
    }

    .settings input[type="range"] {
      width: 100%;
      accent-color: var(--teal);
    }

    .mode-toggle {
      display: flex;
      gap: 6px;
    }

    .countin-toggle .mode-btn {
      min-width: 58px;
      padding-inline: 8px;
    }

    .mode-groups {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      align-items: center;
    }

    .mode-group {
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .mode-group-label {
      font-size: 0.78rem;
      font-weight: 900;
      color: #2a4478;
      min-width: 52px;
    }

    .mode-groups > .mode-group:first-child {
      gap: 4px;
    }

    .mode-groups > .mode-group:first-child .mode-group-label {
      min-width: 40px;
    }

    #noteNamesGroup {
      margin-left: 8px;
    }

    .mode-btn {
      color: #23416e;
      background: #f2f6ff;
      border: 2px solid #d3e1ff;
      box-shadow: none;
      min-height: 30px;
      min-width: 72px;
      padding: 5px 9px;
      font-size: 0.76rem;
    }

    .mode-btn.active {
      color: #fff;
      background: var(--teal);
      border-color: var(--teal-dark);
      box-shadow: 0 4px 0 var(--teal-dark);
    }

    .instruction {
      margin: 0 0 12px;
      text-align: center;
      font-size: clamp(1.02rem, 2.8vw, 1.2rem);
      font-weight: 900;
      color: #203869;
    }

    .runtime-meta {
      display: none;
    }

    /* ── Help sits BELOW the chrome row, not under it ──────────────────────
       game-chrome.js owns the top band on every game: `.pgc-root` is
       `position: fixed; top: 0` at z-index 2147482500, and the coin purse rides
       in it. This button was `absolute; right: 14px; top: 12px; z-index: 22`,
       which put it squarely underneath the purse — and losing a z-index fight
       against 2147482500 meant `elementFromPoint` at its own centre returned
       `.cp-purse`. Help was completely unclickable, and NOT only on a phone:
       measured dead at 393x852, 852x393, iPad both ways and 1440x900.

       Sliding it sideways is not a fix. The purse grows LEFTWARD as the balance
       gains digits (see coin-purse.js), so any horizontal offset that clears a
       3-coin balance is wrong at 5 figures — the same trap that once made the
       mute button unclickable.

       So: fixed to the viewport, below the band. The chrome row measures 58px
       tall (10px pad + a 44px purse) and both it and this offset grow with
       `env(safe-area-inset-top)` together, so the clearance holds on a notched
       phone as well as in a desktop window. */
    .help-ui {
      position: fixed;
      right: calc(12px + env(safe-area-inset-right));
      top: calc(66px + env(safe-area-inset-top));
      z-index: 22;
    }

    .help-btn {
      width: 30px;
      height: 30px;
      border-radius: 50%;
      border: 2px solid #d6e5ff;
      background: #fff;
      color: #3b5e99;
      font-size: 1rem;
      font-weight: 900;
      padding: 0;
      line-height: 1;
      box-shadow: 0 2px 7px rgba(30, 53, 108, 0.14);
    }

    .help-popover {
      position: absolute;
      right: 0;
      top: 42px;
      width: min(290px, 86vw);
      border-radius: 12px;
      border: 2px solid #d8e7ff;
      background: #fff;
      color: #314f85;
      padding: 10px 12px;
      font-size: 0.86rem;
      font-weight: 700;
      line-height: 1.35;
      box-shadow: 0 12px 22px rgba(31, 54, 103, 0.16);
      opacity: 0;
      pointer-events: none;
      transform: translateY(-5px);
      transition: opacity 0.16s ease, transform 0.16s ease;
    }

    .help-ui.open .help-popover,
    .help-ui:hover .help-popover {
      opacity: 1;
      pointer-events: auto;
      transform: translateY(0);
    }

    .message {
      min-height: 34px;
      margin: 4px 0 8px;
      text-align: center;
      font-size: 1rem;
      font-weight: 800;
      color: #1d7b45;
      opacity: 0;
      transform: translateY(-4px);
      transition: opacity 0.2s ease, transform 0.2s ease;
    }

    .message.show {
      opacity: 1;
      transform: translateY(0);
    }

    .slots-wrap {
      overflow-x: auto;
      -webkit-overflow-scrolling: touch;
      padding: 18px 2px 10px;
      position: relative;
    }

    .slots-grid {
      width: max-content;
      margin: 0 auto;
      display: grid;
      grid-template-columns: repeat(8, var(--tile-size));
      gap: var(--gap);
      padding: 2px;
    }

    .slot.measure-start {
      margin-left: 0;
    }

    .slot {
      width: var(--tile-size);
      height: var(--tile-size);
      border-radius: 20px;
      border: 3px dashed #cfd9f6;
      background: linear-gradient(180deg, #f8fbff, #eef4ff);
      display: grid;
      place-items: center;
      position: relative;
      box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.85);
      overflow: hidden;
    }

    .slot.filled {
      border-style: solid;
      border-color: #bfd0ff;
      background: linear-gradient(180deg, #edf4ff, #e6f0ff);
    }

    .slot.sustain-start {
      border-style: solid;
      border-color: var(--hold-color, #8fa3d8);
      background: linear-gradient(180deg, #edf4ff, #e6f0ff);
    }

    .slot.sustain-tail {
      border-style: solid;
      border-color: #bfd0ff;
      background: linear-gradient(180deg, #edf4ff, #e6f0ff);
    }

    .slot-hold-fill {
      position: absolute;
      inset: 9px 5px 7px 5px;
      border-radius: 14px;
      background: linear-gradient(180deg, var(--hold-color, #8fa3d8), var(--hold-color, #8fa3d8));
      box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.4),
        0 1px 3px rgba(33, 43, 74, 0.12);
      z-index: 1;
      pointer-events: none;
    }

    .slot-hold-fill.hold-first-tail {
      border-top-left-radius: 10px;
      border-bottom-left-radius: 10px;
    }

    .slot-hold-fill.hold-last-tail {
      border-top-right-radius: 16px;
      border-bottom-right-radius: 16px;
    }

    .slot.measure-edge {
      box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.85);
    }

    .slot.playing {
      border-color: #009999;
      box-shadow:
        inset 0 2px 0 rgba(255, 255, 255, 0.9),
        0 0 0 5px rgba(0, 153, 153, 0.22);
    }

    .playhead {
      position: absolute;
      z-index: 15;
      width: 6px;
      height: 18px;
      border-radius: 999px;
      background: linear-gradient(180deg, rgba(0, 153, 153, 0.9), rgba(0, 153, 153, 0.35));
      box-shadow: 0 0 10px rgba(0, 153, 153, 0.3);
      transform: translateX(-50%);
      transition: left 0.09s linear, top 0.09s linear, opacity 0.12s ease;
      pointer-events: none;
    }

    .count-in-overlay {
      position: absolute;
      left: 50%;
      top: 4px;
      z-index: 18;
      width: fit-content;
      margin: 0;
      transform: translateX(-50%);
      padding: 4px 10px;
      border-radius: 999px;
      border: 2px solid #cde2ff;
      background: rgba(255, 255, 255, 0.94);
      color: #28518b;
      font-size: 0.82rem;
      font-weight: 900;
      letter-spacing: 0.01em;
      box-shadow: 0 4px 10px rgba(34, 61, 116, 0.12);
      pointer-events: none;
      white-space: nowrap;
    }

    .count-step {
      display: inline-block;
      min-width: 10px;
      text-align: center;
      color: #7c94c4;
      transition: color 0.1s ease, transform 0.1s ease;
    }

    .count-step.active {
      color: #009999;
      transform: translateY(-1px) scale(1.06);
    }

    .slot-num {
      position: absolute;
      right: 8px;
      top: 6px;
      z-index: 6;
      font-size: 0.72rem;
      font-weight: 900;
      color: #7f90bd;
      background: #ffffffd9;
      border-radius: 999px;
      padding: 2px 6px;
      line-height: 1;
    }

    .measure-num {
      position: absolute;
      font-size: 0.64rem;
      font-weight: 900;
      color: #a1adbf;
      line-height: 1;
      pointer-events: none;
      background: transparent;
    }

    .measure-overlays {
      position: absolute;
      left: 0;
      top: 0;
      pointer-events: none;
      z-index: 4;
    }

    .measure-line {
      position: absolute;
      width: 2px;
      border-radius: 999px;
      background: rgba(132, 140, 154, 0.62);
      pointer-events: none;
    }

    .slot-rest {
      font-size: 0.92rem;
      font-weight: 900;
      color: #9aa8cf;
    }

    .bank-dock {
      position: fixed;
      left: 50%;
      bottom: calc(8px + env(safe-area-inset-bottom));
      transform: translateX(-50%);
      width: min(1020px, calc(100vw - 24px));
      z-index: 70;
      pointer-events: none;
    }

    .bank-dock-inner {
      pointer-events: auto;
      border-radius: 0;
      border: 0;
      background: #dde3ea;
      box-shadow: 0 -8px 20px rgba(22, 39, 76, 0.08);
      padding: 8px 10px 10px;
    }

    .bank-title {
      display: none;
    }

    .bank-area {
      border-radius: 0;
      border: 0;
      background: transparent;
      padding: 2px 2px 2px;
      max-height: calc(var(--dock-height) - 8px);
      overflow-x: auto;
      overflow-y: hidden;
      -webkit-overflow-scrolling: touch;
    }

    .bank-grid {
      width: max-content;
      margin: 0 auto;
    }

    .bank-grid.bank-strip {
      display: flex;
      flex-wrap: nowrap;
      align-items: flex-end;
      gap: var(--bank-note-gap);
      padding: 2px 6px 0;
    }

    .bank-grid.c-major-strip {
      width: calc((9 * var(--bank-note-size)) + (8 * var(--bank-note-gap)) + 14px);
    }

    .bank-grid.chromatic-strip {
      width: max-content;
    }

    .bank-grid.chromatic-piano {
      width: max-content;
      padding: 10px 4px 4px;
    }

    .chromatic-piano-strip {
      position: relative;
      width: calc((var(--white-count) * var(--bank-note-size)) + ((var(--white-count) - 1) * var(--bank-note-gap)));
      padding-top: calc(var(--bank-note-size) * 0.72);
      overflow: visible;
    }

    .chromatic-white-row {
      display: flex;
      gap: var(--bank-note-gap);
      align-items: flex-end;
    }

    .chromatic-black-row {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: calc(var(--bank-note-size) * 0.86);
      pointer-events: none;
    }

    .chromatic-black-wrap {
      position: absolute;
      top: -10px;
      transform: translateX(-50%);
      pointer-events: auto;
      z-index: 4;
    }

    .chromatic-black-wrap .bank-note {
      width: calc(var(--bank-note-size) * 0.9);
      height: calc(var(--bank-note-size) * 1.18);
      min-width: calc(var(--bank-note-size) * 0.9);
      min-height: calc(var(--bank-note-size) * 1.18);
    }

    .toolbar {
      display: flex;
      justify-content: center;
      gap: 10px;
      flex-wrap: wrap;
      align-items: center;
    }

    .transport-toolbar {
      position: relative;
      margin-bottom: 6px;
    }

    .transport-manage-group {
      display: flex;
      align-items: center;
      gap: 8px;
      position: relative;
    }

    .transport-divider {
      color: #7f96bf;
      font-size: 1.05rem;
      font-weight: 900;
      line-height: 1;
      margin: 0 2px;
    }

    .sr-only {
      position: absolute;
      width: 1px;
      height: 1px;
      padding: 0;
      margin: -1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
      white-space: nowrap;
      border: 0;
    }

    .transport-btn {
      border: 0;
      padding: 0;
      display: grid;
      place-items: center;
      color: #fff;
    }

    .play-circle {
      width: 68px;
      height: 68px;
      border-radius: 50%;
      background: linear-gradient(180deg, #58d36f, #2fb352);
      box-shadow: 0 5px 0 #249244, 0 10px 20px rgba(40, 137, 66, 0.24);
    }

    .play-circle.micro-celebrate {
      animation: playCelebratePulse 760ms ease;
    }

    .play-circle.micro-celebrate-reduced {
      box-shadow: 0 0 0 6px rgba(87, 221, 127, 0.28);
      transition: box-shadow 0.25s ease;
    }

    @keyframes playCelebratePulse {
      0% { transform: scale(1); filter: brightness(1); }
      35% { transform: scale(1.08); filter: brightness(1.08); }
      100% { transform: scale(1); filter: brightness(1); }
    }

    .play-triangle {
      width: 0;
      height: 0;
      border-left: 18px solid #fff;
      border-top: 11px solid transparent;
      border-bottom: 11px solid transparent;
      margin-left: 4px;
    }

    .stop-octagon {
      width: 54px;
      height: 54px;
      min-width: 54px;
      min-height: 54px;
      clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
      background: linear-gradient(180deg, #ff6f6f, #e24f4f);
      box-shadow: 0 4px 0 #c73f3f, 0 8px 16px rgba(187, 64, 64, 0.22);
    }

    .stop-square {
      width: 16px;
      height: 16px;
      background: #fff;
      border-radius: 3px;
    }

    .tool-icon-btn {
      width: 44px;
      height: 44px;
      min-width: 44px;
      min-height: 44px;
      border-radius: 10px;
      padding: 0;
      background: #fff;
      border: 2px solid #d8e3f8;
      color: #4f6796;
      box-shadow: 0 3px 0 #c6d4f3, 0 5px 10px rgba(48, 74, 133, 0.11);
    }

    .tool-icon-btn svg {
      width: 19px;
      height: 19px;
      stroke: currentColor;
      stroke-width: 2.2;
      fill: none;
      stroke-linecap: round;
      stroke-linejoin: round;
    }

    .tool-icon-btn.clear-icon {
      border-color: #f3c2c2;
      color: #cf5858;
      box-shadow:
        0 3px 0 #e7b1b1,
        0 5px 10px rgba(183, 69, 69, 0.14);
    }

    .tool-icon-btn.save-icon {
      border-color: #95dfdf;
      color: #009999;
      box-shadow:
        0 3px 0 #7ac7c7,
        0 5px 10px rgba(0, 122, 122, 0.14);
    }

    .tool-icon-btn:disabled {
      opacity: 0.45;
      cursor: not-allowed;
      transform: none;
      filter: none;
    }

    .tool-icon-btn.active {
      background: #009999;
      color: #fff;
      border-color: #007d7d;
      box-shadow:
        0 4px 0 #006767,
        0 8px 16px rgba(0, 122, 122, 0.2);
    }

    .pattern-tools {
      margin-top: 12px;
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      gap: 8px;
    }

    .pattern-input {
      min-width: min(360px, 90vw);
      height: 46px;
      border-radius: 12px;
      border: 2px solid #d7e4ff;
      padding: 0 12px;
      font-size: 0.96rem;
      color: #1f2b46;
      background: #fff;
    }

    .pattern-input:focus {
      outline: 3px solid rgba(0, 153, 153, 0.18);
      border-color: #8fd9d9;
    }

    .saved-section {
      margin-top: 12px;
      border: 2px solid #e1ebff;
      border-radius: 16px;
      background: #f9fbff;
      padding: 10px;
    }

    .saved-title {
      margin: 0 0 8px;
      text-align: center;
      font-weight: 900;
      color: #39578e;
      font-size: 0.95rem;
    }

    .saved-list {
      display: grid;
      gap: 8px;
    }

    .saved-empty {
      text-align: center;
      color: #7b8db8;
      font-weight: 700;
      font-size: 0.9rem;
      padding: 8px 0;
    }

    .saved-item {
      border: 2px solid #dbe8ff;
      background: #fff;
      border-radius: 12px;
      padding: 8px;
      display: grid;
      gap: 8px;
    }

    .saved-meta {
      display: flex;
      justify-content: space-between;
      align-items: center;
      gap: 8px;
      flex-wrap: wrap;
      color: #385589;
      font-size: 0.9rem;
      font-weight: 800;
    }

    .saved-actions {
      display: flex;
      gap: 6px;
      flex-wrap: wrap;
      padding-bottom: 4px;
    }

    .saved-actions .mini-btn {
      box-shadow: none !important;
    }

    .mini-btn {
      min-height: 34px;
      min-width: 74px;
      font-size: 0.82rem;
      padding: 8px 10px;
      border-radius: 10px;
    }

    .note {
      width: var(--tile-size);
      height: var(--tile-size);
      border-radius: 22px;
      border: 3px solid transparent;
      margin: 0;
      padding: 0;
      background: var(--note-color, #ff7a7a);
      color: #fff;
      font-size: clamp(1.75rem, 4.8vw, 2.2rem);
      font-weight: 900;
      text-shadow: 0 2px 6px rgba(0, 0, 0, 0.22);
      box-shadow:
        inset 0 1px 1px rgba(255, 255, 255, 0.35),
        0 4px 0 rgba(0, 0, 0, 0.12),
        0 6px 10px rgba(33, 43, 74, 0.14);
      display: grid;
      place-items: center;
      touch-action: none;
      user-select: none;
      -webkit-user-select: none;
      -webkit-touch-callout: none;
      overflow: hidden;
      position: relative;
      transition: transform 0.12s ease, filter 0.12s ease;
    }

      /* ...with ONE exception, on a phone. When the bank strip is wider than
         the screen, its notes give the browser back the sideways pan - see
         updateBankPan() in the JS. The gestures do not fight: the strip scrolls
         sideways and notes are dragged UP out of it onto the staff. Scoped to
         notes inside the strip, so notes already placed are untouched. */
      .bank-area.is-pannable .note {
        touch-action: pan-x;
      }

      /* Reachable is not discoverable: without a cue the strip just looks like it
         ends at the screen edge. A soft right-edge fade, only while there is more to
         see. mask-image rather than an overlay, so it cannot intercept the very
         gesture it advertises. */
      .bank-area.is-pannable {
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
        mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent 100%);
      }


    .bank-note {
      width: var(--bank-note-size);
      height: calc(var(--bank-note-size) * 1.34);
      min-width: var(--bank-note-size);
      min-height: calc(var(--bank-note-size) * 1.34);
      border: 3px solid var(--note-color, #c9d7f5);
      border-radius: 22px;
      background: linear-gradient(180deg, #f7f9ff, #edf2ff);
      box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.95),
        0 4px 0 rgba(25, 46, 93, 0.12),
        0 8px 16px rgba(25, 46, 93, 0.14);
      color: #1f3668;
      font-size: 0.98rem;
      font-weight: 900;
      text-shadow: none;
      position: relative;
      overflow: hidden;
    }

    .bank-note.has-image {
      background: linear-gradient(180deg, #f7f9ff, #edf2ff);
      color: #1f3668;
    }

    .bank-note .note-art {
      width: 82%;
      height: 82%;
      margin-top: -8px;
      filter: drop-shadow(0 4px 5px rgba(0, 52, 75, 0.2));
    }

    .chromatic-white-note .note-art {
      margin-top: -5px;
    }

    .bank-note .note-label {
      bottom: 8px;
      min-width: 0;
      padding: 0;
      font-size: 0.7rem;
      line-height: 1.2;
      color: #223e75;
      background: transparent;
      border: 0;
      text-shadow: 0 1px 2px rgba(255, 255, 255, 0.66);
      box-shadow: none;
    }

    .chromatic-white-note .note-label {
      bottom: 5px;
    }

    .bank-note.note-playing {
      transform: translateY(1px) scale(1.04);
      filter: brightness(1.04);
    }

    .chromatic-black-note {
      border: 0;
      background: linear-gradient(180deg, #3f4c66, #35425b);
      box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.1),
        0 2px 0 rgba(20, 29, 43, 0.32),
        0 5px 9px rgba(20, 29, 43, 0.2);
      color: #eef2ff;
    }

    .chromatic-black-note .note-label {
      color: #ffffff;
      background: transparent;
      border: 0;
      text-shadow: 0 1px 2px rgba(0, 0, 0, 0.38);
    }

    .note.has-image {
      background: linear-gradient(180deg, #ffffff, #eef4ff);
      border-color: var(--note-color, #8fa3d8);
      color: #20315f;
      text-shadow: none;
      box-shadow:
        inset 0 1px 1px rgba(255, 255, 255, 0.9),
        0 4px 0 rgba(0, 0, 0, 0.1),
        0 6px 10px rgba(33, 43, 74, 0.12);
    }

    .bank-note.chromatic-black-note.has-image {
      border: 0;
      background: linear-gradient(180deg, #3f4c66, #35425b);
      color: #eef2ff;
      box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.1),
        0 2px 0 rgba(20, 29, 43, 0.32),
        0 5px 9px rgba(20, 29, 43, 0.2);
    }

    .bank-note.chromatic-black-note.has-image .note-label,
    .bank-note.chromatic-black-note .note-label {
      color: #ffffff;
      text-shadow: 0 1px 2px rgba(0, 0, 0, 0.38);
    }

    /* Make placed notes sit directly over the rest placeholder area. */
    .slot > .slot-note {
      width: calc(100% + 2px);
      height: calc(100% + 2px);
      margin: 0;
      border-radius: 18px;
      box-shadow:
        inset 0 1px 1px rgba(255, 255, 255, 0.88),
        0 1px 3px rgba(33, 43, 74, 0.1);
    }

    .slot-duo {
      position: absolute;
      inset: 0;
      display: grid;
      grid-template-columns: 1fr 1fr;
      z-index: 2;
    }

    .slot-duo .slot-note {
      width: 100%;
      height: 100%;
      margin: 0;
      border-radius: 0;
      border-width: 0;
      box-shadow: none;
    }

    .slot-duo .slot-note:first-child {
      border-right: 1px solid rgba(141, 158, 205, 0.65);
    }

    .slot-note.accented {
      box-shadow:
        inset 0 0 0 2px rgba(255, 255, 255, 0.84),
        0 0 0 2px rgba(245, 181, 78, 0.7),
        0 2px 6px rgba(237, 169, 50, 0.24);
    }

    .slot-duo .slot-note.accented {
      box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.7),
        0 0 0 1.5px rgba(245, 181, 78, 0.74);
    }

    .slot-note.accented::after {
      content: none;
    }

    /* An 18px button (16px in duo slots) is about a third of a fingertip, and
       missing it lands on the note underneath and DRAGS it — so a miss here is
       not nothing, it is damage. The visual dot stays small; only the touch
       target grows, to 44px, via a transparent ::after that overhangs the
       button. The button is already positioned, so that is what the ::after
       resolves against. */
    .accent-toggle-btn::after {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      width: 44px;
      height: 44px;
      transform: translate(-50%, -50%);
    }

    .accent-toggle-btn {
      position: absolute;
      top: 8px;
      left: 8px;
      z-index: 7;
      width: 18px;
      height: 18px;
      border: 0;
      background: transparent;
      color: #6b7fae;
      font-size: 0.72rem;
      font-weight: 900;
      line-height: 1;
      display: grid;
      place-items: center;
      padding: 0;
      text-shadow:
        0 1px 1px rgba(255, 255, 255, 0.72),
        0 0 2px rgba(255, 255, 255, 0.52);
    }

    .slot-sustain-handle {
      position: absolute;
      right: 2px;
      top: 50%;
      transform: translateY(-50%);
      z-index: 8;
      width: 12px;
      height: 34px;
      border-radius: 999px;
      border: 2px solid #ffffff;
      background: linear-gradient(180deg, var(--hold-color, #8fa3d8), var(--hold-color, #8fa3d8));
      box-shadow: 0 2px 6px rgba(23, 40, 76, 0.25);
      padding: 0;
      cursor: ew-resize;
      color: transparent;
    }

    .slot-sustain-handle::before {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      width: 4px;
      height: 18px;
      border-radius: 999px;
      background: rgba(255, 255, 255, 0.88);
    }

    .slot-note.accented .accent-toggle-btn {
      color: #d99521;
      text-shadow:
        0 1px 1px rgba(255, 247, 221, 0.9),
        0 0 2px rgba(255, 247, 221, 0.75);
    }

    .slot-duo .accent-toggle-btn {
      width: 16px;
      height: 16px;
      top: 5px;
      left: 5px;
      font-size: 0.62rem;
    }

    .slot-duo-label {
      position: absolute;
      left: 50%;
      bottom: 2px;
      transform: translateX(-50%);
      z-index: 5;
      padding: 1px 5px;
      border-radius: 999px;
      font-size: 0.65rem;
      font-weight: 900;
      color: #18356c;
      background: rgba(255, 255, 255, 0.72);
      white-space: nowrap;
      pointer-events: none;
    }

    .note-art {
      width: 74%;
      height: 74%;
      object-fit: contain;
      margin-top: -8px;
      pointer-events: none;
      filter: drop-shadow(0 4px 4px rgba(22, 39, 76, 0.2));
    }

    .note-label {
      position: absolute;
      left: 50%;
      bottom: 2px;
      transform: translateX(-50%);
      min-width: 36px;
      padding: 1px 4px;
      border-radius: 999px;
      font-size: 0.78rem;
      font-weight: 900;
      letter-spacing: 0.02em;
      color: #173065;
      background: transparent;
      box-shadow: none;
      text-shadow:
        0 1px 1px rgba(255, 255, 255, 0.8),
        0 0 2px rgba(255, 255, 255, 0.6);
      pointer-events: none;
      white-space: nowrap;
    }

    .slot-duo .note-art {
      width: 82%;
      height: 82%;
      margin-top: -10px;
    }

    .slot-duo .note-label {
      display: none;
    }

    .note.note-playing {
      transform: translateY(1px) scale(1.03);
      filter: brightness(1.04);
    }

    .slot.previewing {
      border-color: #009999;
      box-shadow:
        inset 0 2px 0 rgba(255, 255, 255, 0.9),
        0 0 0 4px rgba(0, 153, 153, 0.18);
    }

    .slot-preview {
      position: absolute;
      inset: 0;
      z-index: 4;
      pointer-events: none;
      opacity: 0.92;
      filter: saturate(1.05) brightness(1.02);
    }

    .slot-preview .slot-note,
    .slot-preview .slot-duo {
      pointer-events: none;
    }

    .slot-preview .slot-note {
      box-shadow:
        inset 0 0 0 2px rgba(255, 255, 255, 0.5),
        0 0 0 3px rgba(0, 153, 153, 0.28);
    }

    .slot-preview .slot-duo .slot-note {
      box-shadow: none;
    }

    .slot-preview .slot-duo-label {
      background: rgba(0, 153, 153, 0.12);
      color: #0d4477;
    }


    .drag-ghost {
      position: fixed;
      z-index: 95;
      pointer-events: none;
      opacity: 0.85;
      transform: rotate(-4deg) scale(1.05);
      box-shadow:
        inset 0 1px 1px rgba(255, 255, 255, 0.42),
        0 5px 0 rgba(0, 0, 0, 0.15),
        0 8px 14px rgba(0, 0, 0, 0.18);
    }

    .help {
      margin: 14px 0 0;
      text-align: center;
      color: #7485b3;
      font-size: 0.85rem;
    }

    .micro-burst {
      position: fixed;
      width: 8px;
      height: 8px;
      pointer-events: none;
      z-index: 120;
    }

    .micro-burst-dot {
      position: absolute;
      width: 8px;
      height: 8px;
      border-radius: 50%;
      background: var(--dot-color, #5b6bff);
      opacity: 0;
      transform: translate(-50%, -50%);
      animation: microBurstDot 760ms ease-out forwards;
      animation-delay: var(--delay, 0ms);
    }

    @keyframes microBurstDot {
      0% {
        opacity: 0;
        transform: translate(-50%, -50%) translate(0, 0) scale(0.65);
      }
      16% {
        opacity: 1;
      }
      100% {
        opacity: 0;
        transform: translate(-50%, -50%) translate(var(--dx, 0px), var(--dy, 0px)) scale(0.26);
      }
    }

    @media (prefers-reduced-motion: reduce) {
      .play-circle.micro-celebrate {
        animation: none;
      }

      .micro-burst-dot {
        animation: none;
      }
    }

    .print-title {
      margin: 0 0 10px;
      text-align: center;
      color: #17366a;
      font-size: 1.3rem;
      font-weight: 900;
    }

    /* Short screens: the beats are what get buried, so the tiles give a
       little before the dock does. */
    @media (max-height: 820px) {
      :root {
        --tile-size: 92px;
      }
    }

    @media (max-width: 860px) {
      :root {
        --tile-size: 96px;
        --gap: 8px;
        --bank-note-size: clamp(38px, calc((100vw - 64px) / 15 - 15px), 86px);
        --bank-note-gap: 6px;
        --dock-height: calc(var(--bank-note-size) * 2.05 + 54px);
      }

      body {
        padding: 10px;
      }

      .app {
        border-radius: 22px;
      }

      .saved-panel {
        width: min(420px, calc(100vw - 36px));
      }

      .toolbar {
        gap: 8px;
      }

      #gameScreen {
        padding-bottom: calc(var(--dock-height) + env(safe-area-inset-bottom) + 20px);
      }

      .bank-dock {
        width: calc(100vw - 20px);
      }
    }

    @media print {
      @page {
        margin: 10mm;
      }

      :root {
        --tile-size: 70px;
        --gap: 4px;
      }

      body {
        background: #fff !important;
        padding: 0;
      }

      .app {
        width: 100%;
        border: 0;
        box-shadow: none;
        border-radius: 0;
      }

      .boot-loader,
      .composer-row,
      .saved-panel,
      .settings-panel,
      .help-ui,
      .settings,
      .instruction,
      .message,
      .bank-dock,
      .playhead,
      .toolbar,
      .pattern-tools,
      .saved-section,
      .help {
        display: none !important;
      }

      .runtime-meta {
        display: block !important;
      }

      #gameScreen[hidden] {
        display: block !important;
      }

      #gameScreen {
        display: flex !important;
        flex-direction: column;
      }

      .screen {
        padding: 8px 10px 12px;
      }

      .print-title {
        order: 1;
        margin: 0 0 4px;
      }

      .progress {
        order: 2;
        margin: 0 0 8px;
      }

      .slots-wrap {
        order: 3;
        overflow: visible;
        width: 100%;
      }

      .slot.measure-start {
        margin-left: 0;
      }

      .slots-grid {
        margin: 0;
      }
    }

    /* ── PK-5 full-bleed (desktop / iframe ≥861px) ──────────────────────────
       Bell Composer is iframed into bell-composer.html on the PK-5 site. The
       iframe width tracks the available content area, so this min-width block
       fires whenever there's room — removing the white card and letting the
       tool + instrument dock run edge-to-edge like the Compose Tool. Below
       861px the existing mobile layout (max-width:860px) takes over untouched.
    ──────────────────────────────────────────────────────────────────────── */
    @media (min-width: 861px) {
      body {
        background: #f5f5f3 !important;
        padding: 0 !important;
      }
      /* Drop the white card — full width, no border / radius / shadow */
      .app {
        width: 100% !important;
        max-width: none !important;
        margin: 0 !important;
        background: transparent !important;
        border: none !important;
        border-radius: 0 !important;
        box-shadow: none !important;
      }
      .screen {
        padding-left: 28px !important;
        padding-right: 28px !important;
      }
      /* Full-width instrument dock — edge to edge, square top */
      .bank-dock {
        left: 0 !important;
        right: 0 !important;
        transform: none !important;
        width: 100% !important;
        max-width: none !important;
      }
      .bank-dock-inner {
        border-radius: 0 !important;
      }
    }

/* Free tier (2026-09-23): only SAVING needs the unlock. The Save button keeps
   working as a door to the wall, so it dims gently and wears the lock chip on
   its corner. Never red, never "error" looking. */
#savePatternBtn.is-locked { position: relative; opacity: .8; }
#savePatternBtn .save-lock-chip { position: absolute; top: -9px; right: -9px; pointer-events: none; line-height: 1; }
#savePatternBtn .save-lock-chip .pmg-lock { padding: 2px 7px; font-size: 10px; box-shadow: 0 1px 3px rgba(27,35,62,.18); background: #fff; }

/* Note names (1.0.2): a Do Re Mi label longer than its letters ("Low Sol♯") shrinks
   a little rather than overflow the bell. Never set in letters mode. */
.note-label.nn-long { scale: 0.84; }
