:root {
   --ink: #163a2a;
   --muted: #718078;
   --green: #237a50;
   --dark-green: #155c3c;
   --lime: #b8e85c;
   --cream: #fcfbf5;
   --surface: #ffffff;
   --line: #d9e5dc;
   --soft: #eaf5ed;
   --app-bg: #f2f5f2;
   --shadow-sm: 0 1px 2px rgba(20, 58, 41, 0.05), 0 7px 24px rgba(20, 58, 41, 0.06);
   --shadow-md: 0 18px 55px rgba(20, 58, 41, 0.12);
   --radius-sm: 9px;
   --radius-md: 14px;
   --radius-lg: 22px;
}

/* SoundFont Download Modal Styles */
.download-modal-overlay {
   position: fixed;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
   background: rgba(22, 58, 41, 0.6);
   backdrop-filter: blur(4px);
   display: flex;
   align-items: center;
   justify-content: center;
   z-index: 9999;
   animation: fadeIn 0.2s ease-out;
}

@keyframes fadeIn {
   from {
      opacity: 0;
   }
   to {
      opacity: 1;
   }
}

.download-modal {
   background: var(--surface);
   border-radius: var(--radius-lg);
   padding: 28px;
   max-width: 420px;
   width: 90%;
   box-shadow: var(--shadow-md);
   animation: slideUp 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

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

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

.download-icon {
   font-size: 32px;
   width: 48px;
   height: 48px;
   display: flex;
   align-items: center;
   justify-content: center;
   background: var(--soft);
   border-radius: 12px;
}

.download-modal-title {
   font-size: 18px;
   font-weight: 600;
   color: var(--ink);
   margin: 0;
}

.download-modal-content {
   display: flex;
   flex-direction: column;
   gap: 16px;
   margin-bottom: 24px;
}

.info-row {
   display: flex;
   align-items: center;
   gap: 10px;
   font-size: 14px;
   color: var(--ink);
}

.info-label {
   font-weight: 500;
   min-width: 70px;
}

.info-value {
   color: var(--muted);
}

.progress-container {
   background: var(--soft);
   border-radius: var(--radius-md);
   padding: 8px 12px;
   overflow: hidden;
}

.progress-bar {
   height: 8px;
   background: linear-gradient(90deg, var(--green), var(--lime));
   border-radius: 4px;
   transition: width 0.15s ease-out;
   width: 0%;
}

.progress-text {
   text-align: center;
   font-size: 13px;
   color: var(--muted);
   margin-top: 8px;
   font-family: monospace;
}

.download-actions {
   display: flex;
   gap: 12px;
   justify-content: flex-end;
}

.download-btn {
   padding: 10px 20px;
   border-radius: var(--radius-sm);
   font-size: 14px;
   font-weight: 500;
   cursor: pointer;
   transition: all 0.15s ease;
   border: none;
   outline: none;
}

.btn-cancel {
   background: var(--soft);
   color: var(--muted);
}

.btn-cancel:hover {
   background: var(--line);
   color: var(--ink);
}

.btn-download {
   background: var(--green);
   color: white;
}

.btn-download:hover:not(:disabled) {
   background: var(--dark-green);
   transform: scale(1.02);
}

.btn-download:disabled {
   opacity: 0.6;
   cursor: not-allowed;
   transform: none;
}

.btn-download.loading {
   pointer-events: none;
   opacity: 0.8;
}

.btn-download .spinner {
   display: inline-block;
   width: 16px;
   height: 16px;
   border: 2px solid transparent;
   border-top-color: white;
   border-radius: 50%;
   animation: spin 0.8s linear infinite;
   margin-right: 8px;
   vertical-align: middle;
}

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

html {
   scroll-behavior: smooth;
}
body {
   min-height: 100vh;
   background: radial-gradient(circle at 8% 4%, rgba(184, 232, 92, 0.12), transparent 25rem), var(--app-bg);
   color: var(--ink);
}
button,
input,
select {
   font-family: inherit;
}
button,
label,
[draggable="true"] {
   -webkit-tap-highlight-color: transparent;
}
.sr-only {
   position: absolute !important;
   width: 1px !important;
   height: 1px !important;
   padding: 0 !important;
   margin: -1px !important;
   overflow: hidden !important;
   clip: rect(0, 0, 0, 0) !important;
   white-space: nowrap !important;
   border: 0 !important;
}

/* Application shell */
.topbar {
   position: relative;
   z-index: 10;
   height: 68px;
   padding: 0 clamp(20px, 4vw, 64px);
   border-bottom: 1px solid rgba(217, 229, 220, 0.9);
   background: rgba(255, 255, 255, 0.92);
   box-shadow: 0 1px 0 rgba(22, 58, 42, 0.03);
   backdrop-filter: blur(16px);
}
.brand {
   gap: 12px;
   font-size: 19px;
   letter-spacing: -0.45px;
}
.brand-icon {
   width: 38px;
   height: 38px;
   border-radius: 12px;
   background: linear-gradient(145deg, #2b875b, #145b3b);
   box-shadow: 0 7px 16px rgba(35, 122, 80, 0.2);
   overflow: hidden;
}
.brand-icon img {
   display: block;
   width: 100%;
   height: 100%;
   border-radius: inherit;
}
.brand small {
   color: #819088;
   font-size: 9px;
   letter-spacing: 0.13em;
}
.topbar-actions {
   align-items: center;
   gap: 7px;
}
.autosave-status {
   display: inline-flex;
   align-items: center;
   gap: 7px;
   margin-right: 5px;
   color: var(--muted);
   font-size: 11px;
   white-space: nowrap;
}
.autosave-status i {
   width: 7px;
   height: 7px;
   border-radius: 50%;
   background: #55a976;
   box-shadow: 0 0 0 4px rgba(85, 169, 118, 0.11);
}
.button {
   min-height: 38px;
   border: 1px solid transparent;
   border-radius: 10px;
   padding: 9px 14px;
   font-size: 12px;
   transition:
      transform 0.16s ease,
      box-shadow 0.16s ease,
      background 0.16s ease,
      border-color 0.16s ease;
}
.button span[aria-hidden="true"] {
   margin-right: 5px;
   font-size: 14px;
}
.button:hover {
   transform: translateY(-1px);
   filter: none;
}
.button-primary {
   background: var(--green);
   box-shadow: 0 6px 14px rgba(35, 122, 80, 0.18);
}
.button-primary:hover {
   background: #1e6e47;
   box-shadow: 0 8px 18px rgba(35, 122, 80, 0.24);
}
.button-ghost {
   border-color: #dbe8df;
   background: #f8fbf9;
}
.button-ghost:hover {
   border-color: #bfd7c6;
   background: #eef7f0;
}
/* Editor topbar's two prominent actions. Both are filled (so they clearly read
   as primary), but carry distinct accents so their purpose is unmistakable:
   Save to Cloud = brand green (the safety action users look for first), and
   Export .pdf = a deep charcoal (the output action). */
.button-save {
   background: var(--green);
   color: #fff;
   box-shadow: 0 6px 14px rgba(35, 122, 80, 0.2);
}
.button-save:hover {
   background: #1e6e47;
   box-shadow: 0 8px 18px rgba(35, 122, 80, 0.26);
}
.button-save.is-saving {
   opacity: 0.75;
   pointer-events: none;
}
/* Unsaved-changes indicator (#4). A small amber dot rides the top-right corner
   of Save to Cloud whenever the open document has edits not yet persisted to
   the cloud. A soft pulse draws the eye without being noisy. */
.button-save.is-unsaved {
   position: relative;
}
.button-save.is-unsaved::after {
   content: "";
   position: absolute;
   top: -3px;
   right: -3px;
   width: 11px;
   height: 11px;
   border-radius: 50%;
   background: #f5a623;
   border: 2px solid var(--surface, #fff);
   box-shadow: 0 0 0 0 rgba(245, 166, 35, 0.5);
   animation: saveUnsavedPulse 2s ease-out infinite;
}
@keyframes saveUnsavedPulse {
   0% {
      box-shadow: 0 0 0 0 rgba(245, 166, 35, 0.5);
   }
   70% {
      box-shadow: 0 0 0 6px rgba(245, 166, 35, 0);
   }
   100% {
      box-shadow: 0 0 0 0 rgba(245, 166, 35, 0);
   }
}
@media (prefers-reduced-motion: reduce) {
   .button-save.is-unsaved::after {
      animation: none;
   }
}
.button-dark {
   background: #223029;
   color: #fff;
   box-shadow: 0 6px 14px rgba(16, 40, 28, 0.22);
}
.button-dark:hover {
   background: #2c3e34;
   box-shadow: 0 8px 18px rgba(16, 40, 28, 0.28);
}
html[data-theme="dark"] .button-dark {
   background: #e7ece8;
   color: #10231b;
}
html[data-theme="dark"] .button-dark:hover {
   background: #f3f6f3;
}
.theme-toggle {
   min-width: 76px;
}
.theme-toggle-icon {
   width: 14px;
   margin-right: 5px !important;
   text-align: center;
}

main {
   max-width: 1560px;
   padding: 30px clamp(20px, 4vw, 64px) 72px;
}
.workspace,
.ribbon-workspace,
.editor-card,
.preview-stage {
   min-width: 0;
   max-width: 100%;
}
.intro {
   margin: 0 0 24px;
}
.intro .eyebrow {
   display: inline-flex;
   align-items: center;
   gap: 7px;
}
.intro .eyebrow::before {
   content: "";
   width: 18px;
   height: 2px;
   border-radius: 2px;
   background: var(--lime);
}
.intro h1 {
   max-width: 760px;
   margin: 8px 0 6px;
   font-size: clamp(27px, 3vw, 38px);
   line-height: 1.08;
   letter-spacing: -1.5px;
}
.intro p {
   font-size: 13px;
}

/* Ribbon */
.ribbon-workspace .editor-card {
   top: 0;
   z-index: 20;
   margin-bottom: 22px;
   padding: 12px 18px 14px;
   border-color: rgba(207, 224, 212, 0.95);
   border-radius: var(--radius-lg);
   background: rgba(255, 255, 255, 0.96);
   box-shadow: var(--shadow-sm);
   backdrop-filter: blur(18px);
   transition:
      padding 0.2s ease,
      border-radius 0.2s ease,
      box-shadow 0.2s ease;
}
.ribbon-workspace .editor-card.is-scrolled {
   padding-top: 9px;
   border-radius: 15px;
   box-shadow: 0 12px 35px rgba(20, 58, 41, 0.13);
}
/* Arrangement-tools ribbon is hidden: chord entry now happens inline on each
   beat (click → popover) and rhythm via the right-click / long-press menu. The
   aside stays in the DOM (JS still references its inputs for meta + lyrics
   state); we only remove it visually and from layout. */
.ribbon-workspace .editor-card {
   display: none;
}
/* Topbar global lyrics toggle (replaces the ribbon Lyrics panel switch). */
.topbar-lyrics-toggle {
   margin-right: 4px;
}
.ribbon-heading {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 16px;
   min-height: 38px;
   padding: 0 2px 9px;
}
.ribbon-heading > div {
   display: flex;
   align-items: baseline;
   gap: 9px;
}
.ribbon-kicker {
   color: var(--green);
   font-size: 9px;
   font-weight: 900;
   letter-spacing: 0.13em;
}
.ribbon-heading strong {
   color: var(--muted);
   font-size: 11px;
   font-weight: 650;
}
.icon-button {
   display: inline-grid;
   place-items: center;
   border: 1px solid #d5e3d8;
   border-radius: 8px;
   background: #fff;
   color: var(--dark-green);
   cursor: pointer;
   transition:
      background 0.15s ease,
      border-color 0.15s ease,
      transform 0.15s ease;
}
.icon-button:hover {
   border-color: #a9c9b3;
   background: var(--soft);
}
.icon-button:active {
   transform: translateY(1px);
}
.icon-button:disabled {
   border-color: #e0e8e2;
   background: #f5f7f5;
   color: #9ba8a0;
   cursor: not-allowed;
   transform: none;
}
.ribbon-toggle {
   width: 30px;
   height: 30px;
}
.ribbon-toggle > span[aria-hidden="true"] {
   display: block;
   font-size: 16px;
   transition: transform 0.2s ease;
}
.editor-card.is-collapsed .ribbon-toggle > span[aria-hidden="true"] {
   transform: rotate(180deg);
}
.editor-card.is-collapsed .ribbon-panels {
   display: none;
}
.editor-card.is-collapsed {
   padding-bottom: 10px;
}
.editor-card.is-collapsed .ribbon-heading {
   padding-bottom: 6px;
}
.editor-card.is-collapsed .ribbon-tabs {
   border-bottom-color: transparent;
}
.ribbon-tabs {
   gap: 3px;
   overflow-x: auto;
   scrollbar-width: none;
}
.ribbon-tab[hidden],
.ribbon-panel[hidden] {
   display: none !important;
}
.ribbon-tabs::-webkit-scrollbar {
   display: none;
}
.ribbon-tab {
   position: relative;
   border-radius: 9px 9px 0 0;
   padding: 9px 14px 11px;
   font-size: 11px;
   font-weight: 750;
   transition:
      color 0.15s ease,
      background 0.15s ease;
}
.ribbon-tab:hover {
   background: #f4f8f5;
   color: var(--dark-green);
}
.ribbon-tab.active {
   background: #eef7f0;
   box-shadow: none;
}
.ribbon-tab.active::after {
   content: "";
   position: absolute;
   right: 12px;
   bottom: 0;
   left: 12px;
   height: 3px;
   border-radius: 3px 3px 0 0;
   background: var(--lime);
}
.ribbon-panels {
   min-height: 108px;
   padding-top: 11px;
}
.ribbon-panel.active {
   gap: 12px;
}
.ribbon-panel .palette-group {
   border-color: #dce9df;
   border-radius: 12px;
   background: #f9fcfa;
}
.ribbon-panel .nashville-builder {
   min-width: 1000px;
   grid-template-columns: max-content 1px minmax(420px, 1fr) 150px;
}
.ribbon-panel .nashville-number-row {
   grid-template-columns: repeat(7, 36px);
}
.ribbon-panel .nashville-number-row.nashville-zero-row {
   grid-template-columns: 36px;
}
.palette-label {
   color: #668171;
}
.chord,
.duration-option {
   transition:
      transform 0.14s ease,
      background 0.14s ease,
      border-color 0.14s ease,
      box-shadow 0.14s ease;
}
.chord:hover,
.duration-option:hover {
   transform: translateY(-2px);
   border-color: #a9ceb4;
   box-shadow: 0 5px 12px rgba(35, 122, 80, 0.09);
}
.chord:focus-visible,
.duration-option:focus-visible {
   outline: 3px solid rgba(184, 232, 92, 0.55);
   outline-offset: 2px;
}
.chord.palette-selected,
.duration-option.palette-selected {
   border-color: var(--green);
   background: #dff2e4;
   box-shadow: 0 0 0 3px rgba(35, 122, 80, 0.1);
}
.chord.is-dragging,
.duration-option.is-dragging {
   opacity: 0.58;
   transform: scale(0.96);
}

/* Canvas */
.preview-stage {
   position: relative;
   width: 100%;
   overflow: hidden;
   border: 0;
   border-radius: 0;
   background: transparent;
   box-shadow: none;
}
html.is-print-layout body {
   background: #dfe6e1;
}
html.is-print-layout .topbar,
html.is-print-layout .intro,
html.is-print-layout .editor-card,
html.is-print-layout .site-footer {
   /* Keep chrome available, but de-emphasize while inspecting score paper. */
   opacity: 0.92;
}
html.is-print-layout .preview-stage {
   border-color: #c9d5cc;
   background: #edf1ee;
   box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.75);
}
html.is-print-layout .preview-viewport {
   padding: 18px 16px 28px;
   background: linear-gradient(180deg, rgba(255, 255, 255, 0.35), transparent 48px), #e7ece8;
}
html.is-print-layout .ribbon-workspace .preview-card {
   min-width: min(920px, 100%);
   margin: 0 auto;
   border: 0;
   border-radius: 0;
   padding: 9mm 9mm 12mm;
   background: #fff;
   box-shadow: none;
   zoom: 1 !important;
}
html.is-print-layout .scroll-affordance {
   display: none;
}
.preview-viewport {
   position: relative;
   overflow: auto;
   max-width: 100%;
   padding: 0;
   outline: none;
   scrollbar-color: #a8beb0 transparent;
   scrollbar-width: thin;
}
.preview-viewport::-webkit-scrollbar {
   width: 9px;
   height: 9px;
}
.preview-viewport::-webkit-scrollbar-track {
   background: transparent;
}
.preview-viewport::-webkit-scrollbar-thumb {
   border: 2px solid transparent;
   border-radius: 10px;
   background: #a8beb0;
   background-clip: padding-box;
}
.preview-viewport:focus-visible {
   box-shadow: inset 0 0 0 3px rgba(35, 122, 80, 0.18);
}
.ribbon-workspace .preview-card {
   width: 100%;
   min-width: 920px;
   margin: 0 auto;
   border: 1px solid #e5e5df;
   border-radius: 5px;
   background: var(--cream);
   box-shadow: var(--shadow-md);
   transform-origin: top left;
}
.preview-header h2 {
   line-height: 1.08;
}
.preview-editable {
   border-radius: 6px;
   transition:
      background 0.15s ease,
      color 0.15s ease,
      box-shadow 0.15s ease;
}
.preview-editable:hover {
   background: rgba(232, 244, 235, 0.72);
   box-shadow: 0 0 0 4px rgba(232, 244, 235, 0.72);
}
.song-meta {
   align-items: flex-start;
}
.transpose-buttons button {
   transition:
      transform 0.14s ease,
      background 0.14s ease,
      border-color 0.14s ease;
}
/* Playback control — play/stop button + BPM input + metronome toggle.
   Sits right after transpose, same row, same visual weight. */
.playback-control {
   display: inline-flex;
   align-items: center;
   margin-left: 12px;
   padding: 4px 6px;
   gap: 2px;
   font-size: var(--ui-font-size, 0.7rem);
   background: color-mix(in srgb, var(--green) 8%, var(--surface));
   border: 1px solid color-mix(in srgb, var(--green) 26%, var(--line));
   border-radius: 999px;
   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}
.play-btn {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: 34px;
   height: 34px;
   border: none;
   border-radius: 50%;
   cursor: pointer;
   color: #fff;
   font-size: 0.98rem;
   line-height: 1;
   background: linear-gradient(135deg, var(--ui-accent, #4caf50), #2f9e44);
   box-shadow: 0 2px 6px rgba(76, 175, 80, 0.35);
   transition:
      transform 0.12s ease,
      background 0.14s ease,
      box-shadow 0.14s ease;
}
.play-btn:hover {
   transform: translateY(-1px);
   background: linear-gradient(135deg, var(--ui-accent, #4caf50), #2b8a3e);
}
.play-btn:active {
   transform: translateY(0) scale(0.96);
}
.play-btn:focus-visible {
   outline: 2px solid var(--ui-accent, #4caf50);
   outline-offset: 2px;
}
.play-btn.playing {
   animation: play-pulse 1.6s ease-in-out infinite;
}
@keyframes play-pulse {
   0% { box-shadow: 0 0 0 0 rgba(76, 175, 80, 0.45); }
   70% { box-shadow: 0 0 0 8px rgba(76, 175, 80, 0); }
   100% { box-shadow: 0 0 0 0 rgba(76, 175, 80, 0); }
}
.bpm-control {
   display: inline-flex;
   align-items: center;
   gap: 5px;
   padding: 0 8px;
   border-left: 1px solid var(--ui-border, #e0e0e0);
   color: var(--ui-text-dim, #666);
   font-size: 0.66rem;
   font-weight: 600;
   text-transform: uppercase;
   letter-spacing: 0.05em;
}
.bpm-control input {
   width: 46px;
   height: 26px;
   border: 1px solid var(--ui-border, #ccc);
   border-radius: 999px;
   text-align: center;
   font-size: 0.8rem;
   font-weight: 600;
   color: var(--ui-text, #333);
   background: var(--ui-bg, #fff);
   -moz-appearance: textfield;
   transition: border-color 0.14s ease, box-shadow 0.14s ease;
}
.bpm-control input:focus-visible {
   outline: none;
   border-color: var(--ui-accent, #4caf50);
   box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.25);
}
.bpm-control input::-webkit-outer-spin-button,
.bpm-control input::-webkit-inner-spin-button {
   -webkit-appearance: none;
   margin: 0;
}
.metronome-btn {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: 30px;
   height: 30px;
   border: none;
   border-radius: 50%;
   background: transparent;
   color: var(--ui-text-dim, #888);
   cursor: pointer;
   font-size: 0.9rem;
   transition: color 0.14s ease, background 0.14s ease;
}
.metronome-btn:hover {
   background: rgba(0, 0, 0, 0.05);
   color: var(--ui-text, #333);
}
.metronome-btn:focus-visible {
   outline: 2px solid var(--ui-accent, #4caf50);
   outline-offset: 2px;
}
.metronome-btn[aria-pressed="true"] {
   color: var(--ui-accent, #4caf50);
}
/* Playback highlight — marks the beat currently being played. */
.beat.beat-playing,
.sub-beat.beat-playing {
   background: rgba(76, 175, 80, 0.25);
   border-radius: 4px;
   box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.5);
   transition:
      background 0.05s ease,
      box-shadow 0.05s ease;
}
/* History toolbar (undo/redo) — sits on its own row below the song meta
   (key / time signature / transpose), aligned to the right so it lines up
   under the transpose control. Wrapped with .song-meta in .preview-meta-col
   so .preview-header keeps exactly two flex children (transpose stays right). */
.preview-meta-col {
   display: flex;
   flex-direction: column;
   align-items: flex-end;
   gap: 12px;
}
.history-toolbar {
   display: flex;
   align-items: center;
   gap: 8px;
}
.history-btn {
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 9px 16px;
   border: 1.5px solid var(--accent, #2f7d4f);
   border-radius: 8px;
   background: var(--surface, #fff);
   color: var(--accent, #2f7d4f);
   font-size: 13px;
   font-weight: 600;
   letter-spacing: 0.01em;
   cursor: pointer;
   transition: all 0.18s ease;
   line-height: 1;
   white-space: nowrap;
   box-shadow: 0 1px 3px rgba(47, 125, 79, 0.12);
}
.history-btn svg {
   width: 18px;
   height: 18px;
   flex-shrink: 0;
   stroke-width: 2.4;
}
.history-btn:not(:disabled):hover {
   background: var(--accent, #2f7d4f);
   color: #fff;
   transform: translateY(-1px);
   box-shadow: 0 4px 12px rgba(47, 125, 79, 0.32);
}
.history-btn:not(:disabled):active {
   transform: translateY(0);
   box-shadow: 0 1px 3px rgba(47, 125, 79, 0.2);
}
.history-btn:disabled {
   opacity: 0.32;
   cursor: not-allowed;
   border-color: rgba(0, 0, 0, 0.15);
   color: var(--muted, #8a9a90);
   transform: none !important;
   box-shadow: none;
}
.btn-label {
   font-weight: 600;
}
.scroll-affordance {
   position: absolute;
   right: 18px;
   bottom: 13px;
   z-index: 4;
   display: none;
   align-items: center;
   gap: 8px;
   padding: 6px 9px;
   border: 1px solid rgba(196, 213, 201, 0.9);
   border-radius: 999px;
   background: rgba(255, 255, 255, 0.92);
   color: var(--muted);
   box-shadow: 0 5px 16px rgba(22, 58, 42, 0.1);
   font-size: 9px;
   pointer-events: none;
}
.preview-stage.is-overflowing:not(.at-scroll-end) .scroll-affordance {
   display: flex;
}
.scroll-affordance b {
   color: var(--green);
   font-size: 14px;
}

/* Sections and interaction feedback */
.preview-section {
   border-bottom-color: #dfe7e1;
}
.section-preview-heading {
   min-height: 34px;
}
.section-tools {
   padding: 4px 7px;
   border: 1px solid transparent;
   border-radius: 10px;
   transition:
      opacity 0.16s ease,
      background 0.16s ease,
      border-color 0.16s ease,
      transform 0.16s ease;
}
.preview-section:not(.is-active):not(:hover):not(:focus-within) .section-tools {
   opacity: 0;
   transform: translateY(-2px);
   pointer-events: none;
}
.preview-section.is-active .section-tools,
.preview-section:hover .section-tools,
.preview-section:focus-within .section-tools {
   border-color: #e0ebe3;
   background: rgba(249, 252, 250, 0.86);
}
.section-title {
   border-radius: 6px;
   padding: 4px 6px;
   transition: background 0.15s ease;
}
.section-title:hover {
   background: #eef7f0;
   text-decoration: none;
}
.section-lyrics-toggle,
.section-chord-above-toggle,
.text-button {
   transition:
      background 0.15s ease,
      color 0.15s ease,
      border-color 0.15s ease;
}
.section-lyrics-toggle:hover,
.section-chord-above-toggle:hover {
   border-color: #9fcbaa;
   background: #e8f5eb;
}
.text-button {
   border-radius: 6px;
   padding: 5px 7px;
}
.text-button:hover {
   background: #eaf5ed;
   text-decoration: none;
}
.section-menu {
   position: relative;
}
.section-menu summary {
   width: 29px;
   height: 29px;
   display: grid;
   place-items: center;
   border-radius: 7px;
   color: var(--muted);
   font-weight: 900;
   letter-spacing: 1px;
   cursor: pointer;
   list-style: none;
}
.section-menu summary::-webkit-details-marker {
   display: none;
}
.section-menu summary:hover,
.section-menu[open] summary {
   background: #eaf5ed;
   color: var(--dark-green);
}
.section-menu-popover {
   position: absolute;
   top: calc(100% + 6px);
   right: 0;
   z-index: 8;
   width: 150px;
   padding: 6px;
   border: 1px solid #dbe7de;
   border-radius: 9px;
   background: #fff;
   box-shadow: 0 10px 28px rgba(20, 53, 36, 0.15);
}
.delete-section {
   width: 100%;
   border: 0;
   border-radius: 6px;
   padding: 8px 9px;
   background: transparent;
   color: #a1433d;
   font: 750 11px inherit;
   text-align: left;
   cursor: pointer;
}
.delete-section:hover {
   background: #fff0ef;
}
.delete-section:disabled {
   color: #acb7b0;
   cursor: not-allowed;
}
/* Copy / paste entries share the section menu layout but read as neutral. */
.copy-section,
.paste-section {
   width: 100%;
   border: 0;
   border-radius: 6px;
   padding: 8px 9px;
   background: transparent;
   color: var(--dark-green, #1f704a);
   font: 750 11px inherit;
   text-align: left;
   cursor: pointer;
}
.copy-section:hover,
.paste-section:hover {
   background: #e5f4e8;
}
.paste-section:disabled {
   color: #acb7b0;
   cursor: not-allowed;
}
.bar {
   position: relative;
   -webkit-user-select: none;
   user-select: none;
   -webkit-touch-callout: none;
}
.bar .lyric-input {
   -webkit-user-select: text;
   user-select: text;
   -webkit-touch-callout: default;
}
.delete-bar {
   position: absolute;
   top: 3px;
   right: 4px;
   z-index: 5;
   width: 22px;
   height: 22px;
   display: grid;
   place-items: center;
   border: 1px solid #ead8d5;
   border-radius: 6px;
   padding: 0;
   background: rgba(255, 255, 255, 0.94);
   color: #a1433d;
   font:
      800 16px/1 Inter,
      ui-sans-serif,
      sans-serif;
   cursor: pointer;
   opacity: 0;
   transform: translateY(-2px);
   transition:
      opacity 0.15s ease,
      transform 0.15s ease,
      background 0.15s ease;
   -webkit-user-select: none;
   user-select: none;
   -webkit-touch-callout: none;
   touch-action: manipulation;
}
.bar:hover .delete-bar,
.bar:focus-within .delete-bar {
   opacity: 1;
   transform: none;
}
.delete-bar:hover {
   background: #fff0ef;
}
/* Per-bar copy/paste tools, revealed on hover next to the delete affordance. */
.bar-tools {
   position: absolute;
   top: 3px;
   right: 30px;
   z-index: 5;
   display: inline-flex;
   gap: 3px;
   opacity: 0;
   transform: translateY(-2px);
   transition:
      opacity 0.15s ease,
      transform 0.15s ease;
}
.bar:hover .bar-tools,
.bar:focus-within .bar-tools {
   opacity: 1;
   transform: none;
}
.copy-bar,
.paste-bar {
   width: 22px;
   height: 22px;
   display: grid;
   place-items: center;
   border: 1px solid #cfe0d3;
   border-radius: 6px;
   padding: 0;
   background: rgba(255, 255, 255, 0.94);
   color: var(--dark-green, #1f704a);
   font:
      800 13px/1 Inter,
      ui-sans-serif,
      sans-serif;
   cursor: pointer;
   -webkit-user-select: none;
   user-select: none;
   -webkit-touch-callout: none;
   touch-action: manipulation;
}
.copy-bar:hover:not(:disabled),
.paste-bar:hover:not(:disabled) {
   background: #e5f4e8;
   border-color: #8eb99a;
}
.paste-bar:disabled {
   opacity: 0.4;
   cursor: default;
}
/* Multi-bar selection mode highlights */
.bar.is-selectable {
   cursor: pointer;
   position: relative;
}
/* The whole bar is one big click target while selecting: block pointer events
   on inner controls so hovering a chord/beat/lyric never shows edit affordances
   and every click lands on the bar itself. */
.preview-section.is-selecting .bar.is-selectable * {
   pointer-events: none;
}
/* Keep the bar number readable but non-interactive. */
.preview-section.is-selecting .bar .bar-num {
   pointer-events: none;
}
/* Hide ALL hover/edit affordances while selecting: copy/paste/delete tools,
   the per-chord × remove badge, add-bar buttons, section menu, etc.
   NOTE: .beat-dot is intentionally NOT hidden here — the beat/ketukan dots
   must stay visible while Copy Bars is active so the bar's rhythm remains
   readable during selection. */
.preview-section.is-selecting .bar-tools,
.preview-section.is-selecting .delete-bar,
.preview-section.is-selecting .chord-remove,
.preview-section.is-selecting .add-bar {
   display: none !important;
}
/* Neutralise every hover state inside a selecting section. */
.preview-section.is-selecting .beat.drop-target:hover,
.preview-section.is-selecting .sub-beat.drop-target:hover,
.preview-section.is-selecting .placed-chord:hover,
.preview-section.is-selecting .duration-line:hover,
.preview-section.is-selecting .nested-duration-line:hover,
.preview-section.is-selecting .lyric-input:hover {
   background: transparent !important;
   box-shadow: none !important;
   cursor: pointer !important;
}
.preview-section.is-selecting .beat.drop-target:hover::before,
.preview-section.is-selecting .beat.drop-target:hover::after,
.preview-section.is-selecting .sub-beat.drop-target:hover::before,
.preview-section.is-selecting .sub-beat.drop-target:hover::after {
   content: none !important;
}
/* A selectable (not yet selected) bar gets a soft dashed outline so the user
   sees the clickable regions, without hiding the content underneath. */
.preview-section.is-selecting .bar.is-selectable {
   border-radius: 8px;
   outline: 1px dashed rgba(31, 112, 74, 0.35);
   outline-offset: -3px;
   transition:
      outline-color 0.12s ease,
      box-shadow 0.12s ease,
      background 0.12s ease;
}
.preview-section.is-selecting .bar.is-selectable:hover {
   outline-color: rgba(31, 112, 74, 0.6);
   background: rgba(31, 112, 74, 0.05);
}
/* A SELECTED bar: translucent green tint + ring so the chords/lyrics inside
   stay fully visible (previously a solid white fill hid the content). */
.bar.is-selected,
.preview-section.is-selecting .bar.is-selected {
   background: color-mix(in srgb, #1f9d55 16%, transparent) !important;
   border-top: none;
   outline: 2px solid #1f9d55 !important;
   outline-offset: -3px;
   box-shadow:
      inset 0 0 0 9999px color-mix(in srgb, #1f9d55 8%, transparent),
      0 2px 8px rgba(31, 157, 85, 0.18);
}
/* A small check badge in the corner of each selected bar. */
.preview-section.is-selecting .bar.is-selected::after {
   content: "✓";
   position: absolute;
   top: 4px;
   right: 6px;
   width: 16px;
   height: 16px;
   display: flex;
   align-items: center;
   justify-content: center;
   font-size: 11px;
   font-weight: 800;
   color: #fff;
   background: #1f9d55;
   border-radius: 50%;
   pointer-events: none;
   z-index: 3;
}
.bar-selection-bar {
   display: flex;
   align-items: center;
   gap: 16px;
   padding: 10px 14px;
   background: linear-gradient(135deg, #1f9d55, #178048);
   border-radius: 12px;
   margin: 12px 0 10px 0; /* Added top margin for spacing from section title */
   color: #fff;
   font-size: 12px;
   user-select: none;
   box-shadow: 0 6px 18px rgba(31, 157, 85, 0.28);
}
.bar-selection-count {
   font-weight: 700;
   display: inline-flex;
   align-items: center;
   gap: 6px;
}
.bar-selection-hint {
   margin-left: auto;
   color: rgba(255, 255, 255, 0.82);
   font-size: 11px;
}
.bar-selection-copy,
.bar-selection-cancel {
   padding: 5px 12px;
   border-radius: 8px;
   border: 1px solid rgba(255, 255, 255, 0.55);
   background: rgba(255, 255, 255, 0.12);
   color: #fff;
   font: 700 11px inherit;
   cursor: pointer;
   transition:
      background 0.12s ease,
      transform 0.12s ease;
}
.bar-selection-copy {
   background: #fff;
   color: #178048;
   border-color: #fff;
}
.bar-selection-copy:hover,
.bar-selection-cancel:hover {
   transform: translateY(-1px);
}
.bar-selection-copy:hover {
   background: #f0fff6;
}
.bar-selection-cancel:hover {
   background: rgba(255, 255, 255, 0.22);
}
.bar-selection-copy:disabled {
   opacity: 0.5;
   cursor: default;
   transform: none;
}
.select-bars {
   width: 100%;
   border: 0;
   border-radius: 6px;
   padding: 8px 9px;
   background: transparent;
   color: var(--dark-green, #1f704a);
   font: 750 11px inherit;
   text-align: left;
   cursor: pointer;
}
.select-bars:hover {
   background: #e5f4e8;
}
.pdf-signature {
   display: none;
}
body.is-dragging .drop-target {
   background: rgba(234, 245, 237, 0.5);
   box-shadow: inset 0 0 0 1px rgba(35, 122, 80, 0.08);
}
body.is-dragging .drop-target::after {
   content: "";
   position: absolute;
   inset: 5px;
   border: 1px dashed rgba(35, 122, 80, 0.28);
   border-radius: 5px;
   pointer-events: none;
}
.drop-target.dragover {
   z-index: 3;
   background: #def2e3 !important;
   outline: 2px solid #63a77a !important;
   outline-offset: -2px;
}
/* Uniform drag ghost: a fixed-size chip used as the drag image for every
   palette item (chords and rhythm symbols alike) so the "+"/symbol no longer
   render at wildly different sizes while dragging. */
.drag-ghost {
   box-sizing: border-box;
   min-width: 44px;
   height: 40px;
   padding: 0 14px;
   display: flex;
   align-items: center;
   justify-content: center;
   font:
      700 16px/1 Inter,
      ui-sans-serif,
      sans-serif;
   color: #fff;
   background: var(--green, #237a50);
   border-radius: 10px;
   box-shadow: 0 6px 16px rgba(35, 122, 80, 0.35);
   white-space: nowrap;
}
.drop-target.drop-success {
   animation: dropPulse 0.42s ease;
}
@keyframes dropPulse {
   0% {
      box-shadow: 0 0 0 0 rgba(35, 122, 80, 0.42);
   }
   100% {
      box-shadow: 0 0 0 10px rgba(35, 122, 80, 0);
   }
}
.placed-chord {
   transition:
      transform 0.14s ease,
      filter 0.14s ease;
}
.placed-chord:hover {
   transform: translateY(-1px);
   filter: saturate(1.08);
}
.lyric-input:focus {
   box-shadow: 0 0 0 3px rgba(35, 122, 80, 0.14);
}
.preview-footer {
   margin-top: 4px;
   color: #7a8a80;
   display: flex;
   justify-content: flex-end; /* Align actions to the right (Help moved to topbar) */
   align-items: center;
}

/* Help button is now in topbar, not footer */
.preview-help-btn {
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 6px 12px 6px 8px;
   border: 1px solid var(--line);
   border-radius: 999px;
   background: color-mix(in srgb, var(--green) 6%, var(--surface));
   color: var(--dark-green);
   font-size: 13px;
   font-weight: 600;
   line-height: 1;
   cursor: pointer;
   transition:
      background 0.18s ease,
      border-color 0.18s ease,
      transform 0.12s ease;
}
.preview-help-btn:hover {
   background: color-mix(in srgb, var(--green) 12%, var(--surface));
   border-color: color-mix(in srgb, var(--green) 40%, var(--line));
}
.preview-help-btn:active {
   transform: translateY(1px);
}
.preview-help-icon {
   display: grid;
   place-items: center;
   width: 18px;
   height: 18px;
   border-radius: 50%;
   background: var(--green);
   color: #fff;
   font-size: 12px;
   font-weight: 800;
   line-height: 1;
}
html[data-theme="dark"] .preview-help-btn {
   color: #cdeede;
}

/* How-to dialog: reuses .confirm-dialog chrome but is wider and left-aligns a
   scrollable list of editing tips. Selectors are scoped under #howToDialog to
   win over the base .confirm-dialog-card rules regardless of source order. */
#howToDialog .howto-dialog-card {
   width: min(480px, 100%);
   max-height: min(80vh, 640px);
   text-align: left;
   align-items: stretch;
}
#howToDialog .confirm-dialog-icon {
   align-self: center;
}
#howToDialog .confirm-dialog-title,
#howToDialog .confirm-dialog-desc {
   text-align: center;
}
.howto-list {
   list-style: none;
   margin: 6px 0 4px;
   padding: 0;
   display: flex;
   flex-direction: column;
   gap: 12px;
   overflow-y: auto;
   width: 100%;
}
.howto-item {
   display: flex;
   align-items: flex-start;
   gap: 12px;
   font-size: 14px;
   line-height: 1.45;
   color: var(--ink);
}
.howto-item-icon {
   flex: 0 0 auto;
   display: grid;
   place-items: center;
   width: 30px;
   height: 30px;
   border-radius: 9px;
   background: color-mix(in srgb, var(--green) 12%, transparent);
   font-size: 15px;
   line-height: 1;
}
.howto-item-text {
   flex: 1 1 auto;
   padding-top: 3px;
}
.howto-item-text strong {
   font-weight: 700;
   color: var(--ink);
}
.howto-item-text code {
   font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
   font-size: 12.5px;
   padding: 1px 5px;
   border-radius: 5px;
   background: color-mix(in srgb, var(--green) 10%, var(--surface));
   color: var(--dark-green);
}
html[data-theme="dark"] .howto-item-text code {
   color: #cdeede;
}

/* Accessible focus treatment */
:where(button, input, select, [tabindex]):focus-visible {
   outline: 3px solid rgba(184, 232, 92, 0.7);
   outline-offset: 2px;
}
.toast {
   /* Must sit above the My Songs home overlay (.cloud-modal, z-index 130) and
      the device hint (160) so copy/save feedback is visible on every screen —
      including when triggered from a card action inside the gallery. */
   z-index: 200;
   border: 1px solid rgba(255, 255, 255, 0.12);
   box-shadow: 0 12px 35px rgba(15, 45, 30, 0.23);
}

/* Desktop-recommendation hint. Rendered on small/touch devices only (JS gates
   it with prefersTap()). Shown on every load/refresh — no persistence. Centered
   modal card over a blurred backdrop. Purely informational — dismiss to use the
   app. */
.device-hint {
   position: fixed;
   inset: 0;
   /* Must sit above every full-screen surface — the login page (140) and the My
      Songs home overlay (130) — so the hint is visible no matter which screen
      the phone user refreshes on. */
   z-index: 160;
   display: grid;
   place-items: center;
   padding: 24px;
   background: rgba(12, 28, 20, 0.42);
   -webkit-backdrop-filter: blur(8px);
   backdrop-filter: blur(8px);
   opacity: 0;
   transition: opacity 0.28s ease;
}
/* When hidden, fully remove it from the layout so its full-screen backdrop can
   never trap clicks — a bare `.device-hint{display:grid}` outranks the built-in
   [hidden] rule, leaving an invisible click-blocking overlay behind. */
.device-hint[hidden] {
   display: none;
}
.device-hint.is-open {
   opacity: 1;
}
.device-hint-card {
   width: min(360px, 100%);
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 12px;
   padding: 26px 24px 22px;
   text-align: center;
   border: 1px solid var(--line);
   border-radius: var(--radius-lg);
   background: var(--surface);
   box-shadow: var(--shadow-md);
   transform: translateY(12px) scale(0.98);
   transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.device-hint.is-open .device-hint-card {
   transform: translateY(0) scale(1);
}
.device-hint-icon {
   flex: 0 0 auto;
   font-size: 40px;
   line-height: 1;
}
.device-hint-copy {
   min-width: 0;
}
.device-hint-copy strong {
   display: block;
   font-size: 17px;
   font-weight: 700;
   color: var(--ink);
}
.device-hint-copy p {
   margin: 6px 0 0;
   font-size: 13px;
   line-height: 1.45;
   color: var(--muted);
}
.device-hint-close {
   flex: 0 0 auto;
   width: 100%;
   min-height: 44px;
   margin-top: 4px;
   padding: 0 16px;
   border: 0;
   border-radius: 999px;
   background: var(--green, #1f7a4d);
   color: #fff;
   font-size: 14px;
   font-weight: 700;
   cursor: pointer;
   transition: filter 0.15s ease;
}
.device-hint-close:hover {
   filter: brightness(1.06);
}
.device-hint-close:focus-visible {
   outline: 2px solid var(--green, #1f7a4d);
   outline-offset: 2px;
}

/* Themed confirm dialog — a drop-in replacement for window.confirm(). Sits above
   every full-screen surface (login 140, home 130) so it's usable from any
   screen. Backdrop click, Cancel and Escape all resolve as "cancelled". */
.confirm-dialog {
   position: fixed;
   inset: 0;
   z-index: 170;
   display: grid;
   place-items: center;
   padding: 24px;
   opacity: 0;
   transition: opacity 0.24s ease;
}
.confirm-dialog[hidden] {
   display: none;
}
.confirm-dialog.is-open {
   opacity: 1;
}
.confirm-dialog-backdrop {
   position: absolute;
   inset: 0;
   background: rgba(12, 28, 20, 0.44);
   -webkit-backdrop-filter: blur(8px);
   backdrop-filter: blur(8px);
}
.confirm-dialog-card {
   position: relative;
   z-index: 1;
   width: min(400px, 100%);
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 10px;
   padding: 28px 26px 22px;
   text-align: center;
   border: 1px solid var(--line);
   border-radius: var(--radius-lg);
   background: var(--surface);
   box-shadow: var(--shadow-md);
   transform: translateY(12px) scale(0.98);
   transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.confirm-dialog.is-open .confirm-dialog-card {
   transform: translateY(0) scale(1);
}
.confirm-dialog-icon {
   display: grid;
   place-items: center;
   width: 48px;
   height: 48px;
   border-radius: 50%;
   background: color-mix(in srgb, var(--green) 14%, transparent);
   color: var(--dark-green);
   font-size: 26px;
   line-height: 1;
}
/* In dark theme the deep --dark-green sits too close to the dark card bg, so
   brighten the glyph (use --green) and strengthen the pill background. */
html[data-theme="dark"] .confirm-dialog-icon {
   color: var(--green);
   background: color-mix(in srgb, var(--green) 24%, transparent);
}
.confirm-dialog-title {
   margin: 4px 0 0;
   font-size: 19px;
   font-weight: 700;
   letter-spacing: -0.01em;
   color: var(--ink);
}
.confirm-dialog-desc {
   margin: 0;
   font-size: 13.5px;
   line-height: 1.5;
   color: var(--muted);
}
/* Free-text field for the Attach Link dialog (paste a share link/payload). */
.attach-link-input {
   width: 100%;
   margin-top: 12px;
   padding: 10px 12px;
   font-size: 13px;
   font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
   line-height: 1.4;
   color: var(--ink);
   background: var(--surface);
   border: 1px solid var(--line);
   border-radius: 10px;
   resize: vertical;
   min-height: 68px;
   box-sizing: border-box;
   word-break: break-all;
}
.attach-link-input:focus-visible {
   outline: none;
   border-color: var(--green);
   box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 22%, transparent);
}
.confirm-dialog-actions {
   display: flex;
   gap: 10px;
   width: 100%;
   margin-top: 14px;
}
.confirm-dialog-actions .button {
   flex: 1 1 0;
   justify-content: center;
   min-height: 44px;
}
/* Destructive confirm (e.g. Sign out) reads red rather than the brand green. */
.confirm-dialog-actions .button.is-danger {
   background: #b42318;
   border-color: #b42318;
   color: #fff;
}
.confirm-dialog-actions .button.is-danger:hover {
   filter: brightness(1.06);
}
/* Three-choice dialogs (e.g. unsaved changes) stack full-width buttons so the
   labels never truncate and the recommended primary action reads first. */
.confirm-dialog-actions.confirm-dialog-actions-stacked {
   flex-direction: column;
   width: 100%;
   gap: 8px;
}
.confirm-dialog-actions.confirm-dialog-actions-stacked .button {
   flex: none;
   width: 100%;
}

/* Site footer */
.site-footer {
   border-top: 1px solid rgba(201, 219, 206, 0.9);
   background: linear-gradient(180deg, rgba(255, 255, 255, 0.5), rgba(235, 244, 237, 0.92));
}
.site-footer-inner {
   width: 100%;
   max-width: 1560px;
   min-height: 112px;
   margin: 0 auto;
   padding: 24px clamp(20px, 4vw, 64px);
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 28px;
}
.footer-identity {
   min-width: 0;
   display: flex;
   align-items: center;
   gap: 12px;
}
.footer-mark {
   width: 38px;
   height: 38px;
   flex: 0 0 auto;
   overflow: hidden;
   border-radius: 12px;
   box-shadow: 0 7px 16px rgba(35, 122, 80, 0.16);
}
.footer-mark img {
   display: block;
   width: 100%;
   height: 100%;
}
.footer-identity strong {
   display: block;
   margin-bottom: 4px;
   color: var(--ink);
   font-size: 14px;
   letter-spacing: -0.2px;
}
.footer-identity p {
   margin: 0;
   color: var(--muted);
   font-size: 11px;
   line-height: 1.5;
}
.footer-identity p b {
   color: var(--dark-green);
   font-weight: 800;
}
.footer-meta {
   display: flex;
   align-items: center;
   justify-content: flex-end;
   gap: 12px;
   color: var(--muted);
   font-size: 10px;
   text-align: right;
}
.open-source-badge {
   min-height: 32px;
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 6px 10px;
   border: 1px solid #cfe3d4;
   border-radius: 999px;
   background: rgba(255, 255, 255, 0.72);
   color: var(--dark-green);
   font-weight: 800;
   white-space: nowrap;
}
.open-source-badge i {
   width: 7px;
   height: 7px;
   border-radius: 50%;
   background: var(--lime);
   box-shadow: 0 0 0 3px rgba(184, 232, 92, 0.2);
}

@media (max-width: 980px) {
   .autosave-status {
      display: none;
   }
   main {
      padding-right: 22px;
      padding-left: 22px;
   }
   .ribbon-workspace .editor-card {
      top: 0;
   }
   .ribbon-workspace .preview-card {
      min-width: 820px;
   }
   .preview-viewport {
      padding: 22px;
   }
}

@media (max-width: 680px) {
   html {
      scroll-behavior: auto;
   }
   body {
      overflow-x: hidden;
   }
   .topbar {
      position: relative;
      height: auto;
      min-height: 0;
      flex-wrap: wrap;
      gap: 10px;
      padding: 11px 12px 12px;
   }
   .brand {
      min-width: 0;
      gap: 9px;
      font-size: 16px;
      letter-spacing: -0.35px;
   }
   .brand > span:last-child {
      min-width: 0;
      white-space: nowrap;
   }
   .brand small {
      display: block;
      overflow: hidden;
      font-size: 7px;
      letter-spacing: 0.08em;
      text-overflow: ellipsis;
   }
   .brand-icon {
      width: 34px;
      height: 34px;
   }
   .topbar-actions {
      display: grid;
      width: 100%;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 6px;
   }
   /* Editor header on small screens: Back stays a compact button and the
      breadcrumb takes the remaining width (it truncates rather than wraps). */
   .topbar-nav {
      width: 100%;
      gap: 10px;
   }
   .editor-breadcrumb {
      flex: 1 1 auto;
      padding-left: 10px;
   }
   .editor-breadcrumb-title {
      max-width: none;
      font-size: 13px;
   }
   .topbar-actions .button,
   .topbar-actions .button-ghost,
   .topbar-actions .upload-project {
      min-width: 0;
      min-height: 42px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: 8px 7px;
      font-size: 10px;
      white-space: nowrap;
   }
   .topbar-actions .button span[aria-hidden="true"],
   .topbar-actions .upload-project span[aria-hidden="true"] {
      margin-right: 4px;
      font-size: 14px;
   }
   main {
      padding: 22px 14px 54px;
   }
   .intro {
      margin-bottom: 18px;
   }
   .intro h1 {
      font-size: 26px;
      letter-spacing: -1px;
   }
   .intro p {
      max-width: 100%;
      line-height: 1.5;
   }
   .ribbon-workspace .editor-card {
      position: sticky;
      top: 0;
      z-index: 30;
      margin-bottom: 16px;
      padding: 9px 10px 10px;
      border-radius: 14px;
   }
   .ribbon-heading {
      min-height: 34px;
      padding-bottom: 6px;
   }
   .ribbon-heading > div {
      display: grid;
      gap: 1px;
   }
   .ribbon-toggle {
      width: 40px;
      height: 40px;
   }
   .ribbon-tabs {
      margin: 0 -2px;
      overflow-x: hidden;
   }
   .ribbon-tab {
      min-width: 0;
      min-height: 44px;
      flex: 1 1 0;
      padding: 8px 3px 9px;
      font-size: 10px;
      line-height: 1.1;
      white-space: normal;
   }
   .ribbon-panels {
      min-height: 0;
      max-height: 46vh;
      margin: 0;
      padding-top: 9px;
      overflow: auto;
      overscroll-behavior: contain;
      scrollbar-width: thin;
   }
   .ribbon-panel.active {
      display: grid;
      width: 100%;
      min-width: 0;
      gap: 10px;
   }
   .ribbon-panel .palette-group {
      width: 100%;
      min-width: 0;
   }
   .ribbon-panel .palette-divider {
      width: 100%;
      height: 1px;
      min-height: 1px;
      margin: 0;
   }
   .ribbon-panel .palette-divider span {
      top: -1px;
      left: 0;
      width: 36px;
      height: 3px;
   }
   .ribbon-panel .chord-root-picker {
      grid-template-columns: repeat(6, minmax(42px, 1fr));
      gap: 6px;
   }
   .ribbon-panel .chord-root-picker .key {
      width: 100%;
      height: 42px;
   }
   .chord,
   .duration-option {
      min-height: 42px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
   }
   .custom-chord-entry {
      grid-template-columns: minmax(0, 1fr);
   }
   .custom-chord-entry .text-input {
      min-height: 42px;
      font-size: 16px;
   }
   .custom-chord-preview {
      min-height: 42px;
   }
   .ribbon-panel .slash-builder {
      display: grid;
      width: 100%;
      min-width: 0;
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: auto;
      gap: 9px;
   }
   .ribbon-panel .slash-builder .palette-label,
   .ribbon-panel .slash-fields,
   .ribbon-panel .add-slash,
   .ribbon-panel .slash-chord-bank {
      grid-column: 1;
      width: 100%;
      margin: 0;
   }
   .slash-fields .select-input {
      min-height: 44px;
      font-size: 16px;
   }
   .ribbon-panel .add-slash {
      min-height: 42px;
   }
   .ribbon-panel .nashville-builder {
      display: grid;
      width: 100%;
      min-width: 0;
      grid-template-columns: minmax(0, 1fr);
      gap: 12px;
   }
   .nashville-panel-divider {
      width: 100%;
      height: 1px;
   }
   .ribbon-panel .nashville-number-row {
      grid-template-columns: repeat(7, minmax(38px, 1fr));
      gap: 5px;
   }
   .ribbon-panel .nashville-number-row.nashville-zero-row {
      grid-template-columns: minmax(42px, 72px);
   }
   .nashville-row-block {
      grid-template-columns: minmax(0, 1fr);
      gap: 6px;
   }
   .nashville-row-label {
      white-space: normal;
   }
   .ribbon-panel .nashville-number-row {
      width: 100%;
      grid-template-columns: repeat(7, minmax(0, 1fr));
   }
   .nashville-key {
      width: 100%;
   }
   .nashville-key,
   .nashville-accidental {
      min-height: 42px;
   }
   .nashville-selected-card {
      min-width: 0;
      min-height: 64px;
   }
   .lyrics-settings {
      min-width: 0 !important;
      align-items: flex-start;
      flex-direction: column;
      gap: 13px;
   }
   .switch-control {
      min-height: 44px;
   }
   .lyrics-shortcuts {
      flex-wrap: wrap;
      gap: 8px 12px;
      padding: 0 2px;
      white-space: normal;
   }
   .auto-syllable-actions {
      flex-direction: column;
      align-items: stretch;
   }
   .auto-syllable-actions .button {
      width: 100%;
      min-height: 44px;
   }
   .preview-stage {
      border-radius: 16px;
   }
   .preview-stage {
      margin-right: -8px;
      margin-left: -8px;
      border-radius: 14px;
   }
   .preview-viewport {
      padding: 0;
      overflow-x: hidden;
      overscroll-behavior-x: contain;
   }
   .ribbon-workspace .preview-card {
      width: 100%;
      min-width: 0;
      min-height: 540px;
      border: 0;
      border-radius: 0;
      padding: 20px 12px;
      box-shadow: none;
   }
   .preview-header {
      flex-direction: column;
      gap: 16px;
   }
   .preview-header h2 {
      font-size: 25px;
      overflow-wrap: anywhere;
   }
   .song-meta {
      flex-wrap: wrap;
      gap: 14px 20px;
      text-align: left;
   }
   .song-meta > span {
      min-width: 72px;
   }
   .transpose-control {
      align-items: flex-start;
   }
   .transpose-buttons button {
      width: 44px;
      height: 44px;
   }
   .preview-rule {
      margin: 20px 0 22px;
   }
   .section-preview-heading {
      align-items: flex-start;
      flex-direction: column;
      gap: 8px;
   }
   .section-tools {
      width: 100%;
      align-items: center;
      flex-direction: row;
      flex-wrap: wrap;
      gap: 5px;
      padding: 5px;
   }
   .section-lyrics-toggle,
   .section-chord-above-toggle,
   .text-button,
   .section-menu summary {
      min-height: 40px;
   }
   .section-menu summary {
      width: 40px;
   }
   .section-menu-popover {
      right: auto;
      left: 0;
      width: 170px;
   }
   .bar-grid {
      width: 100%;
      overflow: visible;
   }
   .bar-batch,
   .bar-batch.has-lyrics {
      display: grid;
      width: 100%;
      min-width: 0;
      grid-template-columns: minmax(0, 1fr);
      margin: 12px 0;
      padding: 0;
      border-bottom: 0;
   }
   .bar-batch .bar,
   .bar-batch.has-lyrics .bar.has-lyrics {
      position: relative;
      width: 100%;
      min-width: 0;
      min-height: 72px;
      padding: 14px 52px 14px 10px;
      border-bottom: 1px solid #c9d6cb;
   }
   .bar-batch .bar:last-child {
      border-bottom: 0;
   }
   .scroll-affordance span {
      display: none;
   }
   .section-tools {
      opacity: 1 !important;
      transform: none !important;
   }
   /* Keep delete-bar centered; sticky :hover from long-press must not re-anchor it. */
   .delete-bar,
   .bar:hover .delete-bar,
   .bar:focus-within .delete-bar,
   .delete-bar:hover,
   .delete-bar:active {
      top: 50%;
      right: 5px;
      width: 40px;
      height: 40px;
      opacity: 1;
      transform: translateY(-50%);
      transition: background 0.15s ease;
   }
   .delete-bar:active {
      background: #ffe6e3;
   }
   /* Keep a large touch target, but draw thin beams higher above the notes. */
   .duration-line {
      top: -32px;
      height: 38px;
      background: transparent !important;
      box-shadow: none !important;
   }
   .duration-line::before {
      top: 8px;
      height: 1.5px;
      border-radius: 1px;
   }
   .duration-quarter .duration-line::after {
      top: 13px;
      height: 1.5px;
      border-radius: 1px;
   }
   .nested-duration-line {
      top: 8px;
      height: 28px;
      background: transparent !important;
      box-shadow: none !important;
   }
   .nested-duration-line::before {
      content: "";
      display: block;
      top: 4px;
      height: 1.5px;
      border-radius: 1px;
      background: var(--dark-green);
   }
   /* Keep high-octave Nashville dots below nested/primary beams on touch layouts. */
   .placed-chord .nashville-octave-high .nashville-octave-dot,
   .placed-chord .nashville-octave-low .nashville-octave-dot {
      z-index: 2;
      color: currentColor;
      font-size: 0.74em;
      font-weight: 800;
      line-height: 1;
      text-shadow:
         0.2px 0 0 currentColor,
         -0.2px 0 0 currentColor;
   }
   .placed-chord .nashville-octave-high .nashville-octave-dot {
      top: 0.18em;
      bottom: auto;
      transform: translate(-50%, -100%);
   }
   /* Low-octave dots: slight lift only from original under-number position. */
   .placed-chord .nashville-octave-low .nashville-octave-dot {
      top: calc(100% - 2px);
      bottom: auto;
      transform: translateX(-50%);
   }
   .beat-column,
   .notation-cell,
   .beat-group,
   .nested-beat-group,
   .bar {
      overflow: visible;
   }
   .placed-chord {
      touch-action: manipulation;
   }
   .preview-footer {
      align-items: stretch;
      flex-direction: column;
   }
   .preview-actions {
      display: grid;
      width: 100%;
      grid-template-columns: 1fr 1fr;
   }
   .preview-actions .button,
   .preview-actions .button-ghost {
      min-height: 44px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
   }
   .toast {
      bottom: max(16px, env(safe-area-inset-bottom));
      width: calc(100% - 28px);
      max-width: 420px;
      text-align: center;
   }
   .site-footer-inner {
      min-height: 0;
      padding: 22px 16px calc(22px + env(safe-area-inset-bottom));
      align-items: flex-start;
      flex-direction: column;
      gap: 16px;
   }
   .footer-identity {
      align-items: flex-start;
   }
   .footer-identity p {
      max-width: 260px;
   }
   .footer-meta {
      width: 100%;
      align-items: flex-start;
      justify-content: flex-start;
      flex-direction: column;
      gap: 8px;
      text-align: left;
   }
}

@media (max-width: 340px) {
   .bar.has-lyrics .beat-column:not(.duration-column),
   .bar.has-lyrics .sub-beat {
      width: 44px;
      min-width: 44px;
   }
   .bar.has-lyrics .sub-lyrics {
      grid-template-columns: repeat(var(--lyric-leaves), 44px);
   }
   .bar.has-lyrics .sub-lyrics .lyric-editor {
      width: 38px;
   }
}

@media print {
   html,
   body {
      background: #fff !important;
   }
   .scroll-affordance,
   .site-footer,
   .pdf-options-modal,
   .toast {
      display: none !important;
   }
   .preview-stage {
      display: contents;
      border: 0;
      background: transparent;
      box-shadow: none;
   }
   .preview-viewport {
      display: block;
      overflow: visible;
      padding: 0;
   }
   .ribbon-workspace .preview-card {
      min-width: 0;
      margin: 0;
      border: 0 !important;
      border-radius: 0 !important;
      background: #fff;
      box-shadow: none !important;
      padding: 0 !important;
      zoom: 1 !important;
   }
   .preview-section .section-tools,
   .delete-bar,
   .section-menu {
      display: none !important;
   }
   .bar-tools {
      opacity: 0 !important;
      pointer-events: none !important;
      visibility: hidden !important;
   }
   .pdf-signature {
      position: fixed !important;
      right: 9mm;
      bottom: 3mm !important;
      left: 9mm;
      margin: 0 !important;
      display: block !important;
      color: #7b8b81;
      font:
         600 10.5px/1 Inter,
         ui-sans-serif,
         sans-serif;
      letter-spacing: 0.04em;
      text-align: center;
   }
}

/* Deep Forest dark theme. The printable score remains light via the print rules below. */
html[data-theme="dark"] {
   --ink: #f1f4f2;
   --muted: #9ca69f;
   --green: #55b982;
   --dark-green: #327a52;
   --lime: #b8e85c;
   --cream: #121412;
   --surface: #161816;
   --line: #303531;
   --soft: #1d211e;
   --app-bg: #0a0a0a;
   --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2), 0 7px 24px rgba(0, 0, 0, 0.22);
   --shadow-md: 0 18px 55px rgba(0, 0, 0, 0.38);
}
html[data-theme="dark"] body {
   background: radial-gradient(circle at 8% 4%, rgba(85, 185, 130, 0.055), transparent 25rem), var(--app-bg);
}
html[data-theme="dark"] .topbar {
   border-color: rgba(48, 53, 49, 0.92);
   background: rgba(16, 17, 16, 0.96);
   box-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
}
html[data-theme="dark"] .brand small,
html[data-theme="dark"] .palette-label,
html[data-theme="dark"] .nashville-row-label,
html[data-theme="dark"] .preview-footer {
   color: var(--muted);
}
html[data-theme="dark"] .button-ghost,
html[data-theme="dark"] .icon-button {
   border-color: var(--line);
   background: var(--surface);
   color: var(--ink);
}
html[data-theme="dark"] .button-ghost:hover,
html[data-theme="dark"] .icon-button:hover {
   border-color: #465049;
   background: var(--soft);
}
html[data-theme="dark"] .icon-button:disabled {
   border-color: #292d2a;
   background: #131513;
   color: #666d68;
}
html[data-theme="dark"] .button-primary {
   color: #08130d;
}
html[data-theme="dark"] .button-primary:hover {
   background: #6dcc98;
}
html[data-theme="dark"] .ribbon-workspace .editor-card {
   border-color: var(--line);
   background: rgba(22, 24, 22, 0.98);
}
html[data-theme="dark"] .ribbon-tab:hover,
html[data-theme="dark"] .ribbon-tab.active,
html[data-theme="dark"] .section-title:hover,
html[data-theme="dark"] .text-button:hover,
html[data-theme="dark"] .section-menu summary:hover,
html[data-theme="dark"] .section-menu[open] summary {
   background: var(--soft);
   color: var(--ink);
}
html[data-theme="dark"] .ribbon-panel .palette-group,
html[data-theme="dark"] .palette-group,
html[data-theme="dark"] .nashville-selected-card {
   border-color: var(--line);
   background: #151715;
}
html[data-theme="dark"] .text-input,
html[data-theme="dark"] .select-input,
html[data-theme="dark"] .lyrics-input,
html[data-theme="dark"] .preview-inline-input,
html[data-theme="dark"] .section-title-input,
html[data-theme="dark"] .chord-root-picker .key,
html[data-theme="dark"] .nashville-key,
html[data-theme="dark"] .nashville-accidental {
   border-color: var(--line);
   background: #101110;
   color: var(--ink);
}
html[data-theme="dark"] .auto-syllable-input {
   border-color: var(--line);
   background: #101110;
   color: var(--ink);
}
html[data-theme="dark"] .chord-root-picker .key:hover,
html[data-theme="dark"] .nashville-key:hover,
html[data-theme="dark"] .nashville-accidental:hover {
   border-color: #55b982;
   background: #1d211e;
   color: #f1f4f2;
}
html[data-theme="dark"] .chord-root-picker .key.active,
html[data-theme="dark"] .nashville-key.active,
html[data-theme="dark"] .nashville-accidental.active {
   border-color: var(--green);
   background: var(--green);
   color: #08130d;
}
html[data-theme="dark"] .nashville-accidentals {
   border-color: var(--line);
   background: #0f100f;
}
html[data-theme="dark"] .nashville-panel-divider,
html[data-theme="dark"] .palette-divider {
   background: var(--line);
}
html[data-theme="dark"] .chord,
html[data-theme="dark"] .chord-family .chord,
html[data-theme="dark"] .nashville-chord,
html[data-theme="dark"] .slash-chord,
html[data-theme="dark"] .custom-chord,
html[data-theme="dark"] .duration-option {
   border-color: #3a403b;
   background: var(--soft) !important;
   color: var(--ink);
}
html[data-theme="dark"] .chord:hover,
html[data-theme="dark"] .duration-option:hover {
   border-color: var(--green);
   background: #252b26 !important;
   color: #f1f4f2;
}
html[data-theme="dark"] .chord.palette-selected,
html[data-theme="dark"] .duration-option.palette-selected {
   border-color: var(--green);
   background: #203b2b !important;
   box-shadow: 0 0 0 3px rgba(85, 185, 130, 0.16);
}
html[data-theme="dark"] .preview-stage {
   border: 0;
   background: transparent;
   box-shadow: none;
}
html[data-theme="dark"] .preview-viewport {
   scrollbar-color: #454b46 transparent;
}
html[data-theme="dark"] .preview-viewport::-webkit-scrollbar-thumb {
   border-color: #0d0e0d;
   background: #454b46;
}
html[data-theme="dark"] .ribbon-workspace .preview-card {
   border-color: var(--line);
   background: var(--cream);
   color: var(--ink);
}
html[data-theme="dark"] .preview-editable:hover {
   background: rgba(85, 185, 130, 0.12);
   box-shadow: 0 0 0 4px rgba(85, 185, 130, 0.12);
}
html[data-theme="dark"] .preview-section {
   border-bottom-color: var(--line);
}
html[data-theme="dark"] .preview-section.is-active .section-tools,
html[data-theme="dark"] .preview-section:hover .section-tools,
html[data-theme="dark"] .preview-section:focus-within .section-tools {
   border-color: var(--line);
   background: rgba(22, 24, 22, 0.94);
}
html[data-theme="dark"] .section-menu-popover {
   border-color: var(--line);
   background: var(--surface);
   box-shadow: 0 10px 28px rgba(0, 0, 0, 0.38);
}
html[data-theme="dark"] .delete-section,
html[data-theme="dark"] .delete-bar {
   color: #f07c76;
}
html[data-theme="dark"] .delete-section:hover,
html[data-theme="dark"] .delete-bar:hover {
   background: #3b2423;
}
html[data-theme="dark"] .delete-bar {
   border-color: #63403d;
   background: rgba(22, 24, 22, 0.96);
}
html[data-theme="dark"] .bar-batch {
   border-color: #3d433e;
}
html[data-theme="dark"] .bar {
   border-color: var(--ink);
}
html[data-theme="dark"] .beat-dot {
   color: #9fb0a6;
}
html[data-theme="dark"] .placed-chord,
html[data-theme="dark"] .sub-beat .placed-chord {
   background: #203b2b;
   color: #d9f5e3;
}
/* Color only the drawn marker lines — never the expanded touch hit-area. */
html[data-theme="dark"] .duration-line,
html[data-theme="dark"] .nested-duration-line {
   background: transparent !important;
   box-shadow: none !important;
}
html[data-theme="dark"] .duration-line::before,
html[data-theme="dark"] .duration-line::after,
html[data-theme="dark"] .nested-duration-line::before {
   background: var(--green);
}
html[data-theme="dark"] .lyric-input {
   border-color: #343a35;
   background: rgba(10, 10, 10, 0.82);
   color: var(--ink);
}
html[data-theme="dark"] .lyric-input:hover,
html[data-theme="dark"] .lyric-input:focus {
   background: #0a0a0a;
}
html[data-theme="dark"] .section-lyrics-toggle {
   border-color: var(--line);
   background: #151715;
   color: var(--muted);
}
html[data-theme="dark"] .section-chord-above-toggle {
   border-color: var(--line);
   background: #151715;
   color: var(--muted);
}
html[data-theme="dark"] .section-lyrics-toggle span {
   background: #303531;
}
html[data-theme="dark"] .section-chord-above-toggle span {
   background: #303531;
}
html[data-theme="dark"] .section-lyrics-toggle.active {
   border-color: #327a52;
   background: #1b3022;
   color: #6dcc98;
}
html[data-theme="dark"] .section-chord-above-toggle.active {
   border-color: #327a52;
   background: #1b3022;
   color: #6dcc98;
}
html[data-theme="dark"] .section-lyrics-toggle.active span {
   background: var(--green);
   color: #08130d;
}
html[data-theme="dark"] .section-chord-above-toggle.active span {
   background: var(--green);
   color: #08130d;
}
html[data-theme="dark"] .lyrics-shortcuts kbd {
   border-color: var(--line);
   background: #101110;
   color: var(--ink);
}
html[data-theme="dark"] .scroll-affordance {
   border-color: var(--line);
   background: rgba(22, 24, 22, 0.95);
}
html[data-theme="dark"] .site-footer {
   border-color: var(--line);
   background: linear-gradient(180deg, rgba(22, 24, 22, 0.4), rgba(10, 10, 10, 0.97));
}

@media print {
   html[data-theme="dark"] {
      --ink: #163a2a;
      --muted: #718078;
      --green: #237a50;
      --dark-green: #155c3c;
      --cream: #fcfbf5;
      --surface: #fff;
      --line: #d9e5dc;
      --soft: #eaf5ed;
      color-scheme: light !important;
   }
   html[data-theme="dark"] .preview-card {
      color: #173a28 !important;
   }
   html[data-theme="dark"] .placed-chord,
   html[data-theme="dark"] .sub-beat .placed-chord {
      background: #dff2e4 !important;
      color: #155c3c !important;
   }
   html[data-theme="dark"] .bar-batch {
      border-color: #c9d6cb !important;
   }
   html[data-theme="dark"] .bar {
      border-color: #173a28 !important;
   }
}

/* ============================================================================
   PDF OPTIONS MODAL
   ----------------------------------------------------------------------------
   Export-settings sheet. Adjusts the --print-* tokens live; hidden in print via
   the @media print rule above. Centred dialog on desktop, bottom sheet on phones.
   ============================================================================ */
.pdf-options-modal {
   position: fixed;
   inset: 0;
   z-index: 60;
   display: grid;
   place-items: center;
   padding: clamp(12px, 4vw, 32px);
}
.pdf-options-modal[hidden] {
   display: none;
}
.pdf-options-backdrop {
   position: absolute;
   inset: 0;
   background: rgba(16, 38, 27, 0.5);
   opacity: 0;
   transition: opacity 0.2s ease;
}
.pdf-options-modal.is-open .pdf-options-backdrop {
   opacity: 1;
}
.pdf-options-dialog {
   position: relative;
   display: flex;
   flex-direction: column;
   /* Wider + taller than a normal dialog on purpose: the left pane shows a whole
      physical page (A4/Letter portrait), so it needs real vertical room to stay
      readable. */
   width: min(1180px, 100%);
   max-height: min(94vh, 940px);
   overflow: hidden;
   border: 1px solid var(--line);
   border-radius: var(--radius-lg);
   background: var(--surface);
   box-shadow: var(--shadow-md);
   opacity: 0;
   transform: translateY(10px) scale(0.985);
   transition:
      opacity 0.2s ease,
      transform 0.2s ease;
}
.pdf-options-modal.is-open .pdf-options-dialog {
   opacity: 1;
   transform: translateY(0) scale(1);
}
@media (prefers-reduced-motion: reduce) {
   .pdf-options-backdrop,
   .pdf-options-dialog {
      transition: none;
   }
}

/* Header */
.pdf-options-head {
   flex: none;
   display: flex;
   align-items: flex-start;
   justify-content: space-between;
   gap: 14px;
   padding: 20px 20px 14px;
   border-bottom: 1px solid var(--line);
}
.pdf-options-kicker {
   display: block;
   margin-bottom: 3px;
   color: var(--green);
   font-size: 10px;
   font-weight: 800;
   letter-spacing: 1.1px;
}
.pdf-options-head h2 {
   margin: 0;
   font-size: 19px;
   letter-spacing: -0.4px;
   color: var(--ink);
}
.pdf-options-sub {
   margin: 6px 0 0;
   max-width: 34ch;
   color: var(--muted);
   font-size: 11.5px;
   line-height: 1.45;
}
.pdf-options-close {
   flex: none;
}

/* Body */
.pdf-options-body {
   flex: 1;
   min-height: 0;
   overflow-y: auto;
   padding: 16px 20px 18px;
   display: flex;
   flex-direction: column;
   gap: 14px;
}

/* Two-pane split: paper preview on the left, controls on the right */
.pdf-options-layout {
   flex: 1;
   min-height: 0;
   display: grid;
   grid-template-columns: minmax(0, 1fr) 372px;
}
.pdf-options-preview {
   display: flex;
   flex-direction: column;
   min-width: 0;
   min-height: 0;
   border-right: 1px solid var(--line);
   background: linear-gradient(180deg, #eef3ef, #e7ede8);
}
.pdf-preview-bar {
   flex: none;
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 10px;
   padding: 10px 16px;
   border-bottom: 1px solid var(--line);
   background: rgba(255, 255, 255, 0.6);
}
.pdf-preview-title {
   color: var(--muted);
   font-size: 10px;
   font-weight: 800;
   letter-spacing: 1px;
   text-transform: uppercase;
}
.pdf-preview-scale {
   padding: 2px 8px;
   border-radius: 999px;
   background: var(--soft);
   color: var(--green);
   font-size: 10.5px;
   font-weight: 800;
   font-variant-numeric: tabular-nums;
}
.pdf-preview-scroll {
   flex: 1;
   min-height: 0;
   overflow: auto;
   padding: 16px 12px;
   display: grid;
   /* `safe` centers only while the paper fits; when a multi-page paper is taller
      than the pane it falls back to start-alignment so the TOP stays reachable
      (plain `center` would push the top out of view and clip it). */
   place-content: safe center;
}
/* The real #previewCard is moved in here. To make this preview MATCH THE PRINTED
   PDF EXACTLY we reproduce true paper geometry:
     • the host is one physical page: --pdf-page-w × --pdf-page-h (mm, set by JS
       from the chosen paper size)
     • page margins come from --pdf-page-margin-* (mm, from the chosen margin
       preset) applied as padding, exactly like the real @page box
     • the card itself gets NO padding/min-width of its own, so its content box
       equals the real printable area (paper − margins)
   The whole page is then visually scaled with --pdf-preview-scale to fit the pane. */
.pdf-preview-paper {
   --pdf-preview-scale: 1;
   --pdf-page-w: 210mm;
   --pdf-page-h: 297mm;
   --pdf-page-count: 1;
   /* Margins are locked to the "narrow" preset (see PDF_MARGINS in pdfOptions.js);
      fitPreviewToPane() overrides these inline for the live preview. */
   --pdf-page-margin-top: 7mm;
   --pdf-page-margin-x: 7mm;
   --pdf-page-margin-bottom: 9mm;
   width: calc(var(--pdf-page-w) * var(--pdf-preview-scale));
   height: calc(var(--pdf-page-h) * var(--pdf-page-count, 1) * var(--pdf-preview-scale));
   margin: 0 auto;
   filter: drop-shadow(0 8px 22px rgba(20, 58, 41, 0.18));
}
.pdf-preview-page {
   position: relative;
   box-sizing: border-box;
   width: var(--pdf-page-w);
   /* --pdf-page-count pages tall, so multi-page songs are fully visible instead
      of being clipped at page 1. */
   height: calc(var(--pdf-page-h) * var(--pdf-page-count, 1));
   padding: var(--pdf-page-margin-top) var(--pdf-page-margin-x) var(--pdf-page-margin-bottom);
   transform: scale(var(--pdf-preview-scale));
   transform-origin: top left;
   background: #fff;
   /* outline, not border: a border would consume 2px of the printable width and
      make text wrap differently from the real PDF. */
   outline: 1px solid #dfe6e0;
}
/* Neutralise the editor card chrome so only the real print rules shape it. */
.pdf-preview-page > #previewCard {
   width: 100% !important;
   min-width: 0 !important;
   max-width: none !important;
   margin: 0 !important;
   padding: 0 !important;
   border: 0 !important;
   border-radius: 0 !important;
   background: #fff !important;
   box-shadow: none !important;
   zoom: 1 !important;
}
/* Read-only preview: this is the LIVE #previewCard node, so block ALL pointer
   interaction (clicks, drags, text-field focus, contenteditable edits) while it
   lives in the preview. It's a faithful PDF mock-up, not an editing surface. */
.pdf-preview-page > #previewCard {
   pointer-events: none !important;
   -webkit-user-select: none !important;
   user-select: none !important;
   cursor: default !important;
}
.pdf-preview-page > #previewCard * {
   pointer-events: none !important;
}
.pdf-preview-page > #previewCard input,
.pdf-preview-page > #previewCard textarea,
.pdf-preview-page > #previewCard button,
.pdf-preview-page > #previewCard [contenteditable] {
   pointer-events: none !important;
   -webkit-user-modify: read-only !important;
   user-select: none !important;
}
/* Signature footer is a REAL-PDF-only flourish. Hide it in the live preview so
   the pane shows only the actual score content (the generated PDF still keeps
   it via the @media print rules). */
.pdf-preview-page > #previewCard .pdf-signature {
   display: none !important;
}
.pdf-options-panel {
   display: flex;
   flex-direction: column;
   min-height: 0;
   min-width: 0;
}
.pdf-field {
   display: flex;
   flex-direction: column;
   gap: 8px;
}
.pdf-field-inline {
   flex-direction: row;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
   flex-wrap: wrap;
}
.pdf-field-label {
   display: flex;
   align-items: baseline;
   justify-content: space-between;
   gap: 10px;
   font-size: 12.5px;
   font-weight: 700;
   color: var(--ink);
}
.pdf-field-label small {
   font-weight: 500;
   font-size: 10.5px;
   color: var(--muted);
}
.pdf-field-divider {
   display: flex;
   align-items: center;
   gap: 10px;
   margin-top: 2px;
   color: var(--muted);
   font-size: 10px;
   font-weight: 800;
   letter-spacing: 1px;
   text-transform: uppercase;
}
.pdf-field-divider::after {
   content: "";
   flex: 1;
   height: 1px;
   background: var(--line);
}

/* Segmented choice buttons (presets, paper, margins) */
.pdf-choice-group {
   display: flex;
   gap: 6px;
   flex-wrap: wrap;
}
.pdf-choice {
   flex: 1 1 auto;
   min-width: 68px;
   min-height: 38px;
   padding: 0 12px;
   border: 1px solid var(--line);
   border-radius: 999px;
   background: var(--surface);
   color: var(--ink);
   font-size: 12.5px;
   font-weight: 700;
   cursor: pointer;
   transition:
      border-color 0.15s ease,
      background 0.15s ease,
      color 0.15s ease;
}
.pdf-choice:hover {
   border-color: var(--green);
   background: var(--soft);
}
.pdf-choice.is-active {
   border-color: var(--green);
   background: var(--green);
   color: #fff;
}
.pdf-choice:focus-visible {
   outline: 3px solid #d9efd6;
   outline-offset: 1px;
}

/* Sliders */
.pdf-slider-value {
   min-width: 52px;
   padding: 2px 7px;
   border-radius: 999px;
   background: var(--soft);
   color: var(--green);
   font-size: 11px;
   font-weight: 800;
   font-variant-numeric: tabular-nums;
   text-align: center;
}
.pdf-slider {
   -webkit-appearance: none;
   appearance: none;
   width: 100%;
   height: 22px;
   background: transparent;
   cursor: pointer;
}
.pdf-slider::-webkit-slider-runnable-track {
   height: 6px;
   border-radius: 999px;
   background: var(--soft);
}
.pdf-slider::-webkit-slider-thumb {
   -webkit-appearance: none;
   appearance: none;
   width: 20px;
   height: 20px;
   margin-top: -7px;
   border: 3px solid #fff;
   border-radius: 50%;
   background: var(--green);
   box-shadow: 0 1px 4px rgba(20, 58, 41, 0.28);
}
.pdf-slider::-moz-range-track {
   height: 6px;
   border-radius: 999px;
   background: var(--soft);
}
.pdf-slider::-moz-range-thumb {
   width: 16px;
   height: 16px;
   border: 3px solid #fff;
   border-radius: 50%;
   background: var(--green);
}
.pdf-slider:focus-visible {
   outline: none;
}
.pdf-slider:focus-visible::-webkit-slider-thumb {
   box-shadow: 0 0 0 4px #d9efd6;
}

/* Footer */
.pdf-options-foot {
   flex: none;
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 10px;
   padding: 14px 20px 18px;
   border-top: 1px solid var(--line);
}

/* Dark theme */
html[data-theme="dark"] .pdf-options-dialog {
   border-color: var(--line);
   background: #151715;
}
html[data-theme="dark"] .pdf-options-backdrop {
   background: rgba(4, 8, 6, 0.62);
}
html[data-theme="dark"] .pdf-choice {
   border-color: var(--line);
   background: #101110;
   color: var(--ink);
}
html[data-theme="dark"] .pdf-choice:hover {
   border-color: #55b982;
   background: #1d211e;
   color: #f1f4f2;
}
html[data-theme="dark"] .pdf-choice.is-active {
   border-color: var(--green);
   background: var(--green);
   color: #08130d;
}
html[data-theme="dark"] .pdf-slider::-webkit-slider-runnable-track,
html[data-theme="dark"] .pdf-slider::-moz-range-track {
   background: #23271f;
}
html[data-theme="dark"] .pdf-slider::-webkit-slider-thumb,
html[data-theme="dark"] .pdf-slider::-moz-range-thumb {
   border-color: #151715;
}
html[data-theme="dark"] .pdf-slider-value {
   background: #1d211e;
   color: #7fd3a4;
}
html[data-theme="dark"] .pdf-options-preview {
   border-color: var(--line);
   background: linear-gradient(180deg, #0e100e, #121412);
}
html[data-theme="dark"] .pdf-preview-bar {
   border-color: var(--line);
   background: rgba(255, 255, 255, 0.03);
}
html[data-theme="dark"] .pdf-preview-scale {
   background: #1d211e;
   color: #7fd3a4;
}

/* Tablets / small laptops: stack the preview above the controls */
@media (max-width: 900px) {
   .pdf-options-dialog {
      width: min(560px, 100%);
   }
   .pdf-options-layout {
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: minmax(140px, 34vh) minmax(0, 1fr);
   }
   .pdf-options-preview {
      border-right: 0;
      border-bottom: 1px solid var(--line);
   }
}

/* Phones: present as a bottom sheet with comfortable touch targets. The live
   PDF preview is HIDDEN here — on a phone there isn't room to render a full page
   usefully, so we show only the PDF options controls. The card is still adopted
   into the (hidden) host and restored on close, so nothing breaks. */
@media (max-width: 560px) {
   .pdf-options-modal {
      place-items: end stretch;
      padding: 0;
   }
   .pdf-options-dialog {
      width: 100%;
      max-height: 88vh;
      border-width: 1px 0 0;
      border-radius: var(--radius-lg) var(--radius-lg) 0 0;
      transform: translateY(16px);
   }
   .pdf-options-modal.is-open .pdf-options-dialog {
      transform: translateY(0);
   }
   /* Options-only layout: drop the preview row entirely. */
   .pdf-options-preview {
      display: none !important;
   }
   .pdf-options-layout {
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: minmax(0, 1fr);
   }
   .pdf-choice {
      min-height: 44px;
   }
   .pdf-field-inline {
      flex-direction: column;
      align-items: stretch;
   }
   .pdf-options-foot .button {
      min-height: 44px;
   }
   /* styles.css hides .button-ghost on phones to declutter the topbar; the
      modal's own actions must stay visible. */
   .pdf-options-foot .button-ghost {
      display: inline-flex !important;
      align-items: center;
      justify-content: center;
   }
}

/* ======================================================================
   CLOUD SYNC UI — login page + My Songs gallery.
   Reuses the theme tokens (var(--surface|ink|line|green|...)) so it tracks
   light/dark automatically. Centered-modal mechanics mirror .device-hint.
   ====================================================================== */

/* ---- Auth gate ----
   Before the first auth-state result is known we hide the app chrome to avoid a
   flash of the editor. `data-auth-gate` is set to "pending" inline in <head>,
   then to "login" or "app" once cloudUI routes. */
html[data-auth-gate="pending"] body > .topbar,
html[data-auth-gate="pending"] body > main,
html[data-auth-gate="login"] body > .topbar,
html[data-auth-gate="login"] body > main {
   visibility: hidden;
}
html[data-auth-gate="pending"] {
   background: var(--app-bg);
}

/* My Songs is a full-viewport screen laid over the editor, so the editor behind
   it must not contribute a scrollbar. Locking the page (rather than hiding the
   editor) keeps the editor's scroll position intact when we route back to it. */
html[data-screen="home"],
html[data-screen="home"] body {
   overflow: hidden;
}

/* ---- Login page (full-screen auth gate) ---- */
.login-page {
   position: fixed;
   inset: 0;
   z-index: 140;
   display: grid;
   grid-template-columns: 1.05fr 1fr;
   background: var(--app-bg);
   opacity: 0;
   transition: opacity 0.3s ease;
   /* Login-only green: deeper than the app's --green so white text on the panel
      and the filled buttons read with more contrast, but NOT as dark as the
      logo/brand gradient. Scoped to the login page (overrides the tokens locally)
      so the rest of the app is untouched. */
   --green: #1a6742;
   --dark-green: #145536;
}
.login-page[hidden] {
   display: none;
}
.login-page.is-open {
   opacity: 1;
}
/* Left brand panel */
.login-aside {
   position: relative;
   display: flex;
   align-items: center;
   justify-content: center;
   padding: 48px;
   color: #fff;
   background: linear-gradient(155deg, var(--green), var(--dark-green));
   overflow: hidden;
}
.login-aside::after {
   content: "";
   position: absolute;
   inset: 0;
   background:
      radial-gradient(circle at 18% 22%, rgba(255, 255, 255, 0.16), transparent 42%),
      radial-gradient(circle at 82% 78%, rgba(255, 255, 255, 0.12), transparent 46%);
   pointer-events: none;
}
.login-aside-inner {
   position: relative;
   max-width: 400px;
}
/* Reuse the My Songs brand lockup. The logo shows on its own — no tinted tile
   behind it — so it reads as a clean mark on the green panel. */
.login-aside-brand {
   margin-bottom: 30px;
}
/* Logo shows bare on the green panel — no tinted tile / blur behind it. */
.login-aside-brand .home-brand-icon {
   width: 46px;
   height: 46px;
   border-radius: 0;
   background: none;
   -webkit-backdrop-filter: none;
   backdrop-filter: none;
}
.login-aside-brand .home-brand-icon img {
   width: 46px;
   height: 46px;
}
.login-aside-brand .home-brand-text {
   color: #fff;
   font-size: 16px;
}
.login-aside-brand .home-brand-text small {
   color: rgba(255, 255, 255, 0.78);
}
.login-brand-icon {
   display: inline-grid;
   place-items: center;
   width: 60px;
   height: 60px;
   border-radius: 18px;
   background: rgba(255, 255, 255, 0.16);
   backdrop-filter: blur(4px);
   margin-bottom: 22px;
}
.login-brand-icon img {
   width: 34px;
   height: 34px;
}
.login-aside-title {
   margin: 0;
   font-size: clamp(26px, 2.6vw, 33px);
   font-weight: 800;
   letter-spacing: -0.02em;
   line-height: 1.16;
}
.login-aside-tag {
   margin: 14px 0 30px;
   font-size: 14.5px;
   line-height: 1.5;
   opacity: 0.88;
}
.login-aside-points {
   list-style: none;
   margin: 0;
   padding: 0;
   display: flex;
   flex-direction: column;
   gap: 14px;
}
.login-aside-points li {
   display: flex;
   align-items: center;
   gap: 12px;
   font-size: 14.5px;
   font-weight: 500;
   opacity: 0.95;
}
.login-aside-points li span {
   display: grid;
   place-items: center;
   width: 30px;
   height: 30px;
   border-radius: 9px;
   background: rgba(255, 255, 255, 0.16);
   font-size: 15px;
}
/* Right form panel */
.login-main {
   display: grid;
   place-items: center;
   padding: 40px 28px;
   overflow-y: auto;
}
.login-card {
   width: min(392px, 100%);
   display: flex;
   flex-direction: column;
   gap: 16px;
}
.login-card-head {
   text-align: center;
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 6px;
   margin-bottom: 4px;
}
/* Compact brand lockup at the top of the form. Only shows on narrow screens
   where the green brand panel is hidden — on wide layouts the panel already
   carries the brand, so we hide this to avoid repeating it. (Scoped under
   .login-card so it outranks the shared .home-brand display rule.) */
.login-card .login-card-brand {
   display: none;
   margin-bottom: 10px;
}
.login-card-brand .home-brand-icon {
   width: 40px;
   height: 40px;
}
.login-card-brand .home-brand-text {
   font-size: 15px;
}
.login-card-title {
   margin: 4px 0 0;
   font-size: 24px;
   font-weight: 800;
   letter-spacing: -0.01em;
   color: var(--ink);
}
.login-card-sub {
   margin: 0;
   font-size: 14px;
   color: var(--muted);
}

/* Shared modal backdrop (login + gallery). */
.cloud-modal {
   position: fixed;
   inset: 0;
   z-index: 130;
   display: grid;
   place-items: center;
   padding: 24px;
   background: rgba(12, 28, 20, 0.46);
   -webkit-backdrop-filter: blur(9px);
   backdrop-filter: blur(9px);
   opacity: 0;
   transition: opacity 0.28s ease;
}
.cloud-modal[hidden] {
   display: none;
}
.cloud-modal.is-open {
   opacity: 1;
}
.cloud-modal-card {
   position: relative;
   width: min(400px, 100%);
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 14px;
   padding: 34px 30px 30px;
   text-align: center;
   border: 1px solid var(--line);
   border-radius: var(--radius-lg);
   background: var(--surface);
   box-shadow: var(--shadow-md);
   transform: translateY(14px) scale(0.98);
   transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
.cloud-modal.is-open .cloud-modal-card {
   transform: translateY(0) scale(1);
}
.cloud-modal-close {
   position: absolute;
   top: 12px;
   right: 12px;
   width: 34px;
   height: 34px;
   display: grid;
   place-items: center;
   border: 1px solid transparent;
   border-radius: 50%;
   background: transparent;
   color: var(--muted);
   font-size: 15px;
   cursor: pointer;
   transition:
      background 0.16s ease,
      color 0.16s ease,
      border-color 0.16s ease;
}
.cloud-modal-close:hover {
   background: var(--soft);
   color: var(--ink);
   border-color: var(--line);
}
.cloud-modal-title {
   margin: 0;
   font-size: 20px;
   font-weight: 800;
   color: var(--ink);
   letter-spacing: -0.01em;
}
.cloud-modal-sub {
   margin: 0;
   font-size: 13px;
   color: var(--muted);
   max-width: 30ch;
}

/* ---- Login modal ---- */
.cloud-login-icon {
   width: 58px;
   height: 58px;
   display: grid;
   place-items: center;
   font-size: 30px;
   color: #fff;
   background: linear-gradient(140deg, var(--green), var(--dark-green));
   border-radius: 18px;
   box-shadow: 0 10px 24px rgba(35, 122, 80, 0.28);
}
.cloud-google-btn {
   width: 100%;
   min-height: 46px;
   margin-top: 4px;
   display: inline-flex;
   align-items: center;
   justify-content: center;
   gap: 10px;
   border: 1px solid var(--line);
   border-radius: 12px;
   background: var(--surface);
   color: var(--ink);
   font: 700 14px inherit;
   cursor: pointer;
   transition:
      transform 0.16s ease,
      box-shadow 0.16s ease,
      background 0.16s ease,
      border-color 0.16s ease;
}
.cloud-google-btn:hover {
   transform: translateY(-1px);
   border-color: #bfd7c6;
   box-shadow: var(--shadow-sm);
}
.cloud-google-mark {
   display: grid;
   place-items: center;
   width: 18px;
   height: 18px;
}
.cloud-divider {
   width: 100%;
   display: flex;
   align-items: center;
   gap: 12px;
   color: var(--muted);
   font-size: 11px;
   text-transform: uppercase;
   letter-spacing: 0.08em;
}
.cloud-divider::before,
.cloud-divider::after {
   content: "";
   flex: 1;
   height: 1px;
   background: var(--line);
}
.cloud-email-form {
   width: 100%;
   display: flex;
   flex-direction: column;
   gap: 12px;
}
.cloud-field {
   display: flex;
   flex-direction: column;
   gap: 5px;
   text-align: left;
}
.cloud-field span {
   font-size: 12px;
   font-weight: 700;
   color: var(--muted);
}
.cloud-field input {
   min-height: 42px;
   padding: 9px 12px;
   border: 1px solid var(--line);
   border-radius: 10px;
   background: var(--app-bg);
   color: var(--ink);
   font-size: 14px;
   transition:
      border-color 0.16s ease,
      box-shadow 0.16s ease;
}
.cloud-field input:focus-visible {
   outline: none;
   border-color: var(--green);
   box-shadow: 0 0 0 3px rgba(35, 122, 80, 0.16);
}
.cloud-auth-error {
   margin: 0;
   padding: 8px 10px;
   font-size: 12.5px;
   text-align: left;
   color: #b42318;
   background: rgba(180, 35, 24, 0.08);
   border: 1px solid rgba(180, 35, 24, 0.22);
   border-radius: 9px;
}
.cloud-auth-error[hidden] {
   display: none;
}
.cloud-auth-actions {
   display: flex;
   gap: 10px;
   margin-top: 2px;
}
.cloud-auth-actions .button {
   flex: 1;
   min-height: 44px;
   justify-content: center;
}
/* The "Sign in" button is a filled green button on the login page. Force white
   text in BOTH themes: the dark-theme `.button-primary{color:#08130d}` rule
   (near-black, for the app's lighter green) would otherwise win by specificity
   and leave near-black text on the login page's deep green — unreadable. */
.cloud-auth-primary,
html[data-theme="dark"] .cloud-auth-primary {
   color: #fff;
}

/* ---- Account button (topbar) ---- */
.account-button {
   display: inline-flex;
   align-items: center;
   gap: 6px;
}
.account-avatar {
   width: 20px;
   height: 20px;
   display: grid;
   place-items: center;
   border-radius: 50%;
   background: var(--soft);
   font-size: 12px;
   overflow: hidden;
}
.account-avatar img {
   width: 100%;
   height: 100%;
   object-fit: cover;
}
.account-button.is-authed .account-avatar {
   background: var(--green);
   color: #fff;
}

/* ---- Profile card (popover anchored under the account button) ---- */
.account-menu {
   position: relative;
}
.account-popover {
   position: absolute;
   top: calc(100% + 10px);
   right: 0;
   z-index: 40;
   width: 244px;
   padding: 8px;
   border: 1px solid var(--line);
   border-radius: 16px;
   background: var(--surface);
   box-shadow:
      0 2px 6px rgba(16, 40, 28, 0.06),
      0 22px 48px -18px rgba(16, 40, 28, 0.34);
   opacity: 0;
   transform: translateY(-6px) scale(0.98);
   transform-origin: top right;
   transition:
      opacity 0.16s ease,
      transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}
.account-popover[hidden] {
   display: none;
}
.account-popover.is-open {
   opacity: 1;
   transform: translateY(0) scale(1);
}
.account-popover-id {
   display: flex;
   align-items: center;
   gap: 10px;
   padding: 8px 8px 10px;
   min-width: 0;
}
.account-popover-avatar {
   flex: 0 0 auto;
   width: 34px;
   height: 34px;
   display: grid;
   place-items: center;
   border-radius: 50%;
   background: var(--green);
   color: #fff;
   font-size: 15px;
   font-weight: 700;
   overflow: hidden;
}
.account-popover-avatar img {
   width: 100%;
   height: 100%;
   object-fit: cover;
}
.account-popover-who {
   display: flex;
   flex-direction: column;
   min-width: 0;
}
.account-popover-who strong {
   font-size: 13.5px;
   font-weight: 700;
   color: var(--ink);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}
.account-popover-who small {
   font-size: 11.5px;
   color: var(--muted);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}
.account-popover-sep {
   height: 1px;
   margin: 2px 4px 6px;
   background: var(--line);
}
.account-popover-item {
   width: 100%;
   display: flex;
   align-items: center;
   gap: 9px;
   padding: 9px 10px;
   border: none;
   border-radius: 10px;
   background: transparent;
   color: var(--ink);
   font: inherit;
   font-size: 13px;
   font-weight: 600;
   text-align: left;
   cursor: pointer;
   transition:
      background 0.15s ease,
      color 0.15s ease;
}
.account-popover-item:hover,
.account-popover-item:focus-visible {
   background: var(--soft);
   outline: none;
}
.account-popover-item.is-signout {
   color: #b42318;
}
.account-popover-item.is-signout:hover,
.account-popover-item.is-signout:focus-visible {
   background: rgba(180, 35, 24, 0.1);
}
.account-popover-item[hidden] {
   display: none;
}

/* ---- Editor header: Back affordance + document breadcrumb ---- */
.topbar-nav {
   display: flex;
   align-items: center;
   gap: 12px;
   min-width: 0;
}
.editor-back {
   flex: 0 0 auto;
}
.editor-breadcrumb {
   display: flex;
   flex-direction: column;
   min-width: 0;
   padding-left: 12px;
   border-left: 1px solid var(--line);
   line-height: 1.25;
}
.editor-breadcrumb-label {
   font-size: 10px;
   font-weight: 600;
   text-transform: uppercase;
   letter-spacing: 0.07em;
   color: var(--muted);
}
.editor-breadcrumb-title {
   font-size: 14px;
   font-weight: 700;
   letter-spacing: -0.01em;
   color: var(--ink);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
   max-width: 34vw;
}
/* Help button in the topbar — high-visibility affordance so first-time users
   can always find the editing guide. Sits right after the breadcrumb. */
.topbar-help-btn {
   display: inline-flex;
   align-items: center;
   gap: 7px;
   flex: 0 0 auto;
   margin-left: 4px;
   padding: 7px 13px 7px 8px;
   border: 1.5px solid color-mix(in srgb, var(--green) 45%, var(--line));
   border-radius: 999px;
   background: color-mix(in srgb, var(--green) 8%, var(--surface));
   color: var(--dark-green);
   font-size: 13px;
   font-weight: 600;
   line-height: 1;
   cursor: pointer;
   transition:
      background 0.18s ease,
      border-color 0.18s ease,
      transform 0.12s ease,
      box-shadow 0.18s ease;
}
.topbar-help-btn:hover {
   background: var(--green);
   border-color: var(--green);
   color: #fff;
   transform: translateY(-1px);
   box-shadow: 0 4px 12px color-mix(in srgb, var(--green) 32%, transparent);
}
.topbar-help-btn:hover .topbar-help-icon {
   background: #fff;
   color: var(--green);
}
.topbar-help-btn:active {
   transform: translateY(0);
}
.topbar-help-icon {
   display: grid;
   place-items: center;
   width: 20px;
   height: 20px;
   border-radius: 50%;
   background: var(--green);
   color: #fff;
   font-size: 13px;
   font-weight: 800;
   line-height: 1;
   transition:
      background 0.18s ease,
      color 0.18s ease;
}
html[data-theme="dark"] .topbar-help-btn {
   color: #cdeede;
}
/* Contextual "Back to editor": only rendered when a document is already open. */
.gallery-resume[hidden] {
   display: none;
}

/* Keep cloud topbar buttons usable on phones (styles.css hides .button-ghost
   at <=560px). We re-show the ghost ones (Back, account) — Save to Cloud and
   Export .pdf are filled buttons now, so they're never hidden. */
@media (max-width: 560px) {
   #backToSongsBtn.button-ghost,
   #accountBtn.button-ghost {
      display: inline-flex !important;
      align-items: center;
      padding: 8px 10px;
   }
   /* Login page: collapse to a single column, hide the brand panel. */
   .login-page {
      grid-template-columns: 1fr;
   }
   .login-aside {
      display: none;
   }
   /* With the brand panel gone, surface a compact lockup above the form. */
   .login-card .login-card-brand {
      display: inline-flex;
   }
   .login-main {
      padding: 28px 20px;
   }
}

/* ======================= My Songs gallery ========================= */
.cloud-gallery {
   place-items: stretch;
   padding: 0;
   /* Pin the single grid cell to the viewport so a wide scrolling card grid
      inside can never stretch the shell (and header) past the screen. */
   grid-template-columns: minmax(0, 1fr);
   grid-template-rows: minmax(0, 1fr);
}
.cloud-gallery-shell {
   position: relative;
   width: 100%;
   max-width: 100%;
   min-width: 0;
   height: 100%;
   overflow: hidden;
   display: flex;
   flex-direction: column;
   background: var(--app-bg);
   transform: translateY(14px);
   opacity: 0;
   transition:
      transform 0.3s cubic-bezier(0.22, 1, 0.36, 1),
      opacity 0.28s ease;
}
.cloud-gallery.is-open .cloud-gallery-shell {
   transform: translateY(0);
   opacity: 1;
}
.cloud-gallery-head {
   flex: 0 0 auto;
   /* 3-column header: brand (left) · compact page title (center) · actions (right).
      The side columns share equal width (1fr) so the centered title stays
      optically centered in the header regardless of how wide each side is. */
   display: grid;
   grid-template-columns: 1fr auto 1fr;
   align-items: center;
   gap: 18px;
   padding: 18px clamp(20px, 4vw, 56px);
   border-bottom: 1px solid var(--line);
   background: var(--surface);
}
.cloud-gallery-heading {
   min-width: 0;
   justify-self: start;
}
.cloud-gallery-heading .cloud-modal-title {
   text-align: left;
}
.cloud-gallery-heading .cloud-modal-sub {
   text-align: left;
   max-width: none;
}
/* Brand lockup. This lives on My Songs because My Songs is the home screen;
   the editor is a sub-page and leads with a Back affordance instead. */
.home-brand {
   display: inline-flex;
   align-items: center;
   gap: 11px;
   min-width: 0;
}
.home-brand-icon {
   flex: 0 0 auto;
   display: grid;
   place-items: center;
   width: 36px;
   height: 36px;
   border-radius: 11px;
   background: var(--soft);
}
.home-brand-icon img {
   width: 22px;
   height: 22px;
}
.home-brand-text {
   display: flex;
   flex-direction: column;
   min-width: 0;
   font-size: 15.5px;
   font-weight: 700;
   letter-spacing: -0.01em;
   color: var(--ink);
   line-height: 1.2;
}
.home-brand-text small {
   font-size: 11px;
   font-weight: 500;
   color: var(--muted);
   letter-spacing: 0;
}
.cloud-gallery-actions {
   display: flex;
   align-items: center;
   justify-content: flex-end;
   justify-self: end;
   gap: 10px;
   flex-wrap: wrap;
}
/* Hero + search stack. The hero moved here from the editor: only the home
   screen gets to state what the product does. */
/* Compact, centered page title in the header's middle column (Option B). Short
   and functional — the user is already signed in, so no marketing tagline. */
.home-intro {
   margin: 0;
   padding: 0;
   text-align: center;
   justify-self: center;
   min-width: 0;
}
.home-intro h1 {
   margin: 0;
   font-size: clamp(15px, 1.6vw, 18px);
   font-weight: 700;
   letter-spacing: -0.01em;
   line-height: 1.2;
   color: var(--ink);
}
.home-intro p {
   margin: 3px 0 0;
   font-size: 12px;
   color: var(--muted);
}
/* Search bar stands on its own row between the hero and the list. */
.cloud-gallery-searchbar {
   flex: 0 0 auto;
   display: flex;
   flex-direction: column;
   align-items: center;
   padding: 14px clamp(20px, 4vw, 56px) 6px;
}
/* Live library count — now the standalone subtitle under the centered title. */
.library-count {
   font-weight: 600;
   color: var(--dark-green);
}
.cloud-search {
   position: relative;
   display: flex;
   align-items: center;
   width: min(560px, 100%);
}
.cloud-search-icon {
   position: absolute;
   left: 16px;
   color: var(--muted);
   font-size: 17px;
   pointer-events: none;
}
.cloud-search input {
   min-height: 48px;
   width: 100%;
   padding: 10px 16px 10px 42px;
   border: 1px solid var(--line);
   border-radius: 999px;
   background: var(--surface);
   color: var(--ink);
   font-size: 14.5px;
   box-shadow: var(--shadow-sm);
   transition:
      border-color 0.16s ease,
      box-shadow 0.16s ease;
}
.cloud-search input::placeholder {
   color: var(--muted);
}
.cloud-search input:focus-visible {
   outline: none;
   border-color: var(--green);
   box-shadow: 0 0 0 3px rgba(35, 122, 80, 0.16);
}
.cloud-gallery-close {
   position: static;
}

.cloud-gallery-body {
   position: relative;
   flex: 1 1 auto;
   min-height: 0;
   width: 100%;
   max-width: 100%;
   overflow: hidden; /* the scrolling grid lives INSIDE here, so it never pushes the shell wider than the viewport */
   display: flex;
   align-items: flex-start; /* pin the grid to the top so the gap below the search bar stays constant */
   justify-content: center;
}
/* Two-row grid that scrolls horizontally. Cards flow column-by-column (top card
   then bottom card of each column), and columns alternate a small vertical
   offset to create a zigzag wave. The grid is the scroll container, so it never
   pushes the shell (or header) wider than the viewport — fixing the drift bug. */
.cloud-cards {
   flex: 1 1 auto;
   min-width: 0; /* let the flex item shrink so overflow-x can scroll instead of stretching the shell */
   width: 100%;
   max-width: 100%;
   height: 100%;
   display: grid;
   grid-template-rows: repeat(2, min-content);
   grid-auto-flow: column;
   grid-auto-columns: max-content;
   gap: 14px 8px;
   align-content: center;
   justify-content: start;
   overflow-x: auto;
   overflow-y: hidden;
   /* Side padding = half the viewport minus half a card, so the FIRST and LAST
      columns can scroll all the way to the horizontal center (where they become
      sharp/active). Few cards still sit centered because the padding fills the
      sides evenly. `align-content:center` centers the card rows VERTICALLY in
      the body so they line up with the left/right nudge icons (which sit at the
      body's vertical midpoint); the symmetric top/bottom padding keeps a minimum
      inset from the search bar and shell edge on shorter windows. */
   padding: 28px max(16px, calc(50% - 105px));
   scrollbar-width: none; /* hide native scrollbar; nudge buttons + swipe drive it */
   -webkit-overflow-scrolling: touch;
   touch-action: pan-x pan-y;
   list-style: none;
   margin: 0;
}
.cloud-cards::-webkit-scrollbar {
   display: none;
}
.cloud-cards:focus-visible {
   outline: 2px solid var(--green);
   outline-offset: -4px;
   border-radius: var(--radius-lg);
}

/* Card. Cards sit in the grid; each column is nudged up or down (zigzag) via
   --shift, and cards near the scroll edges get blurred via --blur (set by JS).
   Hovering/focusing a card lifts it (via --lift) and reveals its actions +
   detail. Visual language: soft elevation + hairline instead of a hard frame. */
.song-card {
   --shift: 0px;
   --lift: 0px;
   position: relative;
   width: 214px;
   height: 252px;
   display: flex;
   flex-direction: column;
   padding: 20px 20px 16px;
   border: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
   border-radius: 22px;
   background: var(--surface);
   box-shadow:
      0 1px 2px rgba(16, 40, 28, 0.04),
      0 8px 24px -12px rgba(16, 40, 28, 0.16);
   cursor: pointer;
   transform: translateY(calc(var(--shift) + var(--lift))) scale(var(--scale, 1));
   filter: blur(var(--blur, 0px));
   transition:
      transform 0.45s cubic-bezier(0.22, 1, 0.36, 1),
      filter 0.3s ease,
      box-shadow 0.35s cubic-bezier(0.22, 1, 0.36, 1),
      border-color 0.3s ease;
   overflow: hidden;
}
/* Zigzag: columns alternate up / down. With 2 rows and column flow the cards
   come in pairs (col1 = cards 1&2, col2 = cards 3&4 …), so a period-4 pattern
   raises odd columns and lowers even columns. */
.song-card:nth-child(4n + 1),
.song-card:nth-child(4n + 2) {
   --shift: -20px;
}
.song-card:nth-child(4n + 3),
.song-card:nth-child(4n + 4) {
   --shift: 20px;
}
.song-card:hover,
.song-card:focus-visible {
   --lift: -6px;
   border-color: color-mix(in srgb, var(--green) 30%, transparent);
   box-shadow:
      0 2px 6px rgba(16, 40, 28, 0.06),
      0 20px 42px -18px rgba(16, 40, 28, 0.3);
   outline: none;
   z-index: 3;
}
/* Dimmed (blurred, off-center) cards are not interactive: they can't be
   clicked, hovered, or focused. Scroll them to the middle to activate them. */
.song-card.is-dim {
   pointer-events: none;
   cursor: default;
}
/* Subtle, minimalist accent: a soft tinted glow in the top-left corner instead
   of a loud full-width gradient bar. */
.song-card::before {
   content: "";
   position: absolute;
   top: -40%;
   left: -30%;
   width: 150px;
   height: 150px;
   border-radius: 50%;
   background: radial-gradient(circle, color-mix(in srgb, var(--lime) 30%, transparent), transparent 70%);
   opacity: 0.55;
   pointer-events: none;
}
/* Legacy hook kept harmless: JS no longer sets .is-active on this grid. */
.song-card.is-active {
   box-shadow: var(--shadow-md);
   border-color: var(--green);
   outline: none;
}
.song-card-mode-icon {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: 26px;
   height: 26px;
   border-radius: 50%;
   font-size: 14px;
   font-weight: 800;
   line-height: 1;
   flex: none;
   color: #fff;
   background: var(--green, #237a50);
   border: 2px solid #fff;
   box-shadow: 0 1px 4px rgba(0, 0, 0, 0.28);
}
.song-card-mode-icon.is-numbers {
   color: #fff;
   background: #4f46e5;
   border-color: #fff;
}
.song-card-title {
   margin: 4px 0 3px;
   font-size: 16.5px;
   font-weight: 700;
   letter-spacing: -0.01em;
   line-height: 1.3;
   color: var(--ink);
   display: -webkit-box;
   -webkit-line-clamp: 2;
   line-clamp: 2;
   -webkit-box-orient: vertical;
   overflow: hidden;
}
.song-card-creator {
   font-size: 12.5px;
   color: var(--muted);
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}
/* Bottom dock: the Key/Time chips sit at the lower-left, with the action row
   parked directly underneath them (invisible, so it costs no visual space).
   On hover the whole dock glides up by --dock-shift, which slides the chips
   upward and "opens" room for the actions that fade in below them. One
   transform on one element = GPU-composited and perfectly in sync. */
.song-card-dock {
   --dock-shift: 42px;
   margin-top: auto;
   /* Layout only reserves the chip row; the action row hangs below it. */
   margin-bottom: calc(-1 * var(--dock-shift));
   display: flex;
   flex-direction: column;
   align-items: flex-start;
   transform: translateY(0);
   transition: transform 0.42s cubic-bezier(0.22, 1, 0.36, 1);
   will-change: transform;
}
.song-card:hover .song-card-dock,
.song-card:focus-visible .song-card-dock,
.song-card:focus-within .song-card-dock {
   transform: translateY(calc(-1 * var(--dock-shift)));
}
.song-card-meta {
   display: flex;
   gap: 16px;
   flex-wrap: wrap;
}
/* Key / Time are the most scanned values on the card, so they carry weight
   through typography alone - no pill, no fill. The value is large, bold and
   full-contrast; the label above it stays small, quiet and uppercase. */
.song-card-chip {
   display: inline-flex;
   align-items: baseline;
   gap: 6px;
   font-size: 15px;
   font-weight: 700;
   letter-spacing: -0.01em;
   color: var(--ink);
}
.song-card-chip small {
   font-weight: 600;
   color: var(--muted);
   font-size: 9px;
   text-transform: uppercase;
   letter-spacing: 0.06em;
}
/* Section count + last-updated: hidden until the card is hovered/focused. It
   stays in the flow the whole time (only opacity/transform animate), so
   revealing it never reflows the card. */
.song-card-detail {
   margin-top: 6px;
   font-size: 11.5px;
   line-height: 1.4;
   color: var(--muted);
   opacity: 0;
   transform: translateY(-4px);
   overflow: hidden;
   display: -webkit-box;
   -webkit-line-clamp: 2;
   line-clamp: 2;
   -webkit-box-orient: vertical;
   transition:
      opacity 0.26s ease 0.06s,
      transform 0.34s cubic-bezier(0.22, 1, 0.36, 1) 0.06s;
}
.song-card:hover .song-card-detail,
.song-card:focus-visible .song-card-detail,
.song-card:focus-within .song-card-detail {
   opacity: 1;
   transform: translateY(0);
}
/* Actions (export / duplicate / delete) are parked below the chips inside the
   dock, so they can never cover the song title. They fade in as the dock
   rises; the small stagger makes the two motions feel like one gesture. */
.song-card-actions {
   margin-top: 10px;
   display: flex;
   gap: 8px;
   opacity: 0;
   transition: opacity 0.22s ease;
}
.song-card:hover .song-card-actions,
.song-card:focus-visible .song-card-actions,
.song-card:focus-within .song-card-actions {
   opacity: 1;
   transition-delay: 0.08s;
}
.song-card-action {
   position: relative;
   width: 32px;
   height: 32px;
   display: grid;
   place-items: center;
   border: none;
   border-radius: 50%;
   background: color-mix(in srgb, var(--soft) 55%, transparent);
   box-shadow: none;
   color: var(--muted);
   font-size: 14px;
   cursor: pointer;
   transition:
      background 0.18s ease,
      color 0.18s ease,
      transform 0.18s ease,
      box-shadow 0.18s ease;
}
.song-card-action:hover,
.song-card-action:focus-visible {
   transform: translateY(-2px);
   box-shadow: 0 6px 14px -5px rgba(16, 40, 28, 0.3);
   color: var(--ink);
   outline: none;
}
/* The Edit shortcut is a PHONE-ONLY affordance (the tap-to-reveal overlay). On
   desktop/tablet a card click already opens the editor, so the button would be
   redundant — hide it here and re-enable it inside the phone media query. */
.song-card-action.is-edit {
   display: none;
}
/* Tooltip naming the button, so the icons are never a guessing game. Sits
   above the button (there is always room: the dock is at the card bottom). */
.song-card-action::after {
   content: attr(data-label);
   position: absolute;
   bottom: calc(100% + 7px);
   left: 50%;
   z-index: 4;
   padding: 4px 8px;
   border-radius: 7px;
   background: color-mix(in srgb, var(--ink) 92%, transparent);
   color: var(--surface);
   font-size: 10.5px;
   font-weight: 600;
   letter-spacing: 0.01em;
   line-height: 1.2;
   white-space: nowrap;
   opacity: 0;
   transform: translate(-50%, 4px);
   pointer-events: none;
   transition:
      opacity 0.16s ease,
      transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
}
.song-card-action:hover::after,
.song-card-action:focus-visible::after {
   opacity: 1;
   transform: translate(-50%, 0);
}
.song-card-action.is-delete:hover {
   background: rgba(180, 35, 24, 0.12);
   color: #b42318;
}
/* Export .pdf is the primary per-card action, so it carries the brand tint. */
.song-card-action.is-pdf:hover,
.song-card-action.is-pdf:focus-visible {
   background: color-mix(in srgb, var(--green) 16%, transparent);
   color: var(--dark-green);
}
.song-card-action.is-duplicate:hover {
   background: var(--soft);
   color: var(--dark-green);
}
/* Copy Link — same visual treatment as is-duplicate */
.song-card-action.is-copy-link:hover {
   background: var(--soft);
   color: var(--dark-green);
}
.song-card-action.is-export:hover {
   background: var(--soft);
   color: var(--dark-green);
}
/* Copy Link — same visual treatment as is-duplicate */
.song-card-action.is-copy-link:hover {
   background: var(--soft);
   color: var(--dark-green);
}

/* Left/right nudge buttons. */
.cloud-nudge {
   position: absolute;
   top: 50%;
   transform: translateY(-50%);
   z-index: 8;
   width: 46px;
   height: 46px;
   display: grid;
   place-items: center;
   border: 1px solid var(--line);
   border-radius: 50%;
   background: var(--surface);
   color: var(--ink);
   font-size: 24px;
   line-height: 1;
   cursor: pointer;
   box-shadow: var(--shadow-sm);
   transition:
      background 0.16s ease,
      transform 0.16s ease,
      border-color 0.16s ease;
}
.cloud-nudge[hidden] {
   display: none;
}
.cloud-nudge:hover {
   border-color: var(--green);
   background: var(--soft);
}
.cloud-nudge-left {
   left: clamp(8px, 2vw, 22px);
}
.cloud-nudge-right {
   right: clamp(8px, 2vw, 22px);
}

/* Gallery states (loading / empty / no-results) overlay the body center. */
.cloud-gallery-state {
   position: absolute;
   inset: 0;
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: center;
   gap: 8px;
   text-align: center;
   color: var(--muted);
   pointer-events: none;
}
.cloud-gallery-state[hidden] {
   display: none;
}
.cloud-gallery-state p {
   margin: 4px 0 0;
   font-size: 17px;
   font-weight: 700;
   color: var(--ink);
}
.cloud-gallery-state span {
   font-size: 13px;
   max-width: 34ch;
}
.cloud-gallery-state-icon {
   font-size: 40px;
   opacity: 0.85;
   color: var(--green, #1f9d55);
}
.cloud-spinner {
   width: 38px;
   height: 38px;
   border: 3px solid var(--line);
   border-top-color: var(--green);
   border-radius: 50%;
   animation: cloud-spin 0.8s linear infinite;
}
@keyframes cloud-spin {
   to {
      transform: rotate(360deg);
   }
}

/* Phone tweaks for the gallery. */
@media (max-width: 680px) {
   .cloud-gallery-head {
      /* Stack the three header columns on phones: brand, then the centered
         title, then the full-width actions. */
      grid-template-columns: 1fr;
      align-items: stretch;
      gap: 12px;
      padding: 16px 18px;
   }
   .cloud-gallery-heading {
      justify-self: start;
   }
   .cloud-gallery-actions {
      width: 100%;
      justify-self: stretch;
      justify-content: flex-start;
   }
   .home-intro {
      justify-self: start;
      text-align: left;
      margin: 0;
      padding: 0;
   }
   .cloud-gallery-searchbar {
      padding: 12px 18px 4px;
   }
   .home-brand-text {
      font-size: 14px;
   }
   .home-brand-text small {
      font-size: 9.5px;
   }
   .home-brand-icon {
      width: 32px;
      height: 32px;
   }
   /* Keep the card anchored to the button but never wider than the viewport. */
   .account-popover {
      width: min(244px, calc(100vw - 24px));
   }
   .cloud-search {
      width: 100%;
   }
   .cloud-search input {
      width: 100%;
   }
   /* On phones the desktop 2-row HORIZONTAL carousel doesn't fit: two 228px
      cards stacked need ~540px of height, far more than a phone's gallery body
      (~380-410px), so the bottom row was clipped. Switch to a natural
      vertical-scrolling grid: cards flow left-to-right and wrap onto new rows,
      and the whole grid scrolls DOWN. Nothing is clipped — you just scroll. */
   .cloud-gallery-body {
      align-items: stretch;
   }
   .cloud-cards {
      display: grid;
      grid-template-rows: none;
      grid-auto-flow: row;
      grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
      grid-auto-columns: auto;
      gap: 14px 12px;
      height: 100%;
      align-content: start;
      justify-content: stretch;
      overflow-x: hidden;
      overflow-y: auto;
      -webkit-overflow-scrolling: touch;
      overscroll-behavior: contain;
      padding: 16px 16px calc(20px + env(safe-area-inset-bottom));
   }
   .song-card {
      /* Cards fill their grid cell; no fixed width, and no zigzag shift/blur
         (that was a horizontal-carousel affordance). A DEFINITE height (not just
         min-height) is required so the tap-to-reveal action overlay — an absolutely
         positioned child using height:100% — can fill the whole card. */
      --shift: 0px;
      --lift: 0px;
      width: 100%;
      height: 184px;
      padding: 16px 16px 14px;
      transform: none;
      filter: none;
      opacity: 1;
   }
   .song-card:nth-child(4n + 1),
   .song-card:nth-child(4n + 2) {
      --shift: 0px;
   }
   .song-card:nth-child(4n + 3),
   .song-card:nth-child(4n + 4) {
      --shift: 0px;
   }
   /* ---- Phone tap-to-reveal action overlay ----
      On phones a card's dock (chips + tiny action row) stays tucked away. Tapping
      a card adds .is-selected (JS), which blurs the card's own content and floats
      a centered grid of enlarged action buttons (Edit / Export .pdf / Export
      .file / Duplicate / Delete) over it. Tapping the card again or tapping
      outside removes .is-selected. */
   .song-card {
      overflow: hidden;
   }
   /* Resting state: the dock is a normal quiet footer; the tiny action row is
      hidden (the overlay is the only way to act on a card on phones). The dock
      must NOT create a containing block (its will-change/transform would make
      the absolutely-positioned action overlay size against the 32px dock instead
      of the whole card), so clear both here. */
   .song-card-dock {
      --dock-shift: 0px;
      transform: none;
      will-change: auto;
      margin-bottom: 0;
   }
   /* CRITICAL: the desktop base applies `transform: translateY(...)` to the dock
      on hover/focus/focus-within (line ~3441). Tapping a card moves focus INTO it
      (:focus-within), which re-applies that transform here and — even as an
      identity translate — establishes a containing block, so the absolutely
      positioned .song-card-actions overlay would size against the ~17px dock
      instead of the whole card (buttons overflow/clip, e.g. multi-line titles
      pushed Delete off the bottom). Force `transform: none` for every dock state
      on phones so the overlay always fills the card and centres vertically
      regardless of how many rows the title wraps to. */
   .song-card:hover .song-card-dock,
   .song-card:focus-visible .song-card-dock,
   .song-card:focus-within .song-card-dock,
   .song-card.is-selected .song-card-dock {
      transform: none;
   }
   .song-card-actions {
      display: none;
   }
   .song-card-detail {
      opacity: 1;
      transform: none;
   }
   /* Explicit resting filter so selecting a card interpolates blur(0)->blur(3px)
      deterministically (transitioning from the `none` keyword can stick). NOTE:
      we blur the dock's META content, never the .song-card-dock element itself —
      the action overlay lives inside the dock in the DOM, and a filter on the
      dock would create a containing block that shrinks the overlay to dock size. */
   .song-card-title,
   .song-card-creator,
   .song-card-detail,
   .song-card-meta,
   .song-card::before {
      filter: blur(0);
      transition:
         filter 0.24s ease,
         opacity 0.24s ease;
   }
   /* Blur + fade the card's own content once selected so the actions read clearly. */
   .song-card.is-selected .song-card-title,
   .song-card.is-selected .song-card-creator,
   .song-card.is-selected .song-card-detail,
   .song-card.is-selected .song-card-meta,
   .song-card.is-selected::before {
      filter: blur(3px);
      opacity: 0.35;
      pointer-events: none;
   }
   .song-card.is-selected {
      border-color: color-mix(in srgb, var(--green) 35%, transparent);
      box-shadow:
         0 2px 6px rgba(16, 40, 28, 0.06),
         0 20px 42px -18px rgba(16, 40, 28, 0.3);
   }
   /* Floated, centered action grid. Sits above the blurred content and animates
      in from a slight scale/offset so it reads as sliding to the card center. */
   .song-card-actions {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 5;
      margin: 0;
      display: none;
      flex-wrap: wrap;
      align-content: center;
      justify-content: center;
      gap: 8px 6px;
      padding: 10px;
      opacity: 0;
      transform: scale(0.9);
      transition:
         opacity 0.24s ease,
         transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
   }
   .song-card.is-selected .song-card-actions {
      display: flex;
      opacity: 1;
      transform: scale(1);
   }
   /* Edit is phone-only — restore it here (hidden on desktop/tablet above). */
   .song-card-action.is-edit {
      display: grid;
   }
   /* 40px buttons + tight gap/padding so all THREE fit per row even on the
      narrowest phone card (~158px wide at 360px vp): 3×40 + 2×6 gap = 132px fits
      inside the ~138px content box. Five actions then always wrap as a centered
      3+2 grid (justify/align-content:center centre both the rows and the short
      last row), so Delete is never orphaned on its own row or clipped. */
   .song-card-action {
      flex: 0 0 auto;
      width: 40px;
      height: 40px;
      border: 1px solid var(--line);
      background: var(--surface);
      color: var(--ink);
      font-size: 17px;
      box-shadow: var(--shadow-sm);
   }
   .song-card-chip {
      font-size: 14px;
   }
   .cloud-nudge {
      width: 40px;
      height: 40px;
      font-size: 20px;
   }
}

/* Touch devices have no hover, so the dock would stay closed until the card is
   focused. On touch TABLETS (which keep the desktop horizontal carousel) keep it
   open: the chips sit up and the actions + detail are permanently visible, which
   is the friendlier tap target there. Phones (<=680px) use a different model —
   tap a card to reveal a centered action overlay — so this is scoped to >680px. */
@media (hover: none) and (min-width: 681px) {
   .song-card-dock {
      transform: translateY(calc(-1 * var(--dock-shift)));
   }
   .song-card-actions,
   .song-card-detail {
      opacity: 1;
   }
   .song-card-detail {
      transform: translateY(0);
   }
   /* Tooltips are hover-only affordances; taps shouldn't leave one stuck on. */
   .song-card-action::after {
      display: none;
   }
}

/* Dark-theme fine-tuning (most colors already come from tokens). */
html[data-theme="dark"] .cloud-google-btn {
   background: var(--surface);
}
html[data-theme="dark"] .cloud-google-btn:hover {
   border-color: #465049;
   background: var(--soft);
}
html[data-theme="dark"] .cloud-field input,
html[data-theme="dark"] .cloud-search input {
   background: #101210;
}
html[data-theme="dark"] .cloud-auth-error {
   color: #ff9b8f;
   background: rgba(255, 100, 85, 0.1);
   border-color: rgba(255, 100, 85, 0.28);
}
html[data-theme="dark"] .song-card-action.is-delete:hover {
   color: #ff9b8f;
   background: rgba(255, 100, 85, 0.12);
   border-color: rgba(255, 100, 85, 0.4);
}

/* ============================================================
   Inline chord editor (type → pick a suggestion) + the matching
   beat-hover field preview. A single width token keeps the hover
   affordance and the popover input pixel-identical.
   ============================================================ */
:root {
   --chord-field-w: 84px; /* shared: hover preview footprint == popover input */
   --chord-field-h: 30px;
}

/* Floating popover, positioned by JS (fixed to the viewport). */
.chord-popover {
   position: fixed;
   z-index: 1400;
   width: max-content;
   min-width: calc(var(--chord-field-w) + 20px);
   max-width: min(92vw, 260px);
   padding: 8px;
   background: var(--surface);
   border: 1px solid var(--line);
   border-radius: var(--radius-md);
   box-shadow: var(--shadow-md);
   animation: chord-pop-in 0.13s ease-out both;
}
@keyframes chord-pop-in {
   from {
      opacity: 0;
      transform: translateY(4px) scale(0.98);
   }
}
/* Little arrow pointing at the anchored beat. */
.chord-popover::after {
   content: "";
   position: absolute;
   left: var(--arrow-x, 50%);
   bottom: -6px;
   width: 12px;
   height: 12px;
   background: var(--surface);
   border-right: 1px solid var(--line);
   border-bottom: 1px solid var(--line);
   transform: translateX(-50%) rotate(45deg);
}
.chord-popover.is-below::after {
   bottom: auto;
   top: -6px;
   border: 0;
   border-left: 1px solid var(--line);
   border-top: 1px solid var(--line);
}
.chord-popover-input {
   width: var(--chord-field-w);
   height: var(--chord-field-h);
   box-sizing: border-box;
   border: 1.5px solid var(--green);
   border-radius: var(--radius-sm);
   padding: 0 10px;
   background: var(--surface);
   color: var(--ink);
   font:
      700 14px/1 Inter,
      ui-sans-serif,
      sans-serif;
   text-align: center;
   letter-spacing: 0.02em;
   outline: 0;
   transition: box-shadow 0.15s;
}
.chord-popover-input:focus {
   box-shadow: 0 0 0 3px rgba(35, 122, 80, 0.18);
}
.chord-popover-input::placeholder {
   color: var(--muted);
   font-weight: 500;
}
.chord-popover-list {
   list-style: none;
   margin: 8px 0 0;
   padding: 0;
   max-height: 232px;
   overflow-y: auto;
   display: grid;
   gap: 2px;
}
.chord-popover-list[hidden] {
   display: none;
}
.chord-suggestion {
   display: flex;
   align-items: center;
   min-height: 34px;
   padding: 5px 10px;
   border-radius: var(--radius-sm);
   cursor: pointer;
   color: var(--ink);
   transition: background 0.1s;
}
.chord-suggestion:hover,
.chord-suggestion.is-active {
   background: var(--soft);
}
.chord-suggestion.is-active {
   box-shadow: inset 0 0 0 1.5px rgba(35, 122, 80, 0.35);
}
.chord-suggestion-label {
   font:
      700 15px/1 Inter,
      ui-sans-serif,
      sans-serif;
   color: var(--dark-green);
}
.chord-popover-msg {
   margin: 8px 2px 2px;
   padding: 6px 8px;
   border-radius: var(--radius-sm);
   background: rgba(200, 90, 70, 0.08);
   color: #b25542;
   font:
      600 12.5px/1.3 Inter,
      ui-sans-serif,
      sans-serif;
   text-align: center;
}
.chord-popover-msg[hidden] {
   display: none;
}
/* Anchor beat highlight while its editor is open. Uses the SAME inset box as the
   hover affordance (preview.css) so the hover preview and the active/clicked
   target are pixel-identical — a solid ring drawn a few px inside the cell. */
html:not(.is-print-layout) .drop-target.chord-editing {
   position: relative;
}
html:not(.is-print-layout) .drop-target.chord-editing::after {
   content: "";
   position: absolute;
   z-index: 5;
   inset: 21px 16px 3px;
   border: 1.5px solid rgba(35, 122, 80, 0.6);
   border-radius: 5px;
   background: rgba(35, 122, 80, 0.06);
   pointer-events: none;
}
/* Hide the placeholder dot inside the beat that's currently being edited. */
html:not(.is-print-layout) .drop-target.chord-editing .beat-dot {
   opacity: 0;
}

html[data-theme="dark"] .chord-popover-msg {
   background: rgba(255, 100, 85, 0.12);
   color: #ff9b8f;
}
html[data-theme="dark"] .chord-suggestion.is-active {
   box-shadow: inset 0 0 0 1.5px rgba(120, 220, 160, 0.4);
}

/* ============================================================
   Beat rhythm context menu (right-click / long-press).
   ============================================================ */
.beat-menu {
   position: fixed;
   z-index: 1450;
   min-width: 200px;
   padding: 6px;
   background: var(--surface);
   border: 1px solid var(--line);
   border-radius: var(--radius-md);
   box-shadow: var(--shadow-md);
   animation: chord-pop-in 0.12s ease-out both;
}
.beat-menu-item {
   display: flex;
   align-items: center;
   justify-content: space-between;
   gap: 12px;
   width: 100%;
   padding: 9px 11px;
   border: 0;
   border-radius: var(--radius-sm);
   background: transparent;
   color: var(--ink);
   font:
      600 14px/1 Inter,
      ui-sans-serif,
      sans-serif;
   text-align: left;
   cursor: pointer;
   transition: background 0.1s;
}
.beat-menu-item:hover {
   background: var(--soft);
}
.beat-menu-item[aria-disabled="true"] {
   opacity: 0.4;
   cursor: not-allowed;
}
.beat-menu-item[aria-disabled="true"]:hover {
   background: transparent;
}
.beat-menu-item.is-danger {
   color: #b25542;
}
.beat-menu-item.is-danger:hover {
   background: rgba(200, 90, 70, 0.08);
}
.beat-menu-hint {
   display: grid;
   place-items: center;
   min-width: 20px;
   height: 20px;
   padding: 0 5px;
   border-radius: 6px;
   background: var(--soft);
   color: var(--muted);
   font:
      700 11px/1 Inter,
      ui-sans-serif,
      sans-serif;
}
html[data-theme="dark"] .beat-menu-item.is-danger {
   color: #ff9b8f;
}
html[data-theme="dark"] .beat-menu-item.is-danger:hover {
   background: rgba(255, 100, 85, 0.12);
}

/* ==================== MODE PICKER DIALOG (New Song) ==================== */
.mode-picker-card {
   width: min(90vw, 520px);
   max-height: 80vh;
   text-align: left;
   align-items: stretch;
   overflow-y: auto;
}
.mode-picker-card .confirm-dialog-icon {
   align-self: center;
}
.mode-picker-close {
   position: absolute;
   top: 16px;
   right: 16px;
   z-index: 2;
   border: none;
   background: transparent;
   font-size: 24px;
   line-height: 1;
   cursor: pointer;
   color: var(--muted);
   padding: 4px;
   border-radius: 4px;
   transition: color 0.18s ease;
}
.mode-picker-close:hover {
   color: var(--ink);
   background: rgba(0, 0, 0, 0.04);
}
.mode-picker-grid {
   display: grid;
   grid-template-columns: 1fr;
   gap: 14px;
   margin: 20px -2px -2px;
   padding: 0 2px;
}
@media (min-width: 640px) {
   .mode-picker-grid {
      grid-template-columns: repeat(2, 1fr);
      gap: 18px;
      margin: 24px -4px -4px;
   }
}
.mode-card {
   display: flex;
   flex-direction: column;
   gap: 14px;
   padding: 18px;
   border: 1.5px solid rgba(0, 0, 0, 0.1);
   border-radius: 14px;
   background: #fff;
   box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
   cursor: pointer;
   transition:
      transform 0.18s ease,
      box-shadow 0.18s ease,
      border-color 0.18s ease,
      background 0.18s ease;
   outline: none;
   text-align: left;
}
.mode-card:focus-visible {
   box-shadow: 0 0 0 3px rgba(184, 232, 92, 0.6);
   border-color: rgba(47, 125, 79, 0.6);
}
.mode-card:hover {
   transform: translateY(-3px);
   box-shadow: 0 8px 18px rgba(0, 0, 0, 0.1);
   border-color: rgba(47, 125, 79, 0.4);
   background: linear-gradient(180deg, #fff 0%, color-mix(in srgb, var(--green) 3%, #fff) 100%);
}
.mode-card-visual {
   height: 80px;
   border-radius: 10px;
   background: rgba(0, 0, 0, 0.02);
   display: grid;
   place-items: center;
   overflow: hidden;
   border: 1px solid rgba(0, 0, 0, 0.06);
}
.mode-card-anim {
   display: flex;
   align-items: center;
   justify-content: center;
   gap: 8px;
   font-size: 16px;
   font-weight: 700;
   font-family:
      system-ui,
      -apple-system,
      sans-serif;
}
.mode-anim-chords {
   animation: chordFlow 2s ease-in-out infinite;
}
@keyframes chordFlow {
   0%,
   100% {
      transform: translateX(0);
   }
   50% {
      transform: translateX(-8px);
   }
}
.mca-chord {
   background: var(--dark-green);
   color: #fff;
   padding: 4px 10px;
   border-radius: 6px;
   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
.mca-chord-1 {
   animation-delay: 0ms;
}
.mca-chord-2 {
   animation-delay: 200ms;
}
.mca-chord-3 {
   animation-delay: 400ms;
}
.mca-chord-4 {
   animation-delay: 600ms;
}
.mode-anim-numbers {
   animation: numBounce 1.8s ease-in-out infinite;
}
@keyframes numBounce {
   0%,
   100% {
      transform: scale(1);
   }
   50% {
      transform: scale(1.08);
   }
}
.mca-num {
   display: inline-block;
   width: 28px;
   height: 28px;
   line-height: 26px;
   text-align: center;
   background: var(--green);
   color: #fff;
   border-radius: 50%;
   font-size: 14px;
   font-weight: 800;
   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}
.mca-num-lyric {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   min-width: 40px;
   height: 28px;
   padding: 0 10px;
   background: color-mix(in srgb, var(--dark-green) 12%, #fff);
   color: var(--dark-green);
   font-size: 12px;
   border-radius: 8px;
   font-weight: 800;
   letter-spacing: 0.08em;
   border: 1.5px solid color-mix(in srgb, var(--dark-green) 25%, transparent);
}
.mode-card-body {
   display: flex;
   flex-direction: column;
   gap: 10px;
}
.mode-card-header {
   display: flex;
   align-items: center;
   gap: 12px;
}
.mode-card-icon {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: 52px;
   height: 52px;
   flex: none;
   border-radius: 14px;
   background: linear-gradient(
      140deg,
      color-mix(in srgb, var(--green) 22%, #fff) 0%,
      color-mix(in srgb, var(--dark-green) 16%, #fff) 100%
   );
   color: var(--dark-green);
   box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--dark-green) 18%, transparent);
   transition:
      transform 0.18s ease,
      box-shadow 0.18s ease;
}
.mode-card:hover .mode-card-icon {
   transform: scale(1.06) rotate(-3deg);
   box-shadow:
      inset 0 0 0 1.5px color-mix(in srgb, var(--dark-green) 32%, transparent),
      0 4px 12px rgba(47, 125, 79, 0.18);
}
.mode-card-title {
   margin: 0;
   font-size: 18px;
   font-weight: 700;
   letter-spacing: -0.02em;
   color: var(--ink);
}
.mode-card-sub {
   margin: 0;
   font-size: 13px;
   color: var(--muted);
}
.mode-card-points {
   margin: 4px 0 0;
   padding: 0;
   list-style: none;
   display: flex;
   flex-wrap: wrap;
   gap: 8px 10px;
}
.mode-card-points li {
   font-size: 12.5px;
   font-weight: 600;
   display: inline-flex;
   align-items: center;
   gap: 6px;
   padding: 4px 10px;
   border-radius: 999px;
   border: 1px solid transparent;
}
.mode-card-points li span:first-child {
   font-weight: 800;
   font-size: 13px;
}
/* Pros = green, Cons = soft red — clear affirmative/negative semantics */
.mode-card-points li.is-pro {
   background: color-mix(in srgb, var(--green) 12%, #fff);
   border-color: color-mix(in srgb, var(--green) 28%, transparent);
   color: var(--dark-green);
}
.mode-card-points li.is-pro span:first-child {
   color: #1f9d55;
}
.mode-card-points li.is-con {
   background: color-mix(in srgb, #e5484d 10%, #fff);
   border-color: color-mix(in srgb, #e5484d 26%, transparent);
   color: #b02a2f;
}
.mode-card-points li.is-con span:first-child {
   color: #e5484d;
}
html[data-theme="dark"] .mode-card {
   background: #1a2e23;
   border-color: rgba(255, 255, 255, 0.08);
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}
html[data-theme="dark"] .mode-card:hover {
   background: linear-gradient(180deg, #1a2e23 0%, color-mix(in srgb, var(--green) 8%, #1a2e23) 100%);
}
html[data-theme="dark"] .mode-card-visual {
   background: rgba(255, 255, 255, 0.04);
   border-color: rgba(255, 255, 255, 0.08);
}
html[data-theme="dark"] .mode-card-points li {
   background: rgba(100, 255, 218, 0.12);
   border-color: rgba(100, 255, 218, 0.25);
   color: #aaddcc;
}
html[data-theme="dark"] .mca-chord {
   background: #7ee0b3;
   color: #0a2a1e;
}
html[data-theme="dark"] .mca-num {
   background: #7ee0b3;
   color: #0a2a1e;
}

/* ---- Editor mode (chords vs numbers) visibility ------------------------
   body[data-editor-mode] is set by render.js on every render. These rules
   drive mode-specific UI without touching JS layout logic. */

/* Lyrics toggle lives inside .song-meta but only makes sense in numbers mode.
   Hide it in chords mode (lyrics feature is off for chord-progression songs).
   Rendered as the first item so it sits to the LEFT of KEY. */
.song-meta-lyrics-toggle {
   display: none;
   align-items: center;
   gap: 8px;
   cursor: pointer;
   user-select: none;
   padding-right: 14px;
   margin-right: 2px;
   border-right: 1px solid var(--line, rgba(0, 0, 0, 0.12));
}
body[data-editor-mode="numbers"] .song-meta-lyrics-toggle {
   display: inline-flex;
}
/* Chord-above toggle — disabled for now (feature not ready in Chord Chart mode).
   .song-meta-chord-above-toggle {
   display: none;
   align-items: center;
   gap: 8px;
   cursor: pointer;
   user-select: none;
   padding-right: 14px;
   margin-right: 2px;
   border-right: 1px solid var(--line, rgba(0, 0, 0, 0.12));
}
body[data-editor-mode="chords"] .song-meta-chord-above-toggle {
   display: inline-flex;
} */
.song-meta-chord-above-toggle {
   display: none !important;
}
.song-meta-lyrics-caption {
   font-size: 11px;
   font-weight: 700;
   letter-spacing: 0.06em;
   color: var(--muted, #6b7280);
}
.song-meta-lyrics-switch {
   display: inline-flex;
   align-items: center;
   gap: 7px;
}
/* Hide the native checkbox but keep it accessible/focusable. */
.song-meta-lyrics-switch input {
   position: absolute;
   opacity: 0;
   width: 1px;
   height: 1px;
   pointer-events: none;
}
.song-meta-lyrics-track {
   position: relative;
   display: inline-block;
   width: 34px;
   height: 20px;
   border-radius: 999px;
   background: var(--line, #d1d5db);
   transition: background 0.2s ease;
   flex: none;
}
.song-meta-lyrics-thumb {
   position: absolute;
   top: 2px;
   left: 2px;
   width: 16px;
   height: 16px;
   border-radius: 50%;
   background: #fff;
   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
   transition: transform 0.2s ease;
}
.song-meta-lyrics-switch input:checked + .song-meta-lyrics-track {
   background: var(--green, #10b981);
}
.song-meta-lyrics-switch input:checked + .song-meta-lyrics-track .song-meta-lyrics-thumb {
   transform: translateX(14px);
}
.song-meta-lyrics-switch input:focus-visible + .song-meta-lyrics-track {
   box-shadow: 0 0 0 3px rgba(184, 232, 92, 0.55);
}
.song-meta-lyrics-switch b {
   font-size: 12px;
   font-weight: 700;
   color: var(--ink);
   min-width: 20px;
}

/* Mode badge — sits to the LEFT of "Save to Cloud" in the topbar actions.
   Clean pill with a small mode glyph + label; adapts color/icon per mode. */
.editor-mode-badge {
   display: inline-flex;
   align-items: center;
   gap: 7px;
   padding: 6px 12px 6px 8px;
   border-radius: 999px;
   font-size: 12px;
   font-weight: 700;
   letter-spacing: 0.01em;
   border: 1px solid color-mix(in srgb, var(--dark-green, #2f7d4f) 22%, transparent);
   color: var(--dark-green, #2f7d4f);
   background: color-mix(in srgb, var(--green, #10b981) 10%, #fff);
   white-space: nowrap;
   transition:
      background 0.18s ease,
      border-color 0.18s ease;
}
.editor-mode-badge-icon {
   display: inline-flex;
   align-items: center;
   justify-content: center;
   width: 22px;
   height: 22px;
   border-radius: 50%;
   background: color-mix(in srgb, var(--green, #10b981) 20%, #fff);
   color: var(--dark-green, #2f7d4f);
   font-size: 12px;
   flex: none;
}
.editor-mode-badge-icon::before {
   content: "♪";
   font-weight: 700;
   line-height: 1;
}
body[data-editor-mode="numbers"] .editor-mode-badge-icon::before {
   content: "#";
}
body[data-editor-mode="numbers"] .editor-mode-badge {
   border-color: color-mix(in srgb, #6366f1 26%, transparent);
   color: #4f46e5;
   background: color-mix(in srgb, #6366f1 9%, #fff);
}
body[data-editor-mode="numbers"] .editor-mode-badge-icon {
   background: color-mix(in srgb, #6366f1 16%, #fff);
   color: #4f46e5;
}
html[data-theme="dark"] .editor-mode-badge {
   color: #7ee0b3;
   border-color: rgba(126, 224, 179, 0.4);
   background: rgba(126, 224, 179, 0.1);
}
html[data-theme="dark"] .editor-mode-badge-icon {
   background: rgba(126, 224, 179, 0.16);
   color: #7ee0b3;
}
html[data-theme="dark"] body[data-editor-mode="numbers"] .editor-mode-badge {
   color: #b0b4ff;
   border-color: rgba(129, 140, 248, 0.4);
   background: rgba(129, 140, 248, 0.12);
}
html[data-theme="dark"] body[data-editor-mode="numbers"] .editor-mode-badge-icon {
   background: rgba(129, 140, 248, 0.2);
   color: #b0b4ff;
}
