From f1f6f8a99e0429673d043c1f25a5dd98dad444b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 21 Jun 2026 12:16:18 +0000 Subject: [PATCH 1/8] Initial plan From 0164dcbe4454b86f824d81f364c6da68eac876c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 21 Jun 2026 12:18:22 +0000 Subject: [PATCH 2/8] feat: add responsive metronome viewport scaling --- app.js | 80 ++++++++++++++++++++++++++++++++++++++++ styles.css | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) diff --git a/app.js b/app.js index 3e93db6..5adf1ac 100644 --- a/app.js +++ b/app.js @@ -642,6 +642,7 @@ let metroPendulumFrame = null; let metroPendulumStartedAt = 0; let metroWasRunningBeforeModal = false; let metroPausedByModal = false; +let metroLayoutFrame = null; function metronomeHtml(){ const meterLabel = meter === 6 ? '6/8' : `${meter}/4`; @@ -726,6 +727,7 @@ function initMetronome(){ renderMetroControls(); syncCleanMetronomeUi(); setBpm(bpm, {restart:false}); + scheduleCleanMetronomeLayoutSync(); document.querySelector('#startMetro')?.addEventListener('click', () => metroRunning ? stopMetronome() : startMetronome()); document.querySelector('#metroResetTop')?.addEventListener('click', resetMetronomeSettings); @@ -753,6 +755,83 @@ function initMetronome(){ })); } +function scheduleCleanMetronomeLayoutSync(){ + if(currentView !== 'metronome') return; + if(metroLayoutFrame) cancelAnimationFrame(metroLayoutFrame); + metroLayoutFrame = requestAnimationFrame(() => { + metroLayoutFrame = null; + syncCleanMetronomeLayout(); + }); +} + +function syncCleanMetronomeLayout(){ + const screen = document.querySelector('.metro-clean-screen'); + const main = document.querySelector('#metroCleanMain'); + const visual = document.querySelector('#metroCleanVisual'); + if(!screen || !main || !visual) return; + + const viewportWidth = Math.max(320, Math.round( + window.visualViewport?.width || + window.innerWidth || + document.documentElement.clientWidth || + screen.clientWidth || + 0 + )); + const viewportHeight = Math.max(320, Math.round( + window.visualViewport?.height || + window.innerHeight || + document.documentElement.clientHeight || + screen.clientHeight || + 0 + )); + const landscape = viewportWidth > viewportHeight; + const head = screen.querySelector('.view-head'); + const actions = screen.querySelector('.metro-clean-actions'); + const screenStyle = getComputedStyle(screen); + const mainStyle = getComputedStyle(main); + const actionsStyle = actions ? getComputedStyle(actions) : null; + const screenHeight = screen.clientHeight || Math.round(screen.getBoundingClientRect().height) || viewportHeight; + const availableWidth = Math.max( + 260, + Math.min(main.clientWidth || screen.clientWidth || viewportWidth, viewportWidth - 28) + ); + const availableHeight = Math.max( + 230, + screenHeight - + (head?.offsetHeight || 0) - + ((parseFloat(screenStyle.paddingTop) || 0) + (parseFloat(screenStyle.paddingBottom) || 0)) - + (actions?.offsetHeight || 0) - + (actionsStyle ? (parseFloat(actionsStyle.marginTop) || 0) : 0) - + 16 + ); + + const baseVisualWidth = landscape ? 384 : 360; + const baseVisualRatio = landscape ? 0.98 : 1.16; + const baseVisualHeight = baseVisualWidth * baseVisualRatio; + const baseMainHeight = + baseVisualHeight + + (landscape ? 56 : 62) + + (landscape ? 58 : 62) + + ((parseFloat(mainStyle.rowGap || mainStyle.gap) || 18) * 2); + const scale = Math.max( + 0.56, + Math.min( + availableWidth / baseVisualWidth, + availableHeight / baseMainHeight, + 1.18 + ) + ); + + screen.classList.toggle('metro-clean-landscape', landscape); + screen.classList.toggle('metro-clean-portrait', !landscape); + screen.style.setProperty('--metro-scale', scale.toFixed(3)); + screen.style.setProperty('--metro-visual-width', `${Math.round(baseVisualWidth * scale)}px`); + screen.style.setProperty('--metro-visual-ratio', baseVisualRatio.toFixed(3)); +} + +window.addEventListener('resize', scheduleCleanMetronomeLayoutSync); +window.visualViewport?.addEventListener?.('resize', scheduleCleanMetronomeLayoutSync); + function pauseMetronomeForModal(){ if(metroPausedByModal) return; metroWasRunningBeforeModal = metroRunning; @@ -918,6 +997,7 @@ function syncCleanMetronomeUi(){ visual.style.setProperty('--metro-duration', `${60000 / bpm}ms`); visual.classList.toggle('running', metroRunning); } + scheduleCleanMetronomeLayoutSync(); } function setBpm(v, opts={restart:true}){ diff --git a/styles.css b/styles.css index 4f6600d..ba8477d 100644 --- a/styles.css +++ b/styles.css @@ -4701,3 +4701,108 @@ label[for="chordSearch"]{ #metroCleanBpmButton { cursor: pointer !important; } + +/* EasyTune v56 — responsive metronome scales to the app viewport */ +.metro-clean-screen{ + --metro-scale:1; + --metro-visual-width:360px; + --metro-visual-ratio:1.16; +} +.metro-clean-main{ + width:min(100%, 760px) !important; + margin:0 auto !important; + gap:clamp(10px, 1.8vh, 18px) !important; + justify-items:stretch !important; +} +.metro-clean-visual{ + width:min(100%, var(--metro-visual-width)) !important; + height:calc(var(--metro-visual-width) * var(--metro-visual-ratio)) !important; + min-height:0 !important; + margin:0 auto !important; + border-radius:clamp(18px, calc(24px * var(--metro-scale)), 28px) !important; +} +.metro-clean-visual::before{ + width:calc(300px * var(--metro-scale)) !important; + height:calc(300px * var(--metro-scale)) !important; +} +.metro-clean-scale{ + top:calc(56px * var(--metro-scale)) !important; + width:calc(190px * var(--metro-scale)) !important; + height:calc(78px * var(--metro-scale)) !important; + border-radius:calc(190px * var(--metro-scale)) calc(190px * var(--metro-scale)) 0 0 !important; +} +.metro-clean-scale::before, +.metro-clean-scale::after{ + top:calc(44px * var(--metro-scale)) !important; + width:calc(36px * var(--metro-scale)) !important; +} +.metro-clean-scale::before{ + left:calc(18px * var(--metro-scale)) !important; +} +.metro-clean-scale::after{ + right:calc(18px * var(--metro-scale)) !important; +} +.metro-clean-pendulum{ + top:calc(74px * var(--metro-scale)) !important; + width:max(3px, calc(4px * var(--metro-scale))) !important; + height:calc(230px * var(--metro-scale)) !important; +} +.metro-clean-pendulum span{ + bottom:calc(-17px * var(--metro-scale)) !important; + width:calc(34px * var(--metro-scale)) !important; + height:calc(34px * var(--metro-scale)) !important; +} +.metro-clean-bpm{ + min-width:0 !important; + padding:calc(10px * var(--metro-scale)) calc(16px * var(--metro-scale)) !important; +} +.metro-clean-bpm strong{ + font-size:clamp(52px, calc(112px * var(--metro-scale)), 112px) !important; +} +.metro-clean-bpm span{ + margin-top:clamp(6px, calc(10px * var(--metro-scale)), 12px) !important; + font-size:clamp(13px, calc(16px * var(--metro-scale)), 16px) !important; +} +.metro-clean-beats{ + min-height:clamp(48px, calc(62px * var(--metro-scale)), 68px) !important; + padding:clamp(10px, calc(16px * var(--metro-scale)), 16px) clamp(8px, calc(12px * var(--metro-scale)), 12px) !important; + gap:clamp(8px, calc(12px * var(--metro-scale)), 14px) !important; +} +.beat-wrap{ + gap:clamp(4px, calc(6px * var(--metro-scale)), 6px) !important; +} +.beat-number{ + font-size:clamp(10px, calc(12px * var(--metro-scale)), 12px) !important; +} +.metro-clean-beats .beat{ + width:clamp(14px, calc(18px * var(--metro-scale)), 18px) !important; + height:clamp(14px, calc(18px * var(--metro-scale)), 18px) !important; +} +.metro-clean-meta{ + width:100% !important; + gap:clamp(8px, calc(10px * var(--metro-scale)), 12px) !important; +} +.metro-clean-meta button{ + min-height:clamp(50px, calc(62px * var(--metro-scale)), 64px) !important; + padding:clamp(8px, calc(10px * var(--metro-scale)), 10px) clamp(4px, calc(8px * var(--metro-scale)), 8px) !important; +} +.metro-clean-meta span{ + font-size:clamp(11px, calc(12px * var(--metro-scale)), 12px) !important; +} +.metro-clean-meta strong{ + font-size:clamp(15px, calc(18px * var(--metro-scale)), 18px) !important; +} +.metro-clean-actions{ + width:min(100%, 520px) !important; + margin:clamp(10px, 1.8vh, 20px) auto 0 !important; +} +.metro-clean-actions .primary-btn{ + min-height:clamp(50px, calc(56px * var(--metro-scale)), 58px) !important; + font-size:clamp(17px, calc(18px * var(--metro-scale)), 18px) !important; +} +.metro-clean-screen.metro-clean-landscape .metro-clean-main{ + gap:clamp(8px, 1.3vh, 14px) !important; +} +.metro-clean-screen.metro-clean-landscape .metro-clean-meta button{ + min-height:clamp(48px, calc(56px * var(--metro-scale)), 58px) !important; +} From acd3d3b41327cd3e88e3548a8c801e30c13da780 Mon Sep 17 00:00:00 2001 From: awj Date: Sun, 21 Jun 2026 14:49:41 +0200 Subject: [PATCH 3/8] fix: remove duplicate CSS, fix padding, integrate responsive metronome styles --- styles.css | 4187 +++------------------------------------------------- 1 file changed, 235 insertions(+), 3952 deletions(-) diff --git a/styles.css b/styles.css index ba8477d..95bd926 100644 --- a/styles.css +++ b/styles.css @@ -180,8 +180,8 @@ button { font: inherit; } pointer-events: none; opacity: .33; background-image: - linear-gradient(90deg, transparent 0 18%, rgba(255,247,237,.08) 18.2% 18.45%, transparent 18.65% 34%, rgba(255,247,237,.08) 34.2% 34.45%, transparent 34.65% 50%, rgba(255,247,237,.08) 50.2% 50.45%, transparent 50.65% 66%, rgba(255,247,237,.08) 66.2% 66.45%, transparent 66.65% 82%, rgba(255,247,237,.08) 82.2% 82.45%, transparent 82.65%), - linear-gradient(180deg, transparent 0 17%, rgba(234,149,22,.08) 17.1% 17.45%, transparent 17.55% 34%, rgba(234,149,22,.08) 34.1% 34.45%, transparent 34.55% 51%, rgba(234,149,22,.08) 51.1% 51.45%, transparent 51.55% 68%, rgba(234,149,22,.08) 68.1% 68.45%, transparent 68.55% 85%, rgba(234,149,22,.08) 85.1% 85.45%, transparent 85.55%); + linear-gradient(90deg, transparent 0 18%, rgba(255,247,237,.08) 18.2% 18.45%, transparent 18.65% 34%, rgba(255,247,237,.08) 34.2% 34.45%, transparent 34.65% 50%, rgba(255,247,237,.08) 50.2% 50.5%, transparent 50.7%), + linear-gradient(180deg, transparent 0 17%, rgba(234,149,22,.08) 17.1% 17.45%, transparent 17.55% 34%, rgba(234,149,22,.08) 34.1% 34.45%, transparent 34.55% 51%, rgba(234,149,22,.08) 51.1% 51.45%, transparent 51.65%); background-size: 190px 190px; transform: rotate(-.4deg) scale(1.08); transform-origin: center; @@ -283,8 +283,8 @@ button { font: inherit; } transform: translateY(-50%) rotate(-7deg); opacity: .52; background-image: - linear-gradient(90deg, transparent 0 19%, rgba(255,247,237,.20) 19.3% 19.9%, transparent 20.2% 38%, rgba(255,247,237,.20) 38.3% 38.9%, transparent 39.2% 57%, rgba(255,247,237,.20) 57.3% 57.9%, transparent 58.2% 76%, rgba(255,247,237,.20) 76.3% 76.9%, transparent 77.2%), - linear-gradient(180deg, transparent 0 18%, rgba(255,247,237,.18) 18.4% 19.9%, transparent 20.3% 35%, rgba(255,247,237,.18) 35.4% 36.9%, transparent 37.3% 52%, rgba(255,247,237,.18) 52.4% 53.9%, transparent 54.3% 69%, rgba(255,247,237,.18) 69.4% 70.9%, transparent 71.3% 86%, rgba(255,247,237,.18) 86.4% 87.9%, transparent 88.3%); + linear-gradient(90deg, transparent 0 19%, rgba(255,247,237,.20) 19.3% 19.9%, transparent 20.2% 38%, rgba(255,247,237,.20) 38.3% 38.9%, transparent 39.2% 57%, rgba(255,247,237,.20) 57.3% 57.9%, transparent 58.1%), + linear-gradient(180deg, transparent 0 18%, rgba(255,247,237,.18) 18.4% 19.9%, transparent 20.3% 35%, rgba(255,247,237,.18) 35.4% 36.9%, transparent 37.3% 52%, rgba(255,247,237,.18) 52.4% 53.9%, transparent 54.3%); filter: drop-shadow(0 14px 22px rgba(0,0,0,.18)); mask-image: linear-gradient(90deg, transparent 0, black 18%, black 90%, transparent 100%); } @@ -431,10 +431,10 @@ button { font: inherit; } .view-screen{ position:relative; overflow:hidden; - padding:22px 18px 26px; + padding:16px 14px 20px; background: - linear-gradient(90deg, rgba(18,9,4,.92), rgba(18,9,4,.60), rgba(18,9,4,.92)), - linear-gradient(180deg, rgba(59,33,18,.45), rgba(18,9,4,.56)); + radial-gradient(circle at 50% 0%, rgba(234,149,22,.07), transparent 18rem), + linear-gradient(180deg, rgba(59,33,18,.44), rgba(18,9,4,.60)); } .view-head{ @@ -442,14 +442,14 @@ button { font: inherit; } align-items:center; justify-content:space-between; gap:12px; - margin:0 0 18px; + margin:0 0 14px; } .view-title{ margin:0; - font-size:clamp(24px,6.2vw,34px); + font-size:clamp(22px,5.4vw,30px); line-height:1; - letter-spacing:-.05em; + letter-spacing:-.045em; font-weight:850; } @@ -457,11 +457,15 @@ button { font: inherit; } .small-action, .ghost-btn, .primary-btn, -.round-btn{ +.round-btn, +.filter-chip, +.preset-bpm, +.meter-btn, +.accent-btn{ border:1px solid rgba(255,247,237,.13); color:var(--text); background:rgba(59,33,18,.72); - border-radius:16px; + border-radius:12px!important; cursor:pointer; -webkit-tap-highlight-color:transparent; } @@ -474,229 +478,56 @@ button { font: inherit; } .view-card{ position:relative; - border:1px solid rgba(255,247,237,.12); - border-radius:24px; - padding:16px; - background: - radial-gradient(circle at 15% 0%, rgba(234,149,22,.10), transparent 180px), - linear-gradient(180deg, rgba(59,33,18,.62), rgba(43,25,15,.42)); - box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 14px 30px rgba(0,0,0,.18); -} -.view-card + .view-card{margin-top:14px} - -.form-label,.group-label{ - display:block; - color:var(--accent); - font-size:11px; - font-weight:950; - letter-spacing:.15em; - text-transform:uppercase; - margin:0 0 10px; -} - -.song-input, -.search-input{ - width:100%; - border:1px solid rgba(255,247,237,.13); - border-radius:20px; - background:rgba(18,9,4,.58); - color:var(--text); - padding:14px; - outline:0; - box-shadow:inset 0 1px 0 rgba(255,255,255,.04); -} -.song-input{min-height:160px;resize:vertical;line-height:1.45;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:14px} -.search-input{height:48px;font-size:15px} -.song-input:focus,.search-input:focus{border-color:rgba(234,149,22,.48);box-shadow:0 0 0 3px rgba(234,149,22,.12)} - -.transpose-controls{ - display:grid; - grid-template-columns:48px 1fr 48px; - align-items:center; - gap:10px; - margin:14px 0; -} -.transpose-value{text-align:center;color:var(--muted);font-weight:850;line-height:1.15} -.transpose-value strong{display:block;color:var(--accent);font-size:28px;letter-spacing:-.05em} -.transpose-actions{display:flex;gap:10px;margin-top:12px;flex-wrap:wrap} -.output-box{ - min-height:145px; - padding:14px; - border-radius:20px; - background:rgba(18,9,4,.46); - border:1px solid rgba(255,247,237,.10); - overflow:auto; - font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; - font-size:14px; - line-height:1.55; - white-space:pre-wrap; -} -.output-line{min-height:1.55em} -.chord-token{ - display:inline-flex; - align-items:center; - justify-content:center; - margin:0 2px 2px; - padding:2px 8px 3px; - border:1px solid rgba(234,149,22,.40); - border-radius:999px; - background:rgba(234,149,22,.14); - color:var(--accent); - font:inherit; - font-weight:900; - cursor:pointer; - vertical-align:baseline; -} -.chord-token:active{transform:scale(.96)} - -.filter-row{display:flex;gap:8px;overflow:auto;padding:2px 2px 12px;margin:0 -2px 10px;scrollbar-width:none} -.filter-row::-webkit-scrollbar{display:none} -.filter-chip{flex:0 0 auto;border:1px solid rgba(255,247,237,.13);border-radius:999px;background:rgba(18,9,4,.48);color:var(--muted);font-weight:850;padding:9px 12px;cursor:pointer} -.filter-chip.active{background:rgba(234,149,22,.18);border-color:rgba(234,149,22,.44);color:var(--accent)} -.chord-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px} -.chord-card{ - border:1px solid rgba(255,247,237,.13); - border-radius:22px; - background:linear-gradient(180deg,rgba(71,40,21,.78),rgba(43,25,15,.56)); - padding:12px; - color:var(--text); - cursor:pointer; - box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 10px 22px rgba(0,0,0,.16); -} -.chord-card:active{transform:scale(.985)} -.chord-card-head{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:8px} -.chord-name{font-size:24px;line-height:1;font-weight:950;color:var(--accent);letter-spacing:-.04em} -.chord-notes{font-size:11px;color:var(--muted);line-height:1.25;text-align:right} -.diagram{width:100%;height:auto;display:block;background:rgba(18,9,4,.30);border-radius:14px;padding:4px} -.diagram line{stroke:rgba(255,247,237,.42);stroke-width:2;stroke-linecap:round} -.diagram .fret{stroke:rgba(234,149,22,.40);stroke-width:3} -.diagram circle{fill:var(--accent);filter:drop-shadow(0 4px 8px rgba(0,0,0,.32))} -.diagram text{fill:rgba(255,247,237,.78);font-size:10px;font-weight:800} - -/* CHORD MODAL */ -.chord-modal,.app-modal{ - position:fixed;inset:0;z-index:80;display:none;align-items:center;justify-content:center;padding:22px;background:rgba(5,2,1,.72);backdrop-filter:blur(10px) -} -.chord-modal.visible,.app-modal.visible{display:flex} -.chord-modal-card,.app-modal-card{ - position:relative;width:min(92vw,390px);max-height:88svh;overflow:auto;border-radius:30px;border:1px solid rgba(255,247,237,.14);background:linear-gradient(180deg,#3b2112,#1a0f08);box-shadow:0 28px 70px rgba(0,0,0,.55);padding:18px -} -.modal-close,.app-modal-close{position:absolute;right:12px;top:10px;width:40px;height:40px;border:0;border-radius:999px;background:rgba(18,9,4,.58);color:var(--muted);font-size:26px;line-height:1;cursor:pointer;z-index:3} -.modal-chord-title{margin:10px 44px 6px 0;font-size:42px;line-height:1;font-weight:950;color:var(--accent);letter-spacing:-.06em} -.modal-chord-sub{margin:0 44px 16px 0;color:var(--muted);font-size:13px;line-height:1.35} -.modal-diagram{width:100%;max-width:320px;margin:0 auto;display:block;background:rgba(18,9,4,.38);border-radius:24px;padding:12px;border:1px solid rgba(255,247,237,.10)} -.modal-diagram line{stroke:rgba(255,247,237,.46);stroke-width:2.2;stroke-linecap:round} -.modal-diagram .fret{stroke:rgba(234,149,22,.48);stroke-width:4} -.modal-diagram circle{fill:var(--accent);filter:drop-shadow(0 6px 10px rgba(0,0,0,.36))} -.modal-diagram text{fill:rgba(255,247,237,.82);font-size:12px;font-weight:900} - -/* METRONOME */ -.metro-layout{display:grid;gap:14px} -.metro-display{display:grid;place-items:center;gap:14px;text-align:center} -.bpm-dial{ - width:190px;height:190px;border-radius:999px;display:grid;place-items:center;position:relative;touch-action:none;user-select:none;cursor:pointer; - background:radial-gradient(circle at 50% 38%,rgba(234,149,22,.18),transparent 52%),linear-gradient(180deg,rgba(59,33,18,.92),rgba(18,9,4,.68)); - border:1px solid rgba(255,247,237,.13);box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 18px 36px rgba(0,0,0,.28) -} -.bpm-dial::before{content:"";position:absolute;inset:12px;border-radius:999px;border:1px dashed rgba(234,149,22,.25)} -.bpm{position:relative;z-index:2;font-size:54px;font-weight:950;line-height:.9;color:var(--text);letter-spacing:-.06em} -.bpm small{display:block;margin-top:6px;font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)} -.meter-in-dial{position:absolute;bottom:40px;z-index:2;color:var(--accent);font-weight:900;font-size:13px} -.bpm-slider{width:100%;accent-color:var(--accent)} -.preset-grid,.meter-buttons,.accent-buttons{display:grid;grid-template-columns:repeat(3,1fr);gap:8px} -.preset-bpm,.meter-btn,.accent-btn{border:1px solid rgba(255,247,237,.13);border-radius:16px;background:rgba(18,9,4,.48);color:var(--muted);padding:10px 6px;font-weight:850;cursor:pointer} -.preset-bpm.active,.meter-btn.active,.accent-btn.active{background:rgba(234,149,22,.18);border-color:rgba(234,149,22,.44);color:var(--accent)} -.beats{position:relative;display:flex;justify-content:center;gap:10px;padding:14px;border-radius:22px;background:rgba(18,9,4,.42);border:1px solid rgba(255,247,237,.10)} -.beat{width:18px;height:18px;border-radius:999px;background:rgba(255,247,237,.18);box-shadow:inset 0 1px 0 rgba(255,255,255,.12);transition:transform .08s ease,background .08s ease,box-shadow .08s ease} -.beat.active{transform:scale(1.24);background:var(--accent);box-shadow:0 0 18px rgba(234,149,22,.45)} -.beat.accent{border:2px solid rgba(34,197,94,.85)} -.metro-controls{display:grid;grid-template-columns:1fr 1fr;gap:10px} -.metro-start{font-size:18px;padding:15px 16px;border-radius:20px} -.metro-reset{padding:15px 16px;border-radius:20px} - -@media (max-width:430px){ - .view-screen{padding:20px 14px 22px} - .view-card{padding:14px;border-radius:22px} - .chord-grid{grid-template-columns:1fr 1fr;gap:10px} - .chord-name{font-size:21px} - .diagram text{font-size:9px} - .bpm-dial{width:170px;height:170px} - .bpm{font-size:48px} - .preset-grid,.meter-buttons,.accent-buttons{gap:7px} - .preset-bpm,.meter-btn,.accent-btn{font-size:12px;padding:9px 4px} -} - -/* ===================================================== - IMPORT Z PLIKU WZORCOWEGO — FORMATOWANIE WIDOKÓW I MODALI - ===================================================== */ - -/* widoki narzędzi: bardziej zwarte, jednolita karta jak w pliku wzorcowym */ -.view-screen{ - position:relative; - overflow:hidden; - padding:16px 14px 20px; - background: - radial-gradient(circle at 50% 0%, rgba(234,149,22,.07), transparent 18rem), - linear-gradient(180deg, rgba(59,33,18,.44), rgba(18,9,4,.60)); -} - -.view-head{ - margin:0 0 14px; -} - -.view-title{ - font-size:clamp(22px,5.4vw,30px); - font-weight:850; - letter-spacing:-.045em; -} - -.view-card{ - padding:14px; + border:1px solid rgba(255,255,255,.10); border-radius:14px; + padding:14px; background: radial-gradient(circle at 16% 0%, rgba(234,149,22,.08), transparent 180px), linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,.012)), linear-gradient(145deg, rgba(43,25,15,.72), rgba(18,9,4,.72)); - border:1px solid rgba(255,255,255,.10); box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 12px 28px rgba(0,0,0,.22); } .view-card + .view-card{margin-top:12px} -.back-btn, -.small-action, -.ghost-btn, -.primary-btn, -.round-btn, -.filter-chip, -.preset-bpm, -.meter-btn, -.accent-btn{ - border-radius:12px!important; -} - -.form-label, -.group-label, -.transpose-heading{ +.form-label,.group-label,.transpose-heading{ + display:block; + color:#f8fafc!important; font-size:13px!important; font-weight:650!important; - color:#f8fafc!important; letter-spacing:.02em!important; text-transform:none!important; + margin:0 0 10px; } .song-input, .search-input, .output-box{ + width:100%; + border:1px solid rgba(255,255,255,.08)!important; border-radius:12px!important; background:#111827!important; - border:1px solid rgba(255,255,255,.08)!important; + color:var(--text); + padding:14px; + outline:0; + box-shadow:inset 0 1px 0 rgba(255,255,255,.04); } +.song-input{min-height:160px;resize:vertical;line-height:1.45;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:14px} +.search-input{height:48px;font-size:15px} +.song-input:focus,.search-input:focus{border-color:rgba(234,149,22,.48);box-shadow:0 0 0 3px rgba(234,149,22,.12)} .transpose-controls{ - max-width:210px; + display:grid; + grid-template-columns:48px 1fr 48px; + align-items:center; + gap:10px; margin:14px auto 12px; + max-width:210px; } .transpose-value{ + text-align:center; + color:var(--muted); + font-weight:850; + line-height:1.15; border-radius:12px; background:#111827; border:1px solid rgba(255,255,255,.08); @@ -708,33 +539,55 @@ button { font: inherit; } color:rgba(248,250,252,.62); } .transpose-value strong{ + display:block; + color:var(--accent); font-size:28px!important; font-weight:300!important; color:#f8fafc!important; + letter-spacing:-.05em; } +.transpose-actions{display:flex;gap:10px;margin-top:12px;flex-wrap:wrap} -/* klikalne akordy w wyniku transpozycji */ +.output-line{min-height:1.55em} .chord-token{ + display:inline-flex; + align-items:center; + justify-content:center; + margin:0 2px 2px; + padding:2px 8px 3px; + border:0; border-radius:10px; background:linear-gradient(180deg,#FFB83D,#EA9516); color:#111827; - border:0; + font:inherit; font-weight:850; + cursor:pointer; + vertical-align:baseline; box-shadow:0 4px 10px rgba(234,149,22,.18), inset 0 1px 0 rgba(255,255,255,.22); } +.chord-token:active{transform:scale(.96)} -/* Akordy — siatka i karta diagramu */ -.chord-grid{ - gap:10px; -} +.filter-row{display:flex;gap:8px;overflow:auto;padding:2px 2px 12px;margin:0 -2px 10px;scrollbar-width:none} +.filter-row::-webkit-scrollbar{display:none} +.filter-chip{flex:0 0 auto;padding:9px 12px;cursor:pointer} +.filter-chip.active{background:rgba(234,149,22,.18);border-color:rgba(234,149,22,.44);color:var(--accent)} + +.chord-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px} .chord-card{ + border:1px solid rgba(255,255,255,.10); border-radius:14px; background: radial-gradient(circle at 20% 0%, rgba(234,149,22,.10), transparent 120px), linear-gradient(180deg,rgba(255,255,255,.035),rgba(255,255,255,.012)), linear-gradient(145deg,rgba(43,25,15,.78),rgba(18,9,4,.68)); - border:1px solid rgba(255,255,255,.10); + padding:12px; + color:var(--text); + cursor:pointer; + box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 10px 22px rgba(0,0,0,.16); } +.chord-card:active{transform:scale(.985)} +.chord-card-head{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:8px} +.chord-name{font-size:24px;line-height:1;font-weight:950;color:var(--accent);letter-spacing:-.04em} .chord-card .chord-name, #chordGrid .chord-name{ display:inline-flex; @@ -748,13 +601,14 @@ button { font: inherit; } font-weight:850; box-shadow:0 6px 16px rgba(234,149,22,.22), inset 0 1px 0 rgba(255,255,255,.25); } -.diagram{ - background:rgba(17,24,39,.70); - border:1px solid rgba(255,255,255,.07); - border-radius:12px; -} +.chord-notes{font-size:11px;color:var(--muted);line-height:1.25;text-align:right} +.diagram{width:100%;height:auto;display:block;background:rgba(17,24,39,.70);border-radius:12px;padding:4px;border:1px solid rgba(255,255,255,.07)} +.diagram line{stroke:rgba(255,247,237,.42);stroke-width:2;stroke-linecap:round} +.diagram .fret{stroke:rgba(234,149,22,.40);stroke-width:3} +.diagram circle{fill:var(--accent);filter:drop-shadow(0 4px 8px rgba(0,0,0,.32))} +.diagram text{fill:rgba(255,247,237,.78);font-size:10px;font-weight:800} -/* Modal akordu — powiększona karta z legendą jak w pliku wzorcowym */ +/* CHORD MODAL */ .chord-modal, .app-modal, .metro-visual-modal{ @@ -873,9 +727,9 @@ button { font: inherit; } .app-modal-card h2{margin:0 42px 14px 0;font-size:22px;letter-spacing:-.03em} .app-modal-card p{color:rgba(248,250,252,.78);line-height:1.45;margin:0 0 14px} -/* Metronom — czytelne sekcje i modal wizualny */ +/* Metronom — responsywne skalowanie */ .metro-layout{display:grid;gap:12px} -.metro-display{padding:16px!important} +.metro-display{display:grid;place-items:center;gap:14px;text-align:center;padding:16px!important} .bpm-dial{ width:190px; height:190px; @@ -901,6 +755,7 @@ button { font: inherit; } background:rgba(17,24,39,.66); color:#f8fafc; font-weight:700; + padding:10px 6px; } .preset-bpm.active,.meter-btn.active,.accent-btn.active{ background:rgba(234,149,22,.18); @@ -998,9 +853,9 @@ button { font: inherit; } transform:translateX(-50%); width:94px; height:38px; - border-radius:18px; - background:rgba(255,255,255,.08); - border:1px solid rgba(255,255,255,.12); + border-radius:50%; + background:linear-gradient(180deg,#FFB83D,#EA9516); + box-shadow:0 12px 28px rgba(234,149,22,.35); } .metro-visual-center{position:absolute;display:grid;place-items:center;gap:2px} .metro-visual-center strong{font-size:48px;font-weight:300;letter-spacing:-.06em} @@ -1008,6 +863,7 @@ button { font: inherit; } .metro-visual-center em{font-style:normal;color:rgba(248,250,252,.62);font-size:13px} .metro-big-beats{display:flex;justify-content:center;gap:10px;margin:8px 0 14px} .metro-modal-controls{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:12px} + @keyframes metroSwing{ from{transform:translateX(-50%) rotate(-24deg)} to{transform:translateX(-50%) rotate(24deg)} @@ -1025,3784 +881,211 @@ button { font: inherit; } } /* ===================================================== - EasyTune v2.5 — CZYSTY METRONOM + EasyTune v56 — RESPONSYWNY METRONOM ===================================================== */ + .metro-clean-screen{ - padding:16px 14px 20px!important; -} -.metro-clean-screen .view-head{ - margin-bottom:14px!important; + --metro-scale: 1; + --metro-visual-width: 360px; + --metro-visual-ratio: 1.16; + padding: clamp(12px, 2vh, 20px) clamp(12px, 1.5vw, 18px) clamp(14px, 2vh, 24px) !important; } + .metro-clean-main{ - display:grid; - gap:14px; + width: min(100%, 760px) !important; + margin: 0 auto !important; + display: grid; + gap: clamp(10px, 1.8vh, 18px) !important; + justify-items: stretch !important; } + .metro-clean-visual{ - --metro-duration:.6s; - position:relative; - width:100%; - min-height:420px; - border-radius:24px; - overflow:hidden; - display:grid; - place-items:center; + --metro-duration: .6s; + width: min(100%, var(--metro-visual-width)) !important; + height: calc(var(--metro-visual-width) * var(--metro-visual-ratio)) !important; + min-height: 0 !important; + margin: 0 auto !important; + position: relative; + border-radius: clamp(18px, calc(24px * var(--metro-scale)), 28px) !important; + overflow: hidden; + display: grid; + place-items: center; background: radial-gradient(circle at 50% 46%, rgba(234,149,22,.14), transparent 54%), - linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.018)), - linear-gradient(145deg,#111a22,#070d13); - border:1px solid rgba(234,149,22,.24); - box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35); + linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.018)), + linear-gradient(145deg, #111a22, #070d13); + border: 1px solid rgba(234,149,22,.24); + box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 24px 60px rgba(0,0,0,.35); } + .metro-clean-visual::before{ - content:""; - position:absolute; - left:50%; - top:50%; - width:min(300px,68vw); - height:min(300px,68vw); - transform:translate(-50%,-50%); - border-radius:50%; - border:2px solid rgba(234,149,22,.22); - background:radial-gradient(circle, rgba(234,149,22,.10), transparent 62%); -} -.metro-clean-visual.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit{ - border-color:rgba(234,149,22,.82); - box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 0 0 3px rgba(234,149,22,.16),0 0 64px rgba(234,149,22,.24),0 24px 60px rgba(0,0,0,.40); -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .22s ease-out 1; - border-color:rgba(234,149,22,.86); -} -@keyframes metroBeatFlash{ - 0%{transform:translate(-50%,-50%) scale(.92);opacity:.56} - 50%{transform:translate(-50%,-50%) scale(1.10);opacity:1} - 100%{transform:translate(-50%,-50%) scale(1);opacity:.72} -} -@keyframes metroAccentFlash{ - 0%{transform:translate(-50%,-50%) scale(.90);opacity:.68} - 50%{transform:translate(-50%,-50%) scale(1.16);opacity:1;box-shadow:0 0 110px rgba(234,149,22,.55)} - 100%{transform:translate(-50%,-50%) scale(1);opacity:.78} + content: ""; + position: absolute; + left: 50%; + top: 50%; + width: calc(300px * var(--metro-scale)) !important; + height: calc(300px * var(--metro-scale)) !important; + transform: translate(-50%, -50%); + border-radius: 50%; + border: 2px solid rgba(234,149,22,.22); + background: radial-gradient(circle, rgba(234,149,22,.10), transparent 62%); } + .metro-clean-scale{ - position:absolute; - left:50%; - top:56px; - width:190px; - height:78px; - transform:translateX(-50%); - border:2px solid rgba(255,214,160,.24); - border-bottom:0; - border-radius:190px 190px 0 0; + position: absolute; + top: calc(56px * var(--metro-scale)) !important; + left: 50%; + transform: translateX(-50%); + width: calc(190px * var(--metro-scale)) !important; + height: calc(78px * var(--metro-scale)) !important; + border-radius: calc(190px * var(--metro-scale)) calc(190px * var(--metro-scale)) 0 0 !important; + border: 1px solid rgba(234,149,22,.22); + background: radial-gradient(circle at 50% 0%, rgba(234,149,22,.12), transparent 66%); } + .metro-clean-scale::before, .metro-clean-scale::after{ - content:""; - position:absolute; - top:44px; - width:36px; - height:2px; - background:rgba(255,214,160,.30); + content: ""; + position: absolute; + top: calc(44px * var(--metro-scale)) !important; + width: calc(36px * var(--metro-scale)) !important; + height: calc(36px * var(--metro-scale)) !important; + border-radius: 50%; + background: rgba(234,149,22,.16); + box-shadow: inset 0 1px 0 rgba(255,255,255,.08); } -.metro-clean-scale::before{left:18px;transform:rotate(32deg)} -.metro-clean-scale::after{right:18px;transform:rotate(-32deg)} + +.metro-clean-scale::before{ + left: calc(18px * var(--metro-scale)) !important; +} + +.metro-clean-scale::after{ + right: calc(18px * var(--metro-scale)) !important; +} + .metro-clean-pendulum{ - position:absolute; - left:50%; - top:74px; - z-index:2; - width:4px; - height:230px; - transform-origin:50% 100%; - background:linear-gradient(180deg,#ffd68a,#EA9516); - border-radius:999px; - box-shadow:0 0 22px rgba(234,149,22,.38); - animation:metroCleanSwing var(--metro-duration) ease-in-out infinite alternate paused; + position: absolute; + top: calc(74px * var(--metro-scale)) !important; + left: 50%; + width: max(3px, calc(4px * var(--metro-scale))) !important; + height: calc(230px * var(--metro-scale)) !important; + transform-origin: 50% 0; + transform: translateX(-50%) rotate(-38deg); + background: linear-gradient(180deg, rgba(248,250,252,.76), rgba(234,149,22,.76)); + border-radius: 999px; + animation: metroSwing var(--metro-duration) ease-in-out infinite alternate; + animation-play-state: paused; } -.metro-clean-visual.running .metro-clean-pendulum{animation-play-state:running} -.metro-clean-pendulum span{ - position:absolute; - left:50%; - bottom:-17px; - width:34px; - height:34px; - transform:translateX(-50%); - border-radius:50%; - background:#EA9516; - box-shadow:0 0 26px rgba(234,149,22,.70); -} -@keyframes metroCleanSwing{ - from{transform:translateX(-50%) rotate(-38deg)} - to{transform:translateX(-50%) rotate(38deg)} -} -.metro-clean-bpm{ - position:relative; - z-index:3; - border:0!important; - background:transparent!important; - box-shadow:none!important; - color:#f8fafc!important; - display:grid!important; - place-items:center!important; - padding:10px 16px!important; - min-width:150px; - border-radius:18px!important; -} -.metro-clean-bpm strong{ - font-size:clamp(72px,18vw,112px); - line-height:.9; - font-weight:250; - letter-spacing:-.08em; -} -.metro-clean-bpm span{ - margin-top:10px; - font-size:16px; - font-weight:300; - letter-spacing:.12em; - color:rgba(248,250,252,.72); -} -.metro-clean-beats{ - display:flex; - justify-content:center; - align-items:center; - gap:12px; - min-height:62px; - padding:16px 12px; - border-radius:16px; - background:rgba(4,9,14,.42); - border:1px solid rgba(255,255,255,.10); -} -.beat-wrap{display:grid;justify-items:center;gap:6px} -.beat-number{font-size:12px;font-weight:600;color:rgba(248,250,252,.54)} -.beat-number.active{color:#ffd68a} -.metro-clean-beats .beat{ - width:18px;height:18px;border-radius:50%;background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.10); -} -.metro-clean-beats .beat.active{background:#EA9516;box-shadow:0 0 18px rgba(234,149,22,.65);transform:scale(1.16)} -.metro-clean-beats .beat.accent{border-color:#ffd68a;box-shadow:0 0 0 2px rgba(234,149,22,.14)} -.metro-clean-meta{ - display:grid; - grid-template-columns:repeat(3,1fr); - gap:10px; - margin:0; -} -.metro-clean-meta button{ - min-height:62px!important; - border-radius:14px!important; - padding:10px 8px!important; - display:grid!important; - gap:6px!important; - text-align:center!important; - background:rgba(4,9,14,.42)!important; - border:1px solid rgba(255,255,255,.10)!important; -} -.metro-clean-meta span{font-size:12px;font-weight:300;color:rgba(248,250,252,.62)} -.metro-clean-meta strong{font-size:18px;font-weight:350;color:#ffd68a;line-height:1} -.metro-clean-actions{display:grid;grid-template-columns:1fr 1.4fr;gap:10px} -.metro-clean-actions .primary-btn,.metro-clean-actions .ghost-btn{min-height:56px!important;border-radius:14px!important;font-size:18px!important} -.metro-settings-modal{ - position:fixed; - inset:0; - z-index:100; - display:none; - align-items:center; - justify-content:center; - padding:14px; - background:rgba(0,0,0,.68); - backdrop-filter:blur(10px); -} -.metro-settings-modal.visible{display:flex} -.metro-settings-card{ - position:relative; - width:min(410px,94vw); - max-height:calc(100dvh - 28px); - overflow:auto; - border-radius:22px; - padding:24px 18px 18px; - background:radial-gradient(circle at 50% 0%, rgba(234,149,22,.10), transparent 18rem),linear-gradient(145deg,#121b25,#050a10); - border:1px solid rgba(255,255,255,.14); - box-shadow:0 34px 90px rgba(0,0,0,.56); -} -.metro-settings-card h2{margin:0 44px 18px 0;font-size:22px;font-weight:300;color:#f8fafc} -.metro-settings-close{ - position:absolute!important;right:12px!important;top:12px!important;width:36px!important;height:36px!important;min-width:36px!important;padding:0!important;border:0!important;border-radius:50%!important;background:rgba(255,255,255,.045)!important;color:#f8fafc!important;font-size:28px!important;line-height:1!important; -} -.metro-bpm-stepper{display:grid;grid-template-columns:56px 1fr 56px;align-items:center;gap:8px;margin:0 0 14px} -.metro-bpm-stepper button{height:54px!important;border-radius:14px!important;font-size:28px!important;color:#EA9516!important} -.metro-bpm-stepper strong{text-align:center;font-size:56px;font-weight:250;line-height:1;color:#f8fafc} -.metro-settings-card .bpm-slider{width:100%;accent-color:#EA9516;margin:6px 0 16px} -.metro-settings-card .preset-grid,.metro-settings-card .meter-buttons,.metro-settings-card .accent-buttons{display:grid;grid-template-columns:repeat(3,1fr);gap:8px} -.metro-settings-card .preset-bpm,.metro-settings-card .meter-btn,.metro-settings-card .accent-btn{min-height:46px!important;border-radius:12px!important;font-size:15px!important;font-weight:400!important} -.metro-settings-card .preset-bpm.active,.metro-settings-card .meter-btn.active,.metro-settings-card .accent-btn.active{background:linear-gradient(180deg,#FFB83D,#EA9516)!important;color:#111827!important;border-color:rgba(255,210,120,.70)!important} -@media(max-width:430px){ - .metro-clean-screen{padding:14px 12px 18px!important} - .metro-clean-visual{min-height:390px;border-radius:22px} - .metro-clean-scale{top:52px;width:168px;height:70px} - .metro-clean-pendulum{top:68px;height:205px} - .metro-clean-meta{gap:8px} - .metro-clean-meta button{min-height:58px!important;padding:9px 4px!important} - .metro-clean-meta strong{font-size:16px} - .metro-clean-actions{grid-template-columns:1fr 1fr} -} - - -/* ===================================================== - EasyTune v2.5.1 — Metronom bez dodatkowego półkola/skali - ===================================================== */ - -/* Usuwa dodatkowy rysunek półkola ze wskazówkami nad wahadłem */ -.metro-clean-scale, -.metro-arc { - display: none !important; -} - -/* Czyści ewentualne pseudo-elementy skali */ -.metro-clean-scale::before, -.metro-clean-scale::after, -.metro-arc::before, -.metro-arc::after { - content: none !important; - display: none !important; -} - -/* Metronom zostaje prostszy: tło + wahadło + BPM */ -.metro-clean-visual { - background: - radial-gradient(circle at center, rgba(234,149,22,.10), transparent 58%), - linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.018)), - #081018 !important; -} - - -/* v2.5.2 metronome cleanup */ -#tapTempoBtn, .tap-tempo, .tap-tempo-wrap { display:none !important; } - -.metro-visual-card{ - display:flex; - flex-direction:column; -} -.metro-big-beats{ - order:2 !important; - margin:0 0 16px 0 !important; -} -.metro-pendulum, -.metro-visual, -.metro-clean-visual{ - order:3 !important; -} - - -/* v2.5.3 */ -#tapTempoBtnMain,.tap-tempo-main,.metro-main-tap{display:none!important;} - -/* Start/Stop wider */ -.metro-start-stop, -#startStopBtn, -.start-stop-btn{ - width:100%!important; - min-width:220px!important; -} - -/* BPM modal Tap Tempo centered and wider */ -#tapTempoBtn, -.tap-tempo-btn{ - display:block!important; - margin:12px auto!important; - min-width:220px!important; - width:70%!important; -} - -/* tooltip/help */ -.tap-tempo-help{ - text-align:center; - font-size:.9rem; - opacity:.8; - margin-top:6px; -} - - -/* v2.5.6 metronome cleanup */ -.metro-main-tap, -#tapTempoBtnMain{ - display:none !important; -} - -#startStopBtn, -.start-stop-btn, -.metro-start-stop{ - width:100% !important; - max-width:none !important; -} - -.tap-help-modal{ - position:fixed; - inset:0; - display:none; - align-items:center; - justify-content:center; - background:rgba(0,0,0,.65); - z-index:9999; -} -.tap-help-modal.open{display:flex;} -.tap-help-card{ - max-width:320px; - padding:20px; - border-radius:18px; - background:#2b190f; - color:#fff; - text-align:center; -} -.tap-help-trigger{ - cursor:pointer; - display:inline-block; - margin-top:10px; -} - - -/* ===================================================== - EasyTune v2.5.7 — poprawiony Tap Tempo i modal informacji - ===================================================== */ - -/* Tap Tempo usunięte z głównego ekranu metronomu */ -#tapTempo { - display: none !important; -} - -/* Duży metronom/BPM nie udaje już wejścia do ustawień tempa */ -#metroCleanBpmButton { - cursor: default !important; -} - -/* Start/Stop po usunięciu Tap Tempo zajmuje całą szerokość */ -.metro-clean-actions { - display: grid !important; - grid-template-columns: 1fr !important; - gap: 10px !important; -} - -.metro-clean-actions #startMetro, -.metro-clean-actions .metro-start { - width: 100% !important; - min-height: 58px !important; -} - -/* Tap Tempo tylko w modalu tempa */ -.metro-tap-row { - display: flex !important; - align-items: center !important; - justify-content: center !important; - gap: 10px !important; - width: 100% !important; - margin: 14px auto 0 !important; -} - -#metroTapInModal.metro-tap-modal-btn { - width: min(260px, 72vw) !important; - min-width: 220px !important; - min-height: 46px !important; - margin: 0 !important; - display: inline-flex !important; - align-items: center !important; - justify-content: center !important; -} - -.metro-tap-info-btn { - width: 34px !important; - height: 34px !important; - min-width: 34px !important; - padding: 0 !important; - border-radius: 999px !important; - display: inline-flex !important; - align-items: center !important; - justify-content: center !important; - font-weight: 850 !important; - color: var(--accent, #EA9516) !important; - background: rgba(255,255,255,.06) !important; - border: 1px solid rgba(234,149,22,.45) !important; -} - -/* Modal pomocy Tap Tempo */ -.tap-help-modal { - position: fixed !important; - inset: 0 !important; - z-index: 10000 !important; - display: none !important; - align-items: center !important; - justify-content: center !important; - padding: 18px !important; - background: rgba(0,0,0,.68) !important; - backdrop-filter: blur(10px) !important; -} - -.tap-help-modal.open { - display: flex !important; -} - -.tap-help-card { - position: relative !important; - width: min(360px, 92vw) !important; - padding: 24px 20px 20px !important; - border-radius: 22px !important; - background: - radial-gradient(circle at 50% 0%, rgba(234,149,22,.12), transparent 18rem), - linear-gradient(145deg,#151f29,#081018) !important; - color: #f8fafc !important; - border: 1px solid rgba(255,255,255,.14) !important; - box-shadow: 0 34px 90px rgba(0,0,0,.56) !important; -} - -.tap-help-card h2 { - margin: 0 42px 12px 0 !important; - font-size: 22px !important; - line-height: 1.1 !important; -} - -.tap-help-card p { - margin: 0 !important; - color: rgba(248,250,252,.82) !important; - font-size: 15px !important; - line-height: 1.45 !important; -} - -.tap-help-close { - position: absolute !important; - top: 10px !important; - right: 10px !important; - width: 36px !important; - height: 36px !important; - padding: 0 !important; - border-radius: 999px !important; - background: rgba(255,255,255,.06) !important; - color: #f8fafc !important; - font-size: 26px !important; - line-height: 1 !important; -} - - -/* === EasyTune formatting polish: hierarchy, spacing, active states, radius consistency, centered chords === */ -.logo-button{ - flex-direction:column !important; - align-items:flex-start !important; - justify-content:center !important; - gap:5px !important; -} -.header-logo{ - width:min(56vw,330px) !important; - max-height:calc(var(--header-height) - 52px) !important; -} -.header-subtitle{ - display:block; - color:rgba(255,247,237,.68); - font-size:clamp(11px,2.8vw,13px); - line-height:1; - font-weight:750; - letter-spacing:.12em; - text-transform:uppercase; - white-space:nowrap; -} -.view-head{ - margin-bottom:18px !important; -} -.view-title{ - font-size:clamp(34px,8.2vw,42px) !important; - line-height:.96 !important; - letter-spacing:-.06em !important; -} -.view-card{ - border-radius:24px !important; - padding:18px !important; - margin:16px 0 24px !important; -} -.view-card + .view-card{ - margin-top:24px !important; -} -.form-label,.group-label{ - margin-bottom:12px !important; -} -.song-input,.search-input,.output-box{ - border-radius:18px !important; -} -.back-btn,.small-action,.ghost-btn,.primary-btn,.filter-chip,.preset-bpm,.meter-btn,.accent-btn,.visual-mode-btn{ - border-radius:18px !important; -} -.filter-chip.active,.preset-bpm.active,.meter-btn.active,.accent-btn.active,.visual-mode-btn.active{ - position:relative; - transform:translateY(-1px); - background:linear-gradient(180deg,rgba(255,184,61,.26),rgba(234,149,22,.18)) !important; - border-color:rgba(255,184,61,.68) !important; - color:#ffd68a !important; - box-shadow:inset 0 2px 0 rgba(255,216,138,.42),0 8px 18px rgba(0,0,0,.18) !important; -} -.tool-card{ - border-radius:24px !important; -} -.chord-card{ - border-radius:24px !important; - padding:14px 12px 16px !important; -} -.chord-card-head{ - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:8px !important; - margin:0 0 12px !important; - text-align:center !important; -} -.chord-card .chord-name,#chordGrid .chord-name{ - min-width:64px !important; - margin:0 auto !important; - font-size:24px !important; -} -.chord-notes{ - display:block !important; - width:100% !important; - color:rgba(255,247,237,.74) !important; - font-size:12px !important; - line-height:1.25 !important; - text-align:center !important; - letter-spacing:.03em !important; -} -.modal-chord-title{ - display:flex !important; - margin-left:auto !important; - margin-right:auto !important; -} -.modal-chord-sub{ - text-align:center !important; - font-size:16px !important; - letter-spacing:.03em !important; -} -@media (max-width:430px){ - .header-logo{width:min(58vw,260px) !important;} - .header-subtitle{font-size:10px;letter-spacing:.10em;} - .view-card{padding:16px !important;margin:16px 0 22px !important;} - .chord-card .chord-name,#chordGrid .chord-name{font-size:22px !important;} - .chord-notes{font-size:11px !important;} -} - -/* === EasyTune correction 2026-06-18: cleaner header, lighter text, card title spacing === */ -.header-subtitle{ - display:none !important; -} -.logo-button{ - height:var(--header-height) !important; - min-height:var(--header-height) !important; - justify-content:center !important; - align-items:flex-start !important; -} -.header-logo{ - width:min(64vw,380px) !important; - max-height:calc(var(--header-height) - 30px) !important; - object-fit:contain !important; -} -body, -button, -input, -textarea, -select, -strong, -b, -h1, -h2, -h3, -.tool-title, -.tool-desc, -.view-title, -.form-label, -.group-label, -.chord-name, -.chord-notes, -.filter-chip, -.small-action, -.primary-btn, -.ghost-btn, -.back-btn, -.round-btn, -.tap-btn, -.metro-clean-bpm strong, -.metro-clean-bpm span, -.metro-clean-meta span, -.metro-clean-meta strong, -.metro-bpm-stepper strong, -.metro-settings-card h2, -.tap-help-card h2, -.app-modal-card h2, -.modal-chord-title, -.modal-chord-sub{ - font-weight:400 !important; -} -.view-card{ - padding:20px 22px 20px !important; -} -.view-card > .form-label, -.view-card > .group-label{ - display:block !important; - padding-left:10px !important; - margin-bottom:14px !important; -} -.metro-settings-card h2, -.tap-help-card h2, -.app-modal-card h2{ - padding-left:10px !important; -} -.chord-card-head{ - padding-left:0 !important; - padding-right:0 !important; -} -.chord-card .chord-name, -#chordGrid .chord-name, -.chord-notes{ - text-align:center !important; - font-weight:400 !important; -} -@media (max-width:430px){ - .header-logo{ - width:min(66vw,300px) !important; - max-height:calc(var(--header-height) - 28px) !important; - } - .view-card{ - padding:18px 20px 18px !important; - } - .view-card > .form-label, - .view-card > .group-label{ - padding-left:8px !important; - } -} - - -/* === EasyTune verified correction: logo restored, card-title weight 500 === */ -.logo-button{ - height:var(--header-height) !important; - min-height:var(--header-height) !important; - justify-content:center !important; - align-items:flex-start !important; -} -.header-logo{ - width:min(48vw,300px) !important; - max-height:calc(var(--header-height) - 42px) !important; - height:auto !important; - object-fit:contain !important; -} -.tool-title, -.view-card > .form-label, -.view-card > .group-label, -.metro-settings-card h2, -.tap-help-card h2, -.app-modal-card h2{ - font-weight:500 !important; -} -@media (max-width:430px){ - .header-logo{ - width:min(54vw,245px) !important; - max-height:calc(var(--header-height) - 38px) !important; - } -} - -/* === EasyTune final fixes: PWA install visibility, chord diagrams, chord filters, metronome accents === */ -html.pwa-installed [data-pwa-install]{ - display:none !important; -} -#chordSearch.search-input{ - margin-bottom:18px !important; -} -#filterRow.filter-row{ - gap:6px !important; - padding:6px 2px 16px !important; - margin:2px -2px 16px !important; -} -#filterRow .filter-chip{ - font-size:11px !important; - font-weight:400 !important; - line-height:1 !important; - padding:7px 9px !important; - border-radius:999px !important; - letter-spacing:.01em !important; -} -.chord-card{ - text-align:center !important; -} -.chord-card-head{ - align-items:center !important; - justify-content:center !important; - text-align:center !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - display:inline-flex !important; - align-items:center !important; - justify-content:center !important; - min-width:58px !important; - padding:7px 12px !important; - border:1px solid rgba(255,247,237,.18) !important; - background:rgba(255,247,237,.035) !important; - box-shadow:none !important; -} -.chord-notes{ - text-align:center !important; - margin-top:0 !important; -} -.diagram, -.modal-diagram{ - display:block !important; - margin-left:auto !important; - margin-right:auto !important; - height:auto !important; -} -.diagram{width:min(170px,100%) !important;} -.modal-diagram{width:min(280px,86vw) !important;} -.diagram line, -.modal-diagram line{ - stroke:rgba(255,247,237,.48); - stroke-width:1.15; - stroke-linecap:round; -} -.diagram .fret, -.modal-diagram .fret{ - stroke:rgba(255,247,237,.62); -} -.diagram .nut, -.modal-diagram .nut{ - stroke:rgba(255,247,237,.88); - stroke-width:3.6; -} -.diagram text, -.modal-diagram text{ - fill:rgba(255,247,237,.70); - font-size:12px; - font-weight:400; - text-anchor:middle; - dominant-baseline:middle; -} -.modal-diagram text{font-size:14px;} -.diagram .fret-number, -.modal-diagram .fret-number{ - fill:rgba(255,247,237,.62); - font-size:11px; -} -.modal-diagram .fret-number{font-size:13px;} -.diagram circle, -.modal-diagram circle{ - fill:#EA9516 !important; -} - -.diagram .string-state, -.modal-diagram .string-state{ - font-size:22px !important; - font-weight:800 !important; - line-height:1 !important; - text-anchor:middle !important; - dominant-baseline:middle !important; -} -.diagram .state-open, -.modal-diagram .state-open{ - fill:#55d36a !important; - color:#55d36a !important; -} -.diagram .state-muted, -.modal-diagram .state-muted{ - fill:#ff6b6b !important; - color:#ff6b6b !important; -} -.diagram .state-open{font-size:20px !important;} -.diagram .state-muted{font-size:20px !important;} -.modal-diagram .state-open{font-size:24px !important;} -.modal-diagram .state-muted{font-size:24px !important;} -.metro-clean-beats .beat{ - border:2px solid transparent !important; -} -.metro-clean-beats .beat.accent{ - border-color:rgba(255,214,138,.86) !important; - box-shadow:0 0 0 2px rgba(234,149,22,.13) !important; -} -.metro-clean-beats .beat.active{ - background:#EA9516 !important; - box-shadow:0 0 18px rgba(234,149,22,.65) !important; -} -.metro-clean-beats .beat.active.accent{ - background:#22c55e !important; - box-shadow:0 0 18px rgba(34,197,94,.42),0 0 0 2px rgba(234,149,22,.13) !important; -} -@media (max-width:430px){ - #filterRow .filter-chip{font-size:10.5px !important;padding:6px 8px !important;} - .diagram{width:min(158px,100%) !important;} -} - -/* === EasyTune chord verification fixes: correct fret positions and O/X markers === */ -.diagram .finger-dot, -.modal-diagram .finger-dot{ - fill:#EA9516 !important; - stroke:none !important; -} -.diagram .state-open, -.modal-diagram .state-open{ - fill:rgba(0,0,0,0) !important; - stroke:#55d36a !important; - stroke-width:2.4 !important; - filter:none !important; -} -.diagram .state-muted line, -.modal-diagram .state-muted line{ - stroke:#ff6b6b !important; - stroke-width:2.4 !important; - stroke-linecap:round !important; - filter:none !important; -} - -/* === EasyTune follow-up: colored chord legend and compact chord cards === */ -#chord-modal-content::after{ - content:none !important; - display:none !important; -} -.chord-legend{ - display:flex !important; - flex-direction:column !important; - gap:4px !important; - width:min(300px,82vw) !important; - margin:6px auto 0 !important; - color:rgba(248,250,252,.78) !important; - font-size:14px !important; - line-height:1.45 !important; - text-align:left !important; -} -.chord-legend span{ - display:flex !important; - align-items:center !important; - gap:9px !important; -} -.chord-legend b{ - display:inline-flex !important; - align-items:center !important; - justify-content:center !important; - min-width:22px !important; - height:22px !important; - font-size:18px !important; - line-height:1 !important; - font-weight:800 !important; -} -.chord-legend .legend-o{color:#55d36a !important;} -.chord-legend .legend-x{color:#ff6b6b !important;} -.chord-legend .legend-fret{ - color:rgba(255,247,237,.78) !important; - font-size:13px !important; - font-weight:500 !important; - min-width:58px !important; - justify-content:flex-start !important; -} -.chord-card{ - padding:12px 10px 8px !important; - gap:0 !important; -} -.chord-card-head{ - margin:0 0 6px !important; - gap:6px !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - color:#fff7ed !important; - background:linear-gradient(135deg, rgba(234,149,22,.98), rgba(251,176,59,.84)) !important; - border:1px solid rgba(255,214,138,.44) !important; - box-shadow:0 8px 18px rgba(234,149,22,.18) !important; - padding:6px 13px !important; -} -.chord-notes{ - margin-top:0 !important; - margin-bottom:0 !important; - line-height:1.18 !important; -} -.chord-card .diagram{ - margin-top:0 !important; - margin-bottom:-8px !important; -} -@media (max-width:430px){ - .chord-card{padding:10px 8px 6px !important;} - .chord-card-head{margin-bottom:4px !important;} - .chord-card .diagram{margin-bottom:-10px !important;} -} - - -/* === EasyTune v6: calmer chord controls and balanced chord cards === */ -#chordSearch.search-input{ - display:block !important; - width:min(280px, 100%) !important; - max-width:280px !important; - margin:0 auto 16px !important; - text-align:center !important; - padding-left:18px !important; - padding-right:18px !important; -} -#filterRow.filter-row{ - display:flex !important; - flex-wrap:wrap !important; - justify-content:center !important; - align-items:center !important; - gap:6px !important; - max-width:330px !important; - margin:0 auto 18px !important; - padding:0 !important; -} -#filterRow .filter-chip{ - flex:0 0 auto !important; - min-width:0 !important; - font-size:10.5px !important; - font-weight:400 !important; - padding:6px 8px !important; - border-width:1px !important; - box-shadow:none !important; -} -.chord-card{ - padding:11px 9px 8px !important; -} -.chord-card-head{ - margin-bottom:5px !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - min-width:46px !important; - padding:4px 10px !important; - border-width:1px !important; - border-color:rgba(255,214,138,.30) !important; - border-radius:12px !important; - box-shadow:0 5px 12px rgba(234,149,22,.12) !important; -} -.chord-card .diagram{ - width:min(164px,100%) !important; - margin-bottom:-4px !important; -} -@media (max-width:430px){ - #chordSearch.search-input{width:min(250px,100%) !important;max-width:250px !important;} - #filterRow.filter-row{max-width:310px !important;gap:5px !important;} - #filterRow .filter-chip{font-size:10px !important;padding:6px 7px !important;} - .chord-card{padding:10px 8px 7px !important;} - .chord-card .diagram{width:min(160px,100%) !important;margin-bottom:-4px !important;} -} - - -/* === EasyTune v7: chord tile spacing and centered diagrams === */ -.chord-grid{ - gap:16px 12px !important; - align-items:start !important; -} -.chord-card{ - padding:10px 9px 10px !important; - overflow:visible !important; - min-height:auto !important; -} -.chord-card-head{ - margin-bottom:5px !important; -} -.chord-card .diagram{ - display:block !important; - width:min(166px,100%) !important; - height:auto !important; - margin:0 auto !important; -} -.chord-card .chord-name,#chordGrid .chord-name{ - padding:3px 8px !important; - min-width:40px !important; - border-radius:10px !important; - border-color:rgba(255,214,138,.26) !important; - box-shadow:0 3px 8px rgba(234,149,22,.10) !important; -} -.diagram .fret-number{ - font-size:14px !important; - font-weight:700 !important; -} -.modal-diagram .fret-number{ - font-size:15px !important; - font-weight:700 !important; -} -.diagram .state-open{ - stroke-width:2 !important; -} -.diagram .state-muted line{ - stroke-width:2.2 !important; -} -.modal-diagram .state-open{ - stroke-width:2.4 !important; -} -.modal-diagram .state-muted line{ - stroke-width:2.6 !important; -} -@media (max-width:430px){ - .chord-grid{gap:15px 10px !important;} - .chord-card{padding:9px 8px 10px !important;} - .chord-card .diagram{width:min(162px,100%) !important;margin:0 auto !important;} -} - - -/* === EasyTune v8: compact unified chord cards === */ -.chord-grid{ - gap:22px 12px !important; - align-items:start !important; -} -.chord-card{ - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:flex-start !important; - padding:11px 9px 12px !important; - overflow:visible !important; - border:1px solid rgba(234,149,22,.18) !important; - background:linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.025)) !important; -} -.chord-card-head{ - width:100% !important; - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:3px !important; - margin:0 0 4px !important; - padding:0 !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - display:block !important; - min-width:0 !important; - padding:0 !important; - border:0 !important; - border-radius:0 !important; - background:transparent !important; - box-shadow:none !important; - color:var(--accent) !important; - font-size:19px !important; - line-height:1.05 !important; - font-weight:760 !important; - letter-spacing:-.025em !important; - text-align:center !important; -} -.chord-card .chord-notes, -#chordGrid .chord-notes{ - display:block !important; - width:100% !important; - max-width:100% !important; - text-align:center !important; - font-size:10.5px !important; - line-height:1.15 !important; - font-weight:520 !important; - color:rgba(248,250,252,.72) !important; - padding:0 !important; - margin:0 !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; -} -.chord-card .diagram{ - display:block !important; - width:min(166px,100%) !important; - height:auto !important; - margin:0 auto !important; - padding:0 !important; - overflow:visible !important; -} -.diagram .fret-number{ - font-size:15px !important; - font-weight:760 !important; -} -.diagram .state-open{ - stroke-width:1.9 !important; -} -.diagram .state-muted line{ - stroke-width:2 !important; -} -.modal-diagram .state-open{ - stroke-width:2.2 !important; -} -.modal-diagram .state-muted line{ - stroke-width:2.35 !important; -} -@media (max-width:430px){ - .chord-grid{gap:20px 10px !important;} - .chord-card{padding:10px 8px 11px !important;} - .chord-card .chord-name,#chordGrid .chord-name{font-size:18px !important;} - .chord-card .diagram{width:min(162px,100%) !important;margin:0 auto !important;} -} - - -/* === EasyTune v9: unified chord surfaces, balanced string states, no white focus frame === */ -.tool-card:focus, -.tool-card:focus-visible, -.chord-card:focus, -.chord-card:focus-visible, -.back-btn:focus, -.back-btn:focus-visible, -.small-action:focus, -.small-action:focus-visible, -.ghost-btn:focus, -.ghost-btn:focus-visible, -.primary-btn:focus, -.primary-btn:focus-visible, -.round-btn:focus, -.round-btn:focus-visible, -.options-button:focus, -.options-button:focus-visible{ - outline:0 !important; - box-shadow:inherit !important; -} -.tool-card{ -webkit-tap-highlight-color:transparent !important; } -.chord-grid{ - gap:20px 12px !important; -} -.chord-card{ - padding:12px 10px 14px !important; - border:1px solid rgba(255,255,255,.12) !important; - border-radius:24px !important; - background: - radial-gradient(circle at 50% 0%, rgba(234,149,22,.08), transparent 12rem), - linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.018)), - linear-gradient(145deg,#111a22,#070d13) !important; - box-shadow:0 12px 30px rgba(0,0,0,.26), inset 0 1px 0 rgba(255,255,255,.05) !important; -} -.chord-card-head{ - margin:0 0 5px !important; -} -.chord-card .chord-name, -#chordGrid .chord-name, -.modal-chord-title{ - display:inline-flex !important; - align-items:center !important; - justify-content:center !important; - background:linear-gradient(180deg,#FFB83D,#EA9516) !important; - color:#111827 !important; - border:1px solid rgba(255,218,160,.28) !important; - box-shadow:0 4px 12px rgba(234,149,22,.18), inset 0 1px 0 rgba(255,255,255,.25) !important; - letter-spacing:-.035em !important; - text-align:center !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - min-width:42px !important; - min-height:30px !important; - padding:4px 10px !important; - border-radius:11px !important; - font-size:16px !important; - line-height:1 !important; - font-weight:780 !important; -} -.modal-chord-title{ - min-width:82px !important; - min-height:54px !important; - padding:6px 12px !important; - border-radius:13px !important; - font-size:36px !important; - line-height:1 !important; - font-weight:820 !important; - margin:0 auto 10px !important; -} -.chord-card .chord-notes, -#chordGrid .chord-notes{ - font-size:10.5px !important; - margin-top:1px !important; -} -.diagram, -.modal-diagram{ - background:transparent !important; - border:0 !important; - border-radius:0 !important; - padding:0 !important; - box-shadow:none !important; -} -.chord-card .diagram{ - width:min(164px,100%) !important; - margin:0 auto !important; -} -.diagram .fret-number{ - font-size:15px !important; - font-weight:780 !important; -} -.modal-diagram .fret-number{ - font-size:15px !important; - font-weight:780 !important; -} -.diagram .state-open, -.modal-diagram .state-open{ - fill:#38d66b !important; - stroke:#38d66b !important; - stroke-width:1.2 !important; -} -.diagram .state-muted line, -.modal-diagram .state-muted line{ - stroke:#ff4d4d !important; - stroke-width:1.7 !important; - stroke-linecap:round !important; -} -.legend-o{color:#38d66b !important;} -.legend-x{color:#ff4d4d !important;} -@media (max-width:430px){ - .chord-grid{gap:18px 10px !important;} - .chord-card{padding:11px 9px 13px !important;} - .chord-card .chord-name,#chordGrid .chord-name{font-size:15px !important;min-height:28px !important;padding:4px 9px !important;} - .chord-card .diagram{width:min(160px,100%) !important;} - .modal-chord-title{font-size:34px !important;min-width:78px !important;min-height:52px !important;} -} - - -/* === EasyTune v10: unified chord title box + home frame cleanup === */ -.start-panel.home-screen{ - border:0 !important; - outline:0 !important; - box-shadow:none !important; - border-radius:0 !important; -} -.start-panel.home-screen::before, -.start-panel.home-screen::after, -.home-screen::before, -.home-screen::after{ - border:0 !important; - outline:0 !important; - box-shadow:none !important; -} -.content:focus, -.content:focus-visible, -.start-panel:focus, -.start-panel:focus-visible, -.home-screen:focus, -.home-screen:focus-visible{ - outline:0 !important; - box-shadow:none !important; -} - -.chord-card{ - padding:12px 10px 13px !important; - gap:5px !important; -} -.chord-title-box, -.chord-card-head.chord-title-box, -.modal-chord-title-box{ - width:100% !important; - max-width:126px !important; - margin:0 auto 5px !important; - padding:0 !important; - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - overflow:hidden !important; - border-radius:13px !important; - border:1px solid rgba(255,218,160,.24) !important; - background:linear-gradient(180deg,#FFB83D,#EA9516) !important; - box-shadow:0 4px 12px rgba(234,149,22,.16), inset 0 1px 0 rgba(255,255,255,.23) !important; -} -.modal-chord-title-box{ - max-width:154px !important; - margin:0 auto 12px !important; - border-radius:14px !important; -} -.chord-card .chord-name, -#chordGrid .chord-name, -.modal-chord-title{ - display:block !important; - width:100% !important; - min-width:0 !important; - min-height:0 !important; - margin:0 !important; - padding:5px 9px 4px !important; - border:0 !important; - border-radius:0 !important; - background:transparent !important; - box-shadow:none !important; - color:#111827 !important; - text-align:center !important; - line-height:1 !important; - letter-spacing:-.03em !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - font-size:17px !important; - font-weight:800 !important; -} -.modal-chord-title{ - font-size:28px !important; - font-weight:820 !important; - padding:7px 10px 5px !important; -} -.chord-title-divider{ - display:block !important; - width:100% !important; - height:1px !important; - flex:0 0 1px !important; - background:rgba(17,24,39,.26) !important; - box-shadow:0 1px 0 rgba(255,255,255,.17) !important; -} -.chord-card .chord-notes, -#chordGrid .chord-notes, -.modal-chord-sub{ - display:block !important; - width:100% !important; - margin:0 !important; - padding:4px 7px 5px !important; - border:0 !important; - background:transparent !important; - color:rgba(17,24,39,.82) !important; - font-size:8.5px !important; - font-weight:650 !important; - line-height:1.05 !important; - text-align:center !important; - letter-spacing:.01em !important; -} -.modal-chord-sub{ - font-size:14px !important; - padding:5px 8px 7px !important; -} -.modal-chord-sub::before{content:"" !important;} -.diagram, -.modal-diagram{ - background:transparent !important; - border:0 !important; - box-shadow:none !important; - filter:none !important; -} -.chord-card .diagram{ - margin:0 auto !important; -} -.diagram .state-open, -.modal-diagram .state-open{ - r:3.4px; - stroke-width:1.1 !important; -} -.modal-diagram .state-open{r:5px;} -.diagram .state-muted line, -.modal-diagram .state-muted line{ - stroke-width:1.45 !important; -} -@media (max-width:430px){ - .chord-title-box,.chord-card-head.chord-title-box{max-width:118px !important;} - .chord-card .chord-name,#chordGrid .chord-name{font-size:16px !important;} - .chord-card .chord-notes,#chordGrid .chord-notes{font-size:8px !important;} - .modal-chord-title{font-size:27px !important;} -} - -/* === EasyTune v11: chord title geometry, legend alignment, home focus frame cleanup === */ -:focus, -:focus-visible{ - outline:0 !important; -} -#content, -#content:focus, -#content:focus-visible, -.app, -.app:focus, -.app:focus-visible, -.start-panel.home-screen, -.start-panel.home-screen:focus, -.start-panel.home-screen:focus-visible{ - outline:0 !important; - border-color:transparent !important; - box-shadow:none !important; -} -.start-panel.home-screen{ - border:0 !important; - background-clip:padding-box !important; -} -.home-screen .home-card-bg{ - border:0 !important; - box-shadow:none !important; -} -.tool-card:focus, -.tool-card:focus-visible, -.tool-card:active, -.logo-button:focus, -.logo-button:focus-visible, -.options-button:focus, -.options-button:focus-visible{ - outline:0 !important; -} - -.tool-title, -.view-card > .form-label, -.view-card > .group-label, -.metro-settings-card h2, -.tap-help-card h2, -.app-modal-card h2{ - font-weight:500 !important; - letter-spacing:.018em !important; -} - -.chord-title-box, -.chord-card-head.chord-title-box{ - width:110px !important; - min-width:110px !important; - max-width:110px !important; - margin:0 auto 6px !important; - padding:0 !important; - gap:0 !important; -} -.modal-chord-title-box{ - width:180px !important; - min-width:180px !important; - max-width:180px !important; - margin:0 auto 12px !important; - padding:0 !important; - gap:0 !important; -} -.chord-card .chord-name, -#chordGrid .chord-name, -.modal-chord-title{ - padding:6px 7px !important; - border:0 !important; - box-shadow:none !important; - background:transparent !important; - min-height:0 !important; - line-height:1 !important; - letter-spacing:-.015em !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - font-size:17px !important; - font-weight:760 !important; -} -.modal-chord-title{ - font-size:28px !important; - font-weight:760 !important; -} -.chord-title-divider{ - margin:0 !important; - height:1px !important; - flex:0 0 1px !important; -} -.chord-card .chord-notes, -#chordGrid .chord-notes, -.modal-chord-sub{ - padding:6px 7px !important; - margin:0 !important; - line-height:1 !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; -} -.chord-card .chord-notes, -#chordGrid .chord-notes{ - font-size:8.5px !important; - font-weight:620 !important; -} -.modal-chord-sub{ - font-size:14px !important; - font-weight:620 !important; -} - -.chord-legend{ - width:180px !important; - max-width:180px !important; - margin:8px auto 0 !important; - padding:0 !important; - align-items:flex-start !important; - text-align:left !important; -} -.chord-legend span{ - width:100% !important; - display:flex !important; - align-items:center !important; - justify-content:flex-start !important; - gap:8px !important; - margin:0 !important; - padding:0 !important; - text-align:left !important; -} -.chord-legend b{ - flex:0 0 18px !important; - width:18px !important; - min-width:18px !important; - max-width:18px !important; - height:18px !important; - margin:0 !important; - padding:0 !important; - display:inline-flex !important; - align-items:center !important; - justify-content:center !important; - text-align:center !important; -} -.chord-legend .legend-fret{ - flex-basis:46px !important; - width:46px !important; - min-width:46px !important; - max-width:46px !important; - justify-content:flex-start !important; - text-align:left !important; -} -@media (max-width:430px){ - .chord-title-box, - .chord-card-head.chord-title-box{ - width:110px !important; - min-width:110px !important; - max-width:110px !important; - } - .modal-chord-title-box{ - width:180px !important; - min-width:180px !important; - max-width:180px !important; - } - .chord-card .chord-name,#chordGrid .chord-name{font-size:17px !important;} - .chord-card .chord-notes,#chordGrid .chord-notes{font-size:8.5px !important;} -} - - -/* === EasyTune v12: card title weight 600 + chord card title only === */ -.tool-title, -.view-card > .form-label, -.view-card > .group-label, -.metro-settings-card h2, -.tap-help-card h2, -.app-modal-card h2, -.card-title, -.view-title, -.section-title, -.panel-title{ - font-weight:600 !important; - letter-spacing:.022em !important; -} - -.chord-card .chord-title-box, -.chord-card-head.chord-title-box{ - width:110px !important; - min-width:110px !important; - max-width:110px !important; - min-height:30px !important; - margin:0 auto 6px !important; - padding:0 !important; - border-radius:12px !important; -} - -.chord-card .chord-name, -#chordGrid .chord-name{ - font-size:17px !important; - font-weight:600 !important; - letter-spacing:.012em !important; - padding:7px 8px !important; - line-height:1 !important; -} - -.chord-card .chord-title-divider, -.chord-card .chord-notes, -#chordGrid .chord-notes{ - display:none !important; -} - -.modal-chord-title-box{ - width:180px !important; - min-width:180px !important; - max-width:180px !important; -} -.modal-chord-title{ - font-weight:600 !important; -} -@media (max-width:430px){ - .chord-card .chord-title-box, - .chord-card-head.chord-title-box{ - width:110px !important; - min-width:110px !important; - max-width:110px !important; - } - .chord-card .chord-name,#chordGrid .chord-name{font-size:17px !important;} -} - - -/* === EasyTune v13: chord layout normalization === */ -:root{ - --chord-fretboard-small:110px; - --chord-fretboard-modal:180px; -} - -/* Kafelki i modal akordu: jeden rytm paddingów, środek optyczny, zawartość ok. 80% */ -.chord-card{ - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:7px !important; - padding:12px 10px 14px !important; - min-height:auto !important; - overflow:visible !important; -} -.chord-modal-card{ - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:12px !important; -} -#chord-modal-content{ - width:100% !important; - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:12px !important; -} - -/* Ramka nazwy = szerokość właściwego gryfu, bez osobnej ramki diagramu */ -.chord-card .chord-title-box, -.chord-card-head.chord-title-box{ - width:var(--chord-fretboard-small) !important; - min-width:var(--chord-fretboard-small) !important; - max-width:var(--chord-fretboard-small) !important; - margin:0 auto 2px !important; - padding:0 !important; - border-radius:12px !important; -} -.modal-chord-title-box{ - width:var(--chord-fretboard-modal) !important; - min-width:var(--chord-fretboard-modal) !important; - max-width:var(--chord-fretboard-modal) !important; - margin:0 auto 2px !important; - padding:0 !important; - border-radius:14px !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - font-size:16px !important; - font-weight:600 !important; - letter-spacing:.012em !important; - padding:6px 7px !important; - line-height:1.05 !important; -} -.modal-chord-title{ - font-size:28px !important; - font-weight:600 !important; - letter-spacing:.01em !important; - padding:8px 9px !important; - line-height:1.05 !important; -} -.chord-title-divider{ - margin:0 !important; -} -.modal-chord-sub{ - font-size:14px !important; - font-weight:600 !important; - padding:8px 9px !important; - line-height:1.05 !important; -} -.chord-card .chord-title-divider, -.chord-card .chord-notes, -#chordGrid .chord-notes{ - display:none !important; -} - -/* Diagram jako część tego samego kontenera, bez ramki; środek zgodny z ramką nazwy */ -.chord-card .diagram{ - width:min(170px,100%) !important; - margin:0 auto !important; - padding:0 !important; - background:transparent !important; - border:0 !important; - box-shadow:none !important; - overflow:visible !important; -} -.modal-diagram{ - width:min(280px,80vw) !important; - margin:0 auto !important; - padding:0 !important; - background:transparent !important; - border:0 !important; - box-shadow:none !important; - overflow:visible !important; -} -.diagram .fret-number, -.modal-diagram .fret-number{ - font-size:16px !important; - font-weight:780 !important; - fill:rgba(255,247,237,.78) !important; -} - -/* Otwarte kółka granych pustych strun + X optycznie równe kółku */ -.diagram .state-open, -.modal-diagram .state-open{ - fill:transparent !important; - stroke:#38d66b !important; - stroke-width:1.45 !important; - filter:none !important; -} -.diagram .state-muted line, -.modal-diagram .state-muted line{ - stroke:#ff4d4d !important; - stroke-width:1.35 !important; - stroke-linecap:round !important; - filter:none !important; -} - -/* Legenda: wyrównanie i skrócona numeracja */ -.chord-legend{ - width:var(--chord-fretboard-modal) !important; - max-width:var(--chord-fretboard-modal) !important; - margin:0 auto !important; - padding:0 !important; - display:flex !important; - flex-direction:column !important; - align-items:stretch !important; - gap:5px !important; - text-align:left !important; -} -.chord-legend span{ - display:grid !important; - grid-template-columns:38px 1fr !important; - align-items:center !important; - justify-items:start !important; - gap:7px !important; - width:100% !important; - margin:0 !important; - padding:0 !important; - text-align:left !important; -} -.chord-legend b, -.chord-legend .legend-fret{ - width:38px !important; - min-width:38px !important; - max-width:38px !important; - height:auto !important; - margin:0 !important; - padding:0 !important; - display:inline-flex !important; - align-items:center !important; - justify-content:flex-start !important; - text-align:left !important; -} -.legend-o{color:#38d66b !important;} -.legend-x{color:#ff4d4d !important;} - -@media (max-width:430px){ - .chord-card{padding:11px 8px 13px !important;gap:6px !important;} - .chord-card .chord-title-box, - .chord-card-head.chord-title-box{ - width:var(--chord-fretboard-small) !important; - min-width:var(--chord-fretboard-small) !important; - max-width:var(--chord-fretboard-small) !important; - } - .chord-card .chord-name,#chordGrid .chord-name{font-size:15.5px !important;} - .modal-chord-title{font-size:27px !important;} -} - - -/* v14 adjustments */ -.chord-card{ - padding:12px 12px 8px !important; /* equal top/side */ -} -.chord-card .chord-name, -#chordGrid .chord-name{ - width:85% !important; - max-width:85% !important; - margin:0 auto !important; -} -.chord-modal-card,.app-modal-card{ - padding:12px !important; -} - - -/* === EasyTune v15: fret-number spacing and more natural titles === */ -.diagram .fret-number, -.modal-diagram .fret-number{ - text-anchor:end !important; -} - -.card-title, -.view-title, -.section-title, -.tool-title, -.panel-title, -.option-title, -.app-modal-card h2, -.metro-visual-card h2{ - font-weight:600 !important; - letter-spacing:0 !important; - line-height:1.18 !important; -} - -.card-title, -.section-title{ - text-transform:none !important; -} - -.chord-card .chord-name, -#chordGrid .chord-name, -.modal-chord-title{ - letter-spacing:0 !important; - font-weight:600 !important; -} - -.chord-card .chord-title-box, -.chord-card-head.chord-title-box{ - width:94px !important; - min-width:94px !important; - max-width:94px !important; -} - -.chord-card .chord-name, -#chordGrid .chord-name{ - width:100% !important; - max-width:100% !important; -} - -@media (max-width:430px){ - .chord-card .chord-title-box, - .chord-card-head.chord-title-box{ - width:94px !important; - min-width:94px !important; - max-width:94px !important; - } -} - - -/* === EasyTune v16: final chord geometry polish === */ -:root{ - --chord-fretboard-small:110px; - --chord-fretboard-modal:180px; -} - -/* Ramka nazwy w kafelkach dokładnie jak szerokość gryfu */ -.chord-card .chord-title-box, -.chord-card-head.chord-title-box{ - width:var(--chord-fretboard-small) !important; - min-width:var(--chord-fretboard-small) !important; - max-width:var(--chord-fretboard-small) !important; - box-sizing:border-box !important; - margin:0 auto 6px !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - width:100% !important; - max-width:100% !important; - box-sizing:border-box !important; - padding:6px 7px !important; - text-align:center !important; -} - -/* Mniejsze otwarte kółka strun granych, bez optycznej przewagi nad X */ -.diagram .state-open, -.modal-diagram .state-open{ - r:2.45px !important; - fill:transparent !important; - stroke:#38d66b !important; - stroke-width:1.25 !important; -} -.modal-diagram .state-open{ - r:3.4px !important; -} -.diagram .state-muted line, -.modal-diagram .state-muted line{ - stroke-width:1.25 !important; -} - -/* Legenda w modalu zaczyna się w osi numerów progów */ -.chord-legend{ - width:212px !important; - max-width:212px !important; - min-width:212px !important; - margin:2px auto 0 !important; - padding:0 !important; - align-self:center !important; -} -.chord-legend span{ - grid-template-columns:32px 1fr !important; - gap:8px !important; -} -.chord-legend b, -.chord-legend .legend-fret{ - width:32px !important; - min-width:32px !important; - max-width:32px !important; -} - -@media (max-width:430px){ - .chord-card .chord-title-box, - .chord-card-head.chord-title-box{ - width:var(--chord-fretboard-small) !important; - min-width:var(--chord-fretboard-small) !important; - max-width:var(--chord-fretboard-small) !important; - } -} - -/* === EasyTune v17: unified subviews and letter chord filters === */ -.view-screen .view-card{ - border:1px solid rgba(255,255,255,.055) !important; - background:linear-gradient(180deg,rgba(255,255,255,.035),rgba(255,255,255,.018)) !important; - box-shadow:none !important; -} -.view-screen .view-card + .view-card{margin-top:12px !important;} -.view-screen .view-head{ - border:0 !important; - box-shadow:none !important; -} -.chords-panel{ - padding:0 !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; -} -.letter-filter-row, -.type-filter-row{ - width:100% !important; - display:flex !important; - flex-wrap:wrap !important; - justify-content:center !important; - align-items:center !important; - gap:7px !important; - margin:0 auto 10px !important; - padding:0 !important; -} -.type-filter-row{margin-bottom:14px !important;} -.letter-chip, -.filter-chip{ - appearance:none !important; - border:1px solid rgba(255,255,255,.10) !important; - background:rgba(255,255,255,.035) !important; - color:rgba(248,250,252,.78) !important; - border-radius:999px !important; - min-height:30px !important; - padding:6px 10px !important; - font-size:12px !important; - line-height:1 !important; - font-weight:560 !important; - letter-spacing:.01em !important; - box-shadow:none !important; -} -.letter-chip:not([data-letter="all"]){ - width:30px !important; - min-width:30px !important; - max-width:30px !important; - padding-left:0 !important; - padding-right:0 !important; -} -.letter-chip.active, -.filter-chip.active{ - border-color:rgba(234,149,22,.42) !important; - background:rgba(234,149,22,.18) !important; - color:#fff7ed !important; -} -#chordSearch, -label[for="chordSearch"]{ - display:none !important; -} -.chord-grid{ - margin-top:0 !important; -} -/* reduce nested-border feeling in metronome/transpose while keeping sections readable */ -.metro-layout .view-card, -.view-card .output-box, -.song-input{ - border-color:rgba(255,255,255,.07) !important; - box-shadow:none !important; -} -@media (max-width:430px){ - .letter-filter-row,.type-filter-row{gap:6px !important;} - .letter-chip,.filter-chip{font-size:11.5px !important;min-height:29px !important;padding:6px 9px !important;} - .letter-chip:not([data-letter="all"]){width:29px !important;min-width:29px !important;max-width:29px !important;} -} - -/* === EasyTune v20: v18/v19 fixes reapplied on v17 base === */ -/* Chords view: no extra frame around the main chord container */ -.view-screen > .chords-panel, -.view-card.chords-panel, -.chords-panel{ - border:0 !important; - outline:0 !important; - background:transparent !important; - box-shadow:none !important; - padding:0 !important; -} -.chords-panel::before, -.chords-panel::after{display:none !important;content:none !important;} - -/* Multi-select filters: top row letters only, second row chord traits including # */ -.letter-filter-row, -.type-filter-row{ - display:flex !important; - flex-wrap:wrap !important; - justify-content:center !important; - align-items:center !important; - gap:7px !important; - width:100% !important; - margin:0 auto 10px !important; - padding:0 !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; -} -.type-filter-row{margin-bottom:14px !important;} -.letter-chip, -.filter-chip{ - appearance:none !important; - border:1px solid rgba(255,255,255,.10) !important; - background:rgba(255,255,255,.035) !important; - color:rgba(248,250,252,.78) !important; - border-radius:999px !important; - min-height:30px !important; - padding:6px 10px !important; - font-size:12px !important; - line-height:1 !important; - font-weight:560 !important; - letter-spacing:.01em !important; - box-shadow:none !important; -} -.letter-chip{ - width:30px !important; - min-width:30px !important; - max-width:30px !important; - padding-left:0 !important; - padding-right:0 !important; -} -.letter-chip.active, -.filter-chip.active{ - border-color:rgba(234,149,22,.50) !important; - background:rgba(234,149,22,.22) !important; - color:#fff7ed !important; -} - -/* Chord cards: title border locked to fretboard width and centered */ -:root{--chord-fretboard-small:144px;--chord-fretboard-large:232px;} -.chord-card-head.chord-title-box{ - width:var(--chord-fretboard-small) !important; - max-width:var(--chord-fretboard-small) !important; - margin:0 auto 7px !important; - padding:0 !important; - display:flex !important; - justify-content:center !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - width:100% !important; - max-width:100% !important; - min-width:0 !important; - box-sizing:border-box !important; - font-size:15px !important; - line-height:1 !important; - padding:5px 8px !important; - border-radius:11px !important; - font-weight:650 !important; - letter-spacing:-.015em !important; -} -.chord-card .diagram{ - width:var(--chord-fretboard-small) !important; - max-width:var(--chord-fretboard-small) !important; - margin:0 auto !important; -} - -/* Fret numbers slightly closer to fretboard, but still readable */ -.diagram .fret-number, -.modal-diagram .fret-number{ - text-anchor:end !important; - font-size:15px !important; - font-weight:780 !important; -} - -/* Modal spacing and legend aligned with fret-number axis */ -.chord-modal-card{padding:44px 18px 18px !important;} -#chord-modal-content{ - display:flex !important; - flex-direction:column !important; - align-items:center !important; -} -.modal-chord-title-box.chord-title-box{ - width:var(--chord-fretboard-large) !important; - max-width:var(--chord-fretboard-large) !important; - margin:0 auto 12px !important; -} -.modal-diagram{ - width:var(--chord-fretboard-large) !important; - max-width:var(--chord-fretboard-large) !important; -} -.chord-legend{ - width:var(--chord-fretboard-large) !important; - max-width:var(--chord-fretboard-large) !important; - box-sizing:border-box !important; - margin:10px auto 0 !important; - padding-left:0 !important; - justify-content:flex-start !important; - text-align:left !important; -} - -@media (max-width:430px){ - :root{--chord-fretboard-small:140px;--chord-fretboard-large:226px;} - .letter-filter-row,.type-filter-row{gap:6px !important;} - .letter-chip,.filter-chip{font-size:11.5px !important;min-height:29px !important;padding:6px 9px !important;} - .letter-chip{width:29px !important;min-width:29px !important;max-width:29px !important;} - .chord-card .chord-name,#chordGrid .chord-name{font-size:14.5px !important;} - .chord-modal-card{padding:42px 14px 16px !important;} -} - - -/* === EasyTune v21: restored chord typography, aligned legend, OR filter UI cleanup === */ -:root{ - --chord-diagram-small:144px; - --chord-diagram-modal:232px; - --chord-fretboard-title-small:94px; - --chord-fretboard-title-modal:149px; -} - -/* chord subview surface: no extra surrounding frame */ -.view-card.chords-panel, -.chords-panel, -.view-screen > .chords-panel{ - border:0 !important; - outline:0 !important; - background:transparent !important; - box-shadow:none !important; - padding:0 !important; -} - -/* filters: upper row letters only; lower row traits; multi-select */ -.letter-filter-row,.type-filter-row{ - display:flex !important; - flex-wrap:wrap !important; - justify-content:center !important; - align-items:center !important; - gap:7px !important; - width:100% !important; - margin:0 auto 10px !important; - padding:0 !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; -} -.type-filter-row{margin-bottom:14px !important;} -.letter-chip[data-letter="all"],.filter-chip[data-filter="all"]{display:none !important;} -.letter-chip,.filter-chip{ - appearance:none !important; - border:1px solid rgba(255,255,255,.10) !important; - background:rgba(255,255,255,.035) !important; - color:rgba(248,250,252,.78) !important; - border-radius:999px !important; - min-height:30px !important; - padding:6px 10px !important; - font-size:12px !important; - line-height:1 !important; - font-weight:560 !important; - letter-spacing:.01em !important; - box-shadow:none !important; -} -.letter-chip{ - width:30px !important; - min-width:30px !important; - max-width:30px !important; - padding-left:0 !important; - padding-right:0 !important; -} -.letter-chip.active,.filter-chip.active{ - border-color:rgba(234,149,22,.50) !important; - background:rgba(234,149,22,.22) !important; - color:#fff7ed !important; -} - -/* card layout: one figure holds title, notes and diagram */ -.chord-grid{gap:20px 12px !important;} -.chord-card{ - display:flex !important; - align-items:center !important; - justify-content:center !important; - padding:12px !important; - overflow:visible !important; -} -.chord-figure, -.chord-card-figure, -.modal-chord-figure{ - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:flex-start !important; - gap:7px !important; - width:100% !important; - margin:0 auto !important; - padding:0 !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; -} -.chord-card-figure{max-width:var(--chord-diagram-small) !important;} -.modal-chord-figure{max-width:var(--chord-diagram-modal) !important;gap:10px !important;} - -/* name + notes box: exact visual fretboard width */ -.chord-card .chord-title-box, -.chord-card-head.chord-title-box{ - width:var(--chord-fretboard-title-small) !important; - min-width:var(--chord-fretboard-title-small) !important; - max-width:var(--chord-fretboard-title-small) !important; - box-sizing:border-box !important; - margin:0 auto !important; - padding:0 !important; - overflow:hidden !important; - border-radius:12px !important; - border:1px solid rgba(255,218,160,.24) !important; - background:linear-gradient(180deg,#FFB83D,#EA9516) !important; - box-shadow:0 4px 12px rgba(234,149,22,.16), inset 0 1px 0 rgba(255,255,255,.23) !important; -} -.modal-chord-title-box.chord-title-box, -.modal-chord-title-box{ - width:var(--chord-fretboard-title-modal) !important; - min-width:var(--chord-fretboard-title-modal) !important; - max-width:var(--chord-fretboard-title-modal) !important; - box-sizing:border-box !important; - margin:0 auto !important; - padding:0 !important; - overflow:hidden !important; - border-radius:14px !important; - border:1px solid rgba(255,218,160,.24) !important; - background:linear-gradient(180deg,#FFB83D,#EA9516) !important; - box-shadow:0 4px 12px rgba(234,149,22,.16), inset 0 1px 0 rgba(255,255,255,.23) !important; -} -.chord-card .chord-name,#chordGrid .chord-name,.modal-chord-title{ - display:block !important; - width:100% !important; - max-width:100% !important; - min-width:0 !important; - box-sizing:border-box !important; - margin:0 !important; - border:0 !important; - border-radius:0 !important; - background:transparent !important; - box-shadow:none !important; - color:#111827 !important; - text-align:center !important; - line-height:1 !important; - letter-spacing:0 !important; - font-weight:650 !important; -} -.chord-card .chord-name,#chordGrid .chord-name{font-size:15px !important;padding:5px 7px 4px !important;} -.modal-chord-title{font-size:26px !important;padding:7px 8px 6px !important;} -.chord-title-divider{ - display:block !important; - width:100% !important; - height:1px !important; - flex:0 0 1px !important; - margin:0 !important; - background:rgba(17,24,39,.26) !important; - box-shadow:0 1px 0 rgba(255,255,255,.17) !important; -} -.chord-card .chord-notes,#chordGrid .chord-notes,.modal-chord-sub{ - display:block !important; - width:100% !important; - box-sizing:border-box !important; - margin:0 !important; - border:0 !important; - background:transparent !important; - color:rgba(17,24,39,.82) !important; - font-weight:620 !important; - text-align:center !important; - line-height:1.05 !important; - letter-spacing:0 !important; - white-space:normal !important; -} -.chord-card .chord-notes,#chordGrid .chord-notes{font-size:8px !important;padding:4px 5px 5px !important;} -.modal-chord-sub{font-size:13px !important;padding:6px 7px 7px !important;} -.modal-chord-sub::before{content:"" !important;} - -/* diagram width and no separate frame */ -.chord-card .diagram{ - display:block !important; - width:var(--chord-diagram-small) !important; - max-width:var(--chord-diagram-small) !important; - height:auto !important; - margin:0 auto !important; - padding:0 !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; - overflow:visible !important; -} -.modal-diagram{ - display:block !important; - width:var(--chord-diagram-modal) !important; - max-width:var(--chord-diagram-modal) !important; - height:auto !important; - margin:0 auto !important; - padding:0 !important; - border:0 !important; - background:transparent !important; - box-shadow:none !important; - overflow:visible !important; -} -.diagram .fret-number,.modal-diagram .fret-number{ - text-anchor:end !important; - font-size:15px !important; - font-weight:780 !important; - fill:rgba(255,247,237,.78) !important; -} -.diagram .state-open,.modal-diagram .state-open{ - fill:transparent !important; - stroke:#38d66b !important; - stroke-width:1.15 !important; - filter:none !important; -} -.diagram .state-muted line,.modal-diagram .state-muted line{ - stroke:#ff4d4d !important; - stroke-width:1.25 !important; - stroke-linecap:round !important; - filter:none !important; -} - -/* modal legend: full diagram width, no early wrapping, starts at fret-number axis */ -.chord-legend{ - width:var(--chord-diagram-modal) !important; - max-width:var(--chord-diagram-modal) !important; - box-sizing:border-box !important; - margin:0 auto !important; - padding:0 0 0 30px !important; - display:flex !important; - flex-direction:column !important; - align-items:flex-start !important; - gap:5px !important; - text-align:left !important; - overflow:visible !important; -} -.chord-legend span{ - display:flex !important; - align-items:center !important; - justify-content:flex-start !important; - gap:7px !important; - width:auto !important; - max-width:none !important; - margin:0 !important; - padding:0 !important; - white-space:nowrap !important; - text-align:left !important; - font-size:12px !important; - line-height:1.15 !important; -} -.chord-legend b,.chord-legend .legend-fret{ - flex:0 0 30px !important; - width:30px !important; - min-width:30px !important; - max-width:30px !important; - height:auto !important; - margin:0 !important; - padding:0 !important; - display:inline-flex !important; - align-items:center !important; - justify-content:flex-start !important; - text-align:left !important; -} -.legend-o{color:#38d66b !important;} -.legend-x{color:#ff4d4d !important;} - -@media (max-width:430px){ - :root{--chord-diagram-small:140px;--chord-diagram-modal:226px;--chord-fretboard-title-small:91px;--chord-fretboard-title-modal:145px;} - .chord-card{padding:11px 9px !important;} - .letter-filter-row,.type-filter-row{gap:6px !important;} - .letter-chip,.filter-chip{font-size:11.5px !important;min-height:29px !important;padding:6px 9px !important;} - .letter-chip{width:29px !important;min-width:29px !important;max-width:29px !important;} - .chord-card .chord-name,#chordGrid .chord-name{font-size:14.5px !important;} - .modal-chord-title{font-size:25px !important;} - .chord-legend{padding-left:29px !important;} - .chord-legend span{font-size:11.5px !important;} -} - - -/* === EasyTune v22: exact 7 filter + 20% larger chord modal content === */ -:root{ - --chord-diagram-modal:278px; - --chord-fretboard-title-modal:179px; -} -.chord-modal-card{ - padding:32px 10px 12px !important; -} -.modal-chord-figure{ - max-width:var(--chord-diagram-modal) !important; - gap:12px !important; -} -.modal-chord-title-box.chord-title-box, -.modal-chord-title-box{ - width:var(--chord-fretboard-title-modal) !important; - min-width:var(--chord-fretboard-title-modal) !important; - max-width:var(--chord-fretboard-title-modal) !important; -} -.modal-diagram{ - width:var(--chord-diagram-modal) !important; - max-width:var(--chord-diagram-modal) !important; -} -.modal-chord-title{ - font-size:31px !important; - padding:8px 9px 7px !important; -} -.modal-chord-sub{ - font-size:15.5px !important; - padding:7px 8px 8px !important; -} -.chord-legend{ - width:var(--chord-diagram-modal) !important; - max-width:var(--chord-diagram-modal) !important; - padding-left:36px !important; -} -.chord-legend span{ - font-size:13px !important; -} -.chord-legend b,.chord-legend .legend-fret{ - flex-basis:34px !important; - width:34px !important; - min-width:34px !important; - max-width:34px !important; -} -@media (max-width:430px){ - :root{--chord-diagram-modal:270px;--chord-fretboard-title-modal:174px;} - .chord-modal-card{padding:30px 8px 10px !important;} - .modal-chord-title{font-size:30px !important;} - .modal-chord-sub{font-size:15px !important;} - .chord-legend{padding-left:35px !important;} - .chord-legend span{font-size:12.5px !important;} -} - - -/* === EasyTune v23: filter spacing, centered chord cards, larger modal diagrams === */ -:root{ - --chord-diagram-modal:318px; - --chord-fretboard-title-modal:205px; -} -.letter-filter-row{ - margin:0 auto 18px !important; - gap:8px !important; -} -.type-filter-row{ - margin:0 auto 18px !important; - gap:8px !important; -} -.letter-chip, -.filter-chip{ - min-height:32px !important; - font-size:13px !important; - line-height:1 !important; -} -.letter-chip{ - width:32px !important; - min-width:32px !important; - max-width:32px !important; -} -.filter-chip[data-filter="sharp"], -.filter-chip[data-filter="7"]{ - width:32px !important; - min-width:32px !important; - max-width:32px !important; - height:32px !important; - min-height:32px !important; - padding:0 !important; - display:inline-flex !important; - align-items:center !important; - justify-content:center !important; - border-radius:999px !important; -} -.chord-grid{ - align-items:stretch !important; -} -.chord-card{ - display:flex !important; - align-items:center !important; - justify-content:center !important; - text-align:center !important; - padding:12px !important; -} -.chord-card-figure{ - min-height:100% !important; - justify-content:center !important; - align-items:center !important; -} -.chord-card .chord-title-divider, -.chord-card .chord-notes, -#chordGrid .chord-notes{ - display:none !important; -} -.chord-card .diagram .fret-number{ - font-size:15px !important; -} -.modal-diagram .fret-number{ - font-size:15.5px !important; -} -.modal-chord-figure{ - max-width:var(--chord-diagram-modal) !important; - gap:12px !important; -} -.modal-diagram{ - width:var(--chord-diagram-modal) !important; - max-width:var(--chord-diagram-modal) !important; -} -.modal-chord-title-box.chord-title-box, -.modal-chord-title-box{ - width:var(--chord-fretboard-title-modal) !important; - min-width:var(--chord-fretboard-title-modal) !important; - max-width:var(--chord-fretboard-title-modal) !important; -} -.chord-legend{ - width:var(--chord-diagram-modal) !important; - max-width:var(--chord-diagram-modal) !important; - padding-left:40px !important; -} -@media (max-width:430px){ - :root{--chord-diagram-modal:306px;--chord-fretboard-title-modal:198px;} - .letter-filter-row{margin-bottom:16px !important;gap:7px !important;} - .type-filter-row{margin-bottom:17px !important;gap:7px !important;} - .letter-chip,.filter-chip{font-size:12.5px !important;min-height:31px !important;} - .letter-chip,.filter-chip[data-filter="sharp"],.filter-chip[data-filter="7"]{width:31px !important;min-width:31px !important;max-width:31px !important;height:31px !important;} - .chord-legend{padding-left:38px !important;} -} - -/* === EasyTune v24: chord figure unified, filter reset companion styling === */ -:root{ - --chord-diagram-small:150px; - --chord-fretboard-title-small:96px; -} -/* widok akordów: nazwa i diagram jako jeden spójny pionowy blok */ -.chord-card{ - padding:13px 12px !important; - align-items:center !important; - justify-content:center !important; -} -.chord-card-figure{ - width:var(--chord-diagram-small) !important; - max-width:var(--chord-diagram-small) !important; - margin:0 auto !important; - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:5px !important; - min-height:0 !important; -} -.chord-card-head.chord-title-box, -.chord-card .chord-title-box{ - width:var(--chord-fretboard-title-small) !important; - min-width:var(--chord-fretboard-title-small) !important; - max-width:var(--chord-fretboard-title-small) !important; - margin:0 auto !important; - padding:0 !important; - display:flex !important; - align-items:center !important; - justify-content:center !important; - box-sizing:border-box !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - width:100% !important; - padding:6px 7px !important; - border:1px solid rgba(234,149,22,.38) !important; - border-radius:14px !important; - background:rgba(234,149,22,.16) !important; - text-align:center !important; - box-sizing:border-box !important; - font-size:15px !important; - font-weight:620 !important; - line-height:1 !important; - letter-spacing:0 !important; -} -.chord-card .diagram{ - width:var(--chord-diagram-small) !important; - max-width:var(--chord-diagram-small) !important; - margin:0 auto !important; -} -.chord-card .chord-title-divider, -.chord-card .chord-notes, -#chordGrid .chord-notes{ - display:none !important; -} - -/* modal: nazwa, dźwięki i diagram w tej samej osi oraz bez osobnego "pływania" */ -.modal-chord-figure{ - width:var(--chord-diagram-modal) !important; - max-width:var(--chord-diagram-modal) !important; - margin:0 auto !important; - align-items:center !important; - justify-content:center !important; - gap:10px !important; -} -.modal-chord-title-box.chord-title-box, -.modal-chord-title-box{ - width:var(--chord-fretboard-title-modal) !important; - min-width:var(--chord-fretboard-title-modal) !important; - max-width:var(--chord-fretboard-title-modal) !important; - margin:0 auto !important; - box-sizing:border-box !important; -} -.modal-chord-sub::before{ - content:"Dźwięki: " !important; - color:rgba(248,250,252,.66) !important; - font-weight:650 !important; -} - -/* mniej pustego światła między nazwą a diagramem w kafelkach */ -.chord-grid{align-items:stretch !important;} -.chord-card:focus, -.chord-card:focus-visible{ - outline:none !important; - box-shadow:0 16px 34px rgba(0,0,0,.24) !important; -} - -@media (max-width:430px){ - :root{--chord-diagram-small:146px;--chord-fretboard-title-small:93px;} - .chord-card{padding:12px 10px !important;} - .chord-card-figure{gap:4px !important;} - .chord-card .chord-name,#chordGrid .chord-name{font-size:14.5px !important;padding:6px 7px !important;} -} - -/* === EasyTune v25: chord filters spacing, reset, and card vertical balance === */ -.chords-panel{ - padding-top:18px !important; -} -.letter-filter-row{ - margin:0 auto 22px !important; - row-gap:10px !important; - column-gap:8px !important; -} -.type-filter-row{ - margin:0 auto 18px !important; - row-gap:10px !important; - column-gap:9px !important; -} -.chord-filter-actions{ - display:flex !important; - justify-content:center !important; - align-items:center !important; - margin:0 auto 18px !important; -} -.chord-reset-btn{ - min-height:34px !important; - padding:8px 18px !important; - border-radius:999px !important; - font-size:12px !important; - font-weight:700 !important; - letter-spacing:.03em !important; - text-transform:uppercase !important; -} -.chord-card{ - padding:14px 12px !important; - display:flex !important; - align-items:center !important; - justify-content:center !important; -} -.chord-card-figure{ - gap:2px !important; - justify-content:center !important; - align-items:center !important; -} -.chord-card .diagram{ - margin-top:0 !important; - margin-bottom:0 !important; -} -.chord-card-head.chord-title-box, -.chord-card .chord-title-box{ - margin:0 auto !important; -} -@media (max-width:430px){ - .letter-filter-row{margin-bottom:20px !important;row-gap:9px !important;column-gap:7px !important;} - .type-filter-row{margin-bottom:16px !important;row-gap:9px !important;column-gap:8px !important;} - .chord-filter-actions{margin-bottom:16px !important;} - .chord-card{padding:13px 10px !important;} - .chord-card-figure{gap:1px !important;} -} - - -/* === EasyTune v26: chord header reset, full names, balanced chord cards and modal notes === */ -.chords-view-head{ - display:grid !important; - grid-template-columns:auto 1fr auto !important; - align-items:center !important; - gap:12px !important; -} -.chords-view-head .view-title{ - text-align:center !important; - justify-self:center !important; - margin:0 !important; -} -.chords-view-head .chord-reset-btn{ - justify-self:end !important; - min-width:0 !important; - white-space:nowrap !important; -} -.chords-panel .chord-filter-actions{display:none !important;} - -/* Kafelki: równe światło góra/dół i nazwa razem z diagramem */ -.chord-card{ - display:flex !important; - align-items:center !important; - justify-content:center !important; - padding:16px 10px 16px !important; - min-height:0 !important; -} -.chord-card-figure{ - width:100% !important; - min-height:100% !important; - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:5px !important; - margin:0 auto !important; -} -.chord-card-head.chord-title-box, -.chord-card .chord-title-box{ - width:118px !important; - min-width:118px !important; - max-width:118px !important; - margin:0 auto 2px !important; -} -.chord-card .chord-name, -#chordGrid .chord-name{ - font-size:13.5px !important; - line-height:1.08 !important; - padding:6px 6px !important; - white-space:normal !important; -} -.chord-card .chord-notes, -#chordGrid .chord-notes{ - display:none !important; -} -.chord-card .diagram{ - margin:0 auto !important; -} - -/* Modal: pełniejsza zawartość, białe dźwięki i większy diagram */ -.chord-modal-card{ - padding:18px 14px 18px !important; -} -.modal-chord-figure{ - width:min(96vw,360px) !important; - max-width:360px !important; - gap:8px !important; - margin:0 auto !important; -} -.modal-diagram{ - width:min(345px,92vw) !important; - max-width:345px !important; - height:auto !important; - margin:0 auto !important; -} -.modal-chord-title-box.chord-title-box, -.modal-chord-title-box{ - width:min(345px,92vw) !important; - min-width:0 !important; - max-width:345px !important; - margin:0 auto 6px !important; -} -.modal-chord-title{ - font-size:26px !important; - line-height:1.1 !important; - padding:8px 10px !important; - white-space:normal !important; -} -.modal-chord-sub{ - color:#fff !important; - font-size:15px !important; - line-height:1.18 !important; - padding:7px 9px 8px !important; -} -.modal-chord-sub::before{content:"" !important;} -.modal-notes-label{color:#fff !important;font-weight:700 !important;} - -@media (max-width:430px){ - .chord-card{padding:15px 9px 15px !important;} - .chord-card-head.chord-title-box, - .chord-card .chord-title-box{width:112px !important;min-width:112px !important;max-width:112px !important;} - .chord-card .chord-name,#chordGrid .chord-name{font-size:12.5px !important;padding:6px 5px !important;} - .modal-diagram{width:min(330px,93vw) !important;} - .modal-chord-title-box.chord-title-box,.modal-chord-title-box{width:min(330px,93vw) !important;max-width:330px !important;} - .modal-chord-title{font-size:24px !important;} - .modal-chord-sub{font-size:14px !important;} -} - -/* === EasyTune v27: minimal SVG whitespace and modal title width === */ -:root{ - --chord-diagram-small:150px; -} - -/* Kafelki akordów: cała grupa dokładnie wyśrodkowana, bez nierównego światła z SVG */ -.chord-card{ - padding:16px 10px 16px !important; - display:flex !important; - align-items:center !important; - justify-content:center !important; -} -.chord-card-figure{ - width:var(--chord-diagram-small) !important; - max-width:var(--chord-diagram-small) !important; - min-height:0 !important; - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:2px !important; - margin:0 auto !important; - padding:0 !important; -} -.chord-card-head.chord-title-box, -.chord-card .chord-title-box{ - margin:0 auto !important; -} -.chord-card .diagram{ - width:var(--chord-diagram-small) !important; - max-width:var(--chord-diagram-small) !important; - margin:0 auto !important; - padding:0 !important; - display:block !important; - overflow:visible !important; -} - -/* Modal akordu: nazwa nie wychodzi poza modal, diagram bez pustego dołu */ -.modal-chord-figure{ - width:min(96vw,360px) !important; - max-width:360px !important; - gap:8px !important; - align-items:center !important; -} -.modal-chord-title-box.chord-title-box, -.modal-chord-title-box{ - width:80% !important; - min-width:0 !important; - max-width:80% !important; - box-sizing:border-box !important; - margin:0 auto 4px !important; -} -.modal-chord-title, -.modal-chord-sub{ - box-sizing:border-box !important; - overflow-wrap:anywhere !important; - word-break:normal !important; -} -.modal-diagram{ - width:min(350px,94vw) !important; - max-width:350px !important; - margin:0 auto !important; - padding:0 !important; - display:block !important; - overflow:visible !important; -} - -@media (max-width:430px){ - :root{--chord-diagram-small:146px;} - .chord-card{padding:15px 9px 15px !important;} - .chord-card-figure{gap:2px !important;} - .modal-chord-title-box.chord-title-box, - .modal-chord-title-box{width:80% !important;max-width:80% !important;} - .modal-diagram{width:min(336px,94vw) !important;max-width:336px !important;} -} - - -/* === EasyTune v28: modal centering, chord tile balance, transpose layout polish === */ -/* Modal akordu: usuń optyczny lewy margines, wyśrodkuj całą figurę i powiększ użyteczną przestrzeń */ -.chord-modal-card{ - padding:14px 10px 16px !important; - align-items:center !important; - justify-content:center !important; - text-align:center !important; -} -#chord-modal-content{ - width:100% !important; - display:flex !important; - align-items:center !important; - justify-content:center !important; - text-align:center !important; -} -.modal-chord-figure{ - width:min(96vw,380px) !important; - max-width:380px !important; - margin:0 auto !important; - padding:0 !important; - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:8px !important; - text-align:center !important; -} -.modal-chord-title-box.chord-title-box, -.modal-chord-title-box{ - width:80% !important; - max-width:304px !important; - min-width:0 !important; - margin:0 auto 3px !important; - align-self:center !important; -} -.modal-diagram{ - width:min(366px,94vw) !important; - max-width:366px !important; - margin:0 auto !important; - align-self:center !important; - transform:translateX(0) !important; -} -.chord-legend{ - width:min(304px,80%) !important; - max-width:304px !important; - margin:4px auto 0 !important; - align-self:center !important; -} - -/* Kafelki akordów: więcej górnego światła i mniejsza przerwa nazwa–diagram */ -.chord-card{ - padding:20px 10px 16px !important; - display:flex !important; - align-items:center !important; - justify-content:center !important; -} -.chord-card-figure{ - gap:0 !important; - align-items:center !important; - justify-content:center !important; - margin:0 auto !important; -} -.chord-card-head.chord-title-box, -.chord-card .chord-title-box{ - margin:0 auto -1px !important; -} -.chord-card .diagram{ - margin:-1px auto 0 !important; -} - -/* Transpozycja: przyciski i podpisy zgodne z resztą kart */ -.view-head .view-title{ - text-align:center !important; - justify-self:center !important; -} -.form-label-row{ - display:flex !important; - align-items:center !important; - justify-content:space-between !important; - gap:12px !important; - margin:0 0 8px !important; -} -.form-label-row .form-label{ - margin:0 !important; -} -.icon-action{ - display:inline-flex !important; - align-items:center !important; - justify-content:center !important; - gap:7px !important; - min-height:34px !important; - padding:7px 12px !important; - border-radius:999px !important; - white-space:nowrap !important; -} -.icon-action span[aria-hidden="true"]{ - font-size:14px !important; - line-height:1 !important; -} -.transpose-section-label{ - display:block !important; - margin:14px 0 8px !important; - text-align:left !important; -} -.transpose-controls{ - margin-top:0 !important; -} -.transpose-value span{display:none !important;} -.transpose-reset-row{ - display:flex !important; - justify-content:center !important; - align-items:center !important; - margin-top:12px !important; -} -.transpose-reset-row .ghost-btn{ - min-width:116px !important; -} -.output-actions{ - display:flex !important; - justify-content:center !important; - margin-top:12px !important; -} -.output-actions .primary-btn{ - min-width:160px !important; -} - -@media (max-width:430px){ - .chord-card{padding:19px 9px 15px !important;} - .modal-diagram{width:min(350px,94vw) !important;max-width:350px !important;} - .modal-chord-title-box.chord-title-box,.modal-chord-title-box{max-width:294px !important;} - .chord-legend{width:min(294px,80%) !important;max-width:294px !important;} - .form-label-row{gap:8px !important;} - .icon-action{padding:7px 10px !important;font-size:12px !important;} -} - -/* === EasyTune v29: chord modal centering fix === - Przyczyną optycznej pustki z lewej strony była kombinacja szerokiego viewBoxu SVG - z pozycją gryfu i dodatkowymi szerokościami kontenerów. Ten blok wymusza jeden, - wyśrodkowany tor: tytuł → diagram → legenda. */ -.chord-modal-card{ - padding:22px 10px 14px !important; - display:flex !important; - align-items:center !important; - justify-content:center !important; - text-align:center !important; - overflow:hidden !important; -} -#chord-modal-content{ - width:100% !important; - max-width:100% !important; - margin:0 auto !important; - padding:0 !important; - display:flex !important; - justify-content:center !important; - align-items:center !important; - text-align:center !important; -} -.modal-chord-figure{ - width:min(92vw,340px) !important; - max-width:340px !important; - margin:0 auto !important; - padding:0 !important; - display:flex !important; - flex-direction:column !important; - align-items:center !important; - justify-content:center !important; - gap:9px !important; - transform:none !important; - left:auto !important; - right:auto !important; -} -.modal-chord-title-box.chord-title-box, -.modal-chord-title-box{ - width:80% !important; - max-width:272px !important; - min-width:0 !important; - margin:0 auto !important; - align-self:center !important; - box-sizing:border-box !important; -} -.modal-diagram{ - width:min(340px,92vw) !important; - max-width:340px !important; - margin:0 auto !important; - padding:0 !important; - display:block !important; - align-self:center !important; - transform:none !important; - overflow:visible !important; -} -.chord-legend{ - width:min(340px,92vw) !important; - max-width:340px !important; - margin:2px auto 0 !important; - padding-left:24px !important; - box-sizing:border-box !important; - align-self:center !important; -} -.chord-legend span{ - white-space:nowrap !important; -} -@media (max-width:430px){ - .chord-modal-card{padding:22px 8px 14px !important;} - .modal-chord-figure{width:min(94vw,330px) !important;max-width:330px !important;gap:8px !important;} - .modal-diagram{width:min(330px,94vw) !important;max-width:330px !important;} - .modal-chord-title-box.chord-title-box, - .modal-chord-title-box{width:80% !important;max-width:264px !important;} - .chord-legend{width:min(330px,94vw) !important;max-width:330px !important;padding-left:24px !important;} -} - -/* === EasyTune v30: drobne korekty tekstów i transpozycji === */ -.tool-card .tool-copy{ - margin-left:8px !important; -} -@media (max-width:430px){ - .tool-card .tool-copy{margin-left:6px !important;} -} -.result-label-row{ - justify-content:flex-start !important; - align-items:center !important; - gap:8px !important; - margin-bottom:8px !important; -} -.result-label-row .form-label{ - margin:0 !important; -} -.info-dot{ - width:20px !important; - height:20px !important; - border-radius:50% !important; - border:1px solid rgba(234,149,22,.72) !important; - background:rgba(234,149,22,.12) !important; - color:#f5b35a !important; - display:inline-flex !important; - align-items:center !important; - justify-content:center !important; - padding:0 !important; - font-size:12px !important; - line-height:1 !important; - font-weight:700 !important; - font-family:inherit !important; - cursor:help !important; -} - -/* === EasyTune v31: transpose result info and clear button polish === */ -.result-label-row{ - position:relative !important; - display:flex !important; - align-items:center !important; - justify-content:center !important; - padding-right:30px !important; -} -.result-label-row .info-dot{ - position:absolute !important; - right:0 !important; - top:50% !important; - transform:translateY(-50%) !important; -} -#clearSong.small-action{ - gap:0 !important; -} - - -/* === EasyTune v33: transposition subtitle alignment and no-wrap song scaling === */ -#songInput, -#songOutput{ - font-size:14px; - transition:font-size .12s ease; -} -.song-input{ - white-space:pre; - overflow:auto; - word-break:normal; -} -.output-box{ - white-space:pre; - overflow:auto; - word-break:normal; -} -.output-line{ - white-space:pre; - min-width:max-content; -} -.transpose-section-label, -.result-label-row, -.form-label-row{ - text-align:left !important; -} -.result-label-row{ - justify-content:flex-start !important; - position:relative; -} -.result-label-row .info-dot{ - margin-left:auto !important; -} - -/* EasyTune v35 — metronom: jeden system synchronizacji, bez podwójnego ruchu */ -.metro-clean-main{ - display:grid !important; - gap:14px !important; -} -.metro-clean-visual{order:1 !important;} -.metro-clean-beats{order:2 !important;} -.metro-clean-meta{order:3 !important;} -.metro-clean-actions{order:4 !important;} -/* Wyłączamy ciągłe animacje, które przesuwały fazę względem kliknięcia. */ -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual::before{ - animation:none !important; -} -.metro-clean-pendulum{ - transform:translateX(-50%) rotate(0deg) !important; -} -.metro-clean-visual.beat-hit, -.metro-clean-visual.beat-hit::before{ - animation:none !important; - box-shadow:inherit !important; -} -/* Zostaje tylko krótki rozbłysk na akcencie. */ -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .18s ease-out 1 !important; -} -.metro-clean-visual.accent-hit{ - border-color:rgba(234,149,22,.82) !important; - box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 0 0 3px rgba(234,149,22,.16),0 0 60px rgba(234,149,22,.22),0 24px 60px rgba(0,0,0,.40) !important; -} - - -/* EasyTune v36 — metronom: układ i jedna synchronizacja wahadła */ -.metro-clean-main{ - display:grid !important; - gap:14px !important; -} -.metro-clean-meta{order:1 !important;} -.metro-clean-visual{order:2 !important;} -.metro-clean-beats{order:3 !important;} -.metro-clean-actions{order:4 !important;} - -/* Przywrócone wahadło: jedyny ciągły ruch. Bez pulsowania koła. */ -.metro-clean-visual::before, -.metro-clean-visual.beat-hit, -.metro-clean-visual.beat-hit::before{ - animation:none !important; -} -.metro-clean-pendulum{ - animation:metroCleanSwing var(--metro-duration, 600ms) ease-in-out infinite alternate paused !important; - transform:translateX(-50%) rotate(-38deg); -} -.metro-clean-visual.running .metro-clean-pendulum{ - animation-play-state:running !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .18s ease-out 1 !important; -} - -/* EasyTune v37 — metronom: przywrócone wahadło + równy pionowy rytm */ -.metro-clean-main{ - display:grid !important; - gap:20px !important; - align-items:center !important; - justify-items:center !important; -} -.metro-clean-meta{ - order:1 !important; - margin:0 auto !important; -} -.metro-clean-visual{ - order:2 !important; - margin:0 auto !important; -} -.metro-clean-beats{ - order:3 !important; - margin:0 auto !important; -} -.metro-clean-actions{ - margin-top:20px !important; - display:flex !important; - justify-content:center !important; -} -/* Nadpisanie wcześniejszego animation:none z v35: wahadło ma się ruszać prawo-lewo. */ -.metro-clean-visual .metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum{ - animation-name:metroCleanSwing !important; - animation-duration:var(--metro-duration, 600ms) !important; - animation-timing-function:ease-in-out !important; - animation-iteration-count:infinite !important; - animation-direction:alternate !important; - animation-fill-mode:both !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual .metro-clean-pendulum{ - animation-play-state:paused !important; -} .metro-clean-visual.running .metro-clean-pendulum{ - animation-play-state:running !important; + animation-play-state: running; } -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - transform:translateX(-50%) rotate(0deg) !important; -} -/* Dalej bez pulsowania tarczy — zostaje tylko krótki rozbłysk akcentu. */ -.metro-clean-visual.beat-hit, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .18s ease-out 1 !important; -} - -/* EasyTune v38 — metronom: ruch wahadła sterowany tylko JS, bez zdublowanych animacji CSS */ -.metro-clean-visual .metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transition:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-main{ - gap:24px !important; -} -.metro-clean-meta{ - order:1 !important; -} -.metro-clean-visual{ - order:2 !important; -} -.metro-clean-beats{ - order:3 !important; - margin-top:2px !important; - margin-bottom:6px !important; -} -.metro-clean-actions{ - order:4 !important; - margin-top:18px !important; -} - -/* EasyTune v39 — metronom: czysty układ i ruch wskazówki sterowany tylko JS */ -.metro-clean-main{ - display:grid !important; - grid-template-areas: - "meta" - "visual" - "beats" !important; - gap:24px !important; - align-items:center !important; - justify-items:center !important; +.metro-clean-pendulum span{ + position: absolute; + bottom: calc(-17px * var(--metro-scale)) !important; + left: 50%; + transform: translateX(-50%); + width: calc(34px * var(--metro-scale)) !important; + height: calc(34px * var(--metro-scale)) !important; + border-radius: 50%; + background: linear-gradient(180deg, #FFB83D, #EA9516); + box-shadow: 0 10px 26px rgba(234,149,22,.28); } -.metro-clean-meta{grid-area:meta !important; order:1 !important; margin:0 auto !important; width:min(100%, 520px) !important;} -.metro-clean-visual{grid-area:visual !important; order:2 !important; margin:0 auto !important;} -.metro-clean-beats{grid-area:beats !important; order:3 !important; margin:0 auto 0 !important;} -.metro-clean-actions{margin-top:24px !important; display:flex !important; justify-content:center !important;} -.metro-clean-visual, -.metro-clean-visual::before, -.metro-clean-visual.beat-hit, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .18s ease-out 1 !important; -} -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transition:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - transform:translateX(-50%) rotate(0deg) !important; +.metro-clean-bpm{ + position: relative; + z-index: 2; + min-width: 0 !important; + padding: calc(10px * var(--metro-scale)) calc(16px * var(--metro-scale)) !important; + display: grid; + text-align: center; + line-height: 1; } -/* EasyTune v40 — metronome: only JS moves the pendulum; no circle pulse, no CSS swing */ -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum{ - animation:none !important; - transition:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual::before, -.metro-clean-visual.beat-hit, -.metro-clean-visual.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .18s ease-out 1 !important; -} -.metro-clean-main{ - display:grid !important; - gap:18px !important; +.metro-clean-bpm strong{ + font-size: clamp(52px, calc(112px * var(--metro-scale)), 112px) !important; + font-weight: 300; + color: #f8fafc; + letter-spacing: -.06em; } -.metro-clean-meta{order:1 !important;} -.metro-clean-visual{order:2 !important;} -.metro-clean-beats{order:3 !important; margin-top:2px !important; margin-bottom:2px !important;} -.metro-clean-actions{order:4 !important; margin-top:4px !important;} -/* EasyTune v41 — metronome final sync overrides */ -.metro-clean-visual::before, -.metro-clean-visual.beat-hit, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .18s ease-out 1 !important; -} -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transform-origin:50% 100% !important; +.metro-clean-bpm span{ + margin-top: clamp(6px, calc(10px * var(--metro-scale)), 12px) !important; + font-size: clamp(13px, calc(16px * var(--metro-scale)), 16px) !important; + color: rgba(248,250,252,.62); + letter-spacing: .16em; } -/* EasyTune v42 — metronome endpoint sync: no CSS swing or circle pulse */ -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual::before, -.metro-clean-visual.beat-hit, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .17s ease-out 1 !important; -} -.metro-clean-main{ - gap:20px !important; -} .metro-clean-beats{ - margin-top:6px !important; - margin-bottom:8px !important; -} - - -/* EasyTune v43 — final metronome sync CSS: JS controls needle, no circle pulse */ -.metro-clean-visual, -.metro-clean-visual::before, -.metro-clean-visual.beat-hit, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .18s ease-out 1 !important; -} -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - transition:none !important; -} - -/* EasyTune v45 — metronome sync fix: no frame flash, no circle pulse, JS-only needle */ -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transition:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual, -.metro-clean-visual.beat-hit, -.metro-clean-visual.running.beat-hit{ - animation:none !important; -} -.metro-clean-visual.beat-hit, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.accent-hit{ - border-color:rgba(234,149,22,.24) !important; - box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; -} -.metro-clean-visual::before, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .14s ease-out 1 !important; - border-color:rgba(234,149,22,.86) !important; -} - - -/* EasyTune v46 — hard metronome safety: no frame flash, no CSS swing, JS-only needle */ -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transition:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual.beat-hit, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.accent-hit{ - border-color:rgba(234,149,22,.24) !important; - box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; - animation:none !important; -} -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .14s ease-out 1 !important; -} - -/* EasyTune v54 — mobile metronome fit */ -@media (max-width: 430px){ - .metro-clean-screen{ - padding:12px 10px calc(12px + env(safe-area-inset-bottom, 0px)) !important; - } - .metro-clean-main{ - gap:10px !important; - } - .metro-clean-visual{ - min-height:min(42vh,300px) !important; - border-radius:18px !important; - } - .metro-clean-pendulum{ - top:54px !important; - height:165px !important; - } - .metro-clean-bpm strong{ - font-size:clamp(56px,17vw,78px) !important; - } - .metro-clean-beats{ - min-height:52px !important; - padding:10px 8px !important; - gap:8px !important; - } - .metro-clean-meta{ - gap:8px !important; - } - .metro-clean-meta button{ - min-height:54px !important; - } - .metro-clean-actions .primary-btn{ - min-height:50px !important; - font-size:17px !important; - } -} -@media (max-width: 430px) and (max-height: 760px){ - .metro-clean-visual{ - min-height:min(36vh,250px) !important; - } - .metro-clean-pendulum{ - top:44px !important; - height:140px !important; - } - .metro-clean-meta button{ - min-height:50px !important; - padding:7px 4px !important; - } - .metro-clean-meta strong{ - font-size:15px !important; - } -} - -/* EasyTune v47 — no frame flash; JS-only needle */ -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transition:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual.beat-hit, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.accent-hit{ - border-color:rgba(234,149,22,.24) !important; - box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; - animation:none !important; -} -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} - -/* EasyTune v48 — metronome: endpoint-only light, no frame/circle pulse */ -.metro-clean-visual, -.metro-clean-visual.beat-hit, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.accent-hit{ - animation:none !important; - border-color:rgba(234,149,22,.24) !important; - box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; -} -.metro-clean-visual::before, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .14s ease-out 1 !important; - border-color:rgba(234,149,22,.86) !important; -} -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transform-origin:50% 100% !important; -} - -/* EasyTune v50 — twardy stan początkowy wskazówki: maksymalny lewy wychył. - JS steruje ruchem; CSS nie może przywracać pionu ani pulsowania ramki. */ -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - transform:translateX(-50%) rotate(-38deg) !important; -} -.metro-clean-visual, -.metro-clean-visual.beat-hit, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.accent-hit{ - animation:none !important; - border-color:rgba(234,149,22,.24) !important; - box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; -} -.metro-clean-visual::before, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .14s ease-out 1 !important; - border-color:rgba(234,149,22,.86) !important; + display: flex; + justify-content: center; + align-items: center; + min-height: clamp(48px, calc(62px * var(--metro-scale)), 68px) !important; + padding: clamp(10px, calc(16px * var(--metro-scale)), 16px) clamp(8px, calc(12px * var(--metro-scale)), 12px) !important; + gap: clamp(8px, calc(12px * var(--metro-scale)), 14px) !important; + cursor: pointer; + position: relative; } -/* EasyTune v51 — final metronome CSS guard: no CSS swing/pulse, idle needle left */ -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transition:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - transform:translateX(-50%) rotate(-38deg) !important; -} -.metro-clean-visual, -.metro-clean-visual.beat-hit, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.accent-hit{ - animation:none !important; - border-color:rgba(234,149,22,.24) !important; - box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; -} -.metro-clean-visual::before, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .14s ease-out 1 !important; - border-color:rgba(234,149,22,.86) !important; +.beat-wrap{ + display: flex; + flex-direction: column; + align-items: center; + gap: clamp(4px, calc(6px * var(--metro-scale)), 6px) !important; } - -/* EasyTune v52 — metronome sync guard */ -.metro-clean-pendulum, -.metro-clean-visual.running .metro-clean-pendulum, -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - animation:none !important; - transition:none !important; - transform-origin:50% 100% !important; -} -.metro-clean-visual:not(.running) .metro-clean-pendulum{ - transform:translateX(-50%) rotate(-38deg) !important; -} -.metro-clean-visual, -.metro-clean-visual.beat-hit, -.metro-clean-visual.running.beat-hit, -.metro-clean-visual.accent-hit{ - animation:none !important; - border-color:rgba(234,149,22,.24) !important; - box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; -} -.metro-clean-visual::before, -.metro-clean-visual.beat-hit::before, -.metro-clean-visual.running.beat-hit::before{ - animation:none !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .14s ease-out 1 !important; - border-color:rgba(234,149,22,.86) !important; +.beat-number{ + font-size: clamp(10px, calc(12px * var(--metro-scale)), 12px) !important; + color: rgba(248,250,252,.52); } -/* EasyTune v53 — explicit visual durations used by metronome sync compensation */ -.metro-clean-beats .beat, -.metro-clean-beats .beat-number{ - transition:transform .08s ease, background-color .08s ease, color .08s ease, box-shadow .08s ease !important; -} -.metro-clean-visual.accent-hit::before{ - animation:metroAccentFlash .14s ease-out 1 !important; +.metro-clean-beats .beat{ + width: clamp(14px, calc(18px * var(--metro-scale)), 18px) !important; + height: clamp(14px, calc(18px * var(--metro-scale)), 18px) !important; } -/* EasyTune v55 — fix beats container full width + BPM button cursor */ -/* .metro-clean-beats has no explicit width; parent grid's justify-items:center - (set in v39) causes it to shrink-wrap to ~132px. Force full width. */ -.metro-clean-beats { +.metro-clean-meta{ width: 100% !important; -} -/* BPM display button now opens Tempo modal — restore pointer cursor */ -#metroCleanBpmButton { - cursor: pointer !important; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: clamp(8px, calc(10px * var(--metro-scale)), 12px) !important; } -/* EasyTune v56 — responsive metronome scales to the app viewport */ -.metro-clean-screen{ - --metro-scale:1; - --metro-visual-width:360px; - --metro-visual-ratio:1.16; -} -.metro-clean-main{ - width:min(100%, 760px) !important; - margin:0 auto !important; - gap:clamp(10px, 1.8vh, 18px) !important; - justify-items:stretch !important; -} -.metro-clean-visual{ - width:min(100%, var(--metro-visual-width)) !important; - height:calc(var(--metro-visual-width) * var(--metro-visual-ratio)) !important; - min-height:0 !important; - margin:0 auto !important; - border-radius:clamp(18px, calc(24px * var(--metro-scale)), 28px) !important; -} -.metro-clean-visual::before{ - width:calc(300px * var(--metro-scale)) !important; - height:calc(300px * var(--metro-scale)) !important; -} -.metro-clean-scale{ - top:calc(56px * var(--metro-scale)) !important; - width:calc(190px * var(--metro-scale)) !important; - height:calc(78px * var(--metro-scale)) !important; - border-radius:calc(190px * var(--metro-scale)) calc(190px * var(--metro-scale)) 0 0 !important; -} -.metro-clean-scale::before, -.metro-clean-scale::after{ - top:calc(44px * var(--metro-scale)) !important; - width:calc(36px * var(--metro-scale)) !important; -} -.metro-clean-scale::before{ - left:calc(18px * var(--metro-scale)) !important; -} -.metro-clean-scale::after{ - right:calc(18px * var(--metro-scale)) !important; -} -.metro-clean-pendulum{ - top:calc(74px * var(--metro-scale)) !important; - width:max(3px, calc(4px * var(--metro-scale))) !important; - height:calc(230px * var(--metro-scale)) !important; -} -.metro-clean-pendulum span{ - bottom:calc(-17px * var(--metro-scale)) !important; - width:calc(34px * var(--metro-scale)) !important; - height:calc(34px * var(--metro-scale)) !important; -} -.metro-clean-bpm{ - min-width:0 !important; - padding:calc(10px * var(--metro-scale)) calc(16px * var(--metro-scale)) !important; -} -.metro-clean-bpm strong{ - font-size:clamp(52px, calc(112px * var(--metro-scale)), 112px) !important; -} -.metro-clean-bpm span{ - margin-top:clamp(6px, calc(10px * var(--metro-scale)), 12px) !important; - font-size:clamp(13px, calc(16px * var(--metro-scale)), 16px) !important; -} -.metro-clean-beats{ - min-height:clamp(48px, calc(62px * var(--metro-scale)), 68px) !important; - padding:clamp(10px, calc(16px * var(--metro-scale)), 16px) clamp(8px, calc(12px * var(--metro-scale)), 12px) !important; - gap:clamp(8px, calc(12px * var(--metro-scale)), 14px) !important; -} -.beat-wrap{ - gap:clamp(4px, calc(6px * var(--metro-scale)), 6px) !important; -} -.beat-number{ - font-size:clamp(10px, calc(12px * var(--metro-scale)), 12px) !important; -} -.metro-clean-beats .beat{ - width:clamp(14px, calc(18px * var(--metro-scale)), 18px) !important; - height:clamp(14px, calc(18px * var(--metro-scale)), 18px) !important; -} -.metro-clean-meta{ - width:100% !important; - gap:clamp(8px, calc(10px * var(--metro-scale)), 12px) !important; -} .metro-clean-meta button{ - min-height:clamp(50px, calc(62px * var(--metro-scale)), 64px) !important; - padding:clamp(8px, calc(10px * var(--metro-scale)), 10px) clamp(4px, calc(8px * var(--metro-scale)), 8px) !important; + min-height: clamp(50px, calc(62px * var(--metro-scale)), 64px) !important; + padding: clamp(8px, calc(10px * var(--metro-scale)), 10px) clamp(4px, calc(8px * var(--metro-scale)), 8px) !important; + font-size: clamp(11px, calc(12px * var(--metro-scale)), 12px) !important; } + .metro-clean-meta span{ - font-size:clamp(11px, calc(12px * var(--metro-scale)), 12px) !important; + font-size: clamp(11px, calc(12px * var(--metro-scale)), 12px) !important; } + .metro-clean-meta strong{ - font-size:clamp(15px, calc(18px * var(--metro-scale)), 18px) !important; + font-size: clamp(15px, calc(18px * var(--metro-scale)), 18px) !important; } + .metro-clean-actions{ - width:min(100%, 520px) !important; - margin:clamp(10px, 1.8vh, 20px) auto 0 !important; + width: min(100%, 520px) !important; + margin: clamp(10px, 1.8vh, 20px) auto 0 !important; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; } + .metro-clean-actions .primary-btn{ - min-height:clamp(50px, calc(56px * var(--metro-scale)), 58px) !important; - font-size:clamp(17px, calc(18px * var(--metro-scale)), 18px) !important; + min-height: clamp(50px, calc(56px * var(--metro-scale)), 58px) !important; + font-size: clamp(17px, calc(18px * var(--metro-scale)), 18px) !important; } + .metro-clean-screen.metro-clean-landscape .metro-clean-main{ - gap:clamp(8px, 1.3vh, 14px) !important; + gap: clamp(8px, 1.3vh, 14px) !important; } + .metro-clean-screen.metro-clean-landscape .metro-clean-meta button{ - min-height:clamp(48px, calc(56px * var(--metro-scale)), 58px) !important; + min-height: clamp(48px, calc(56px * var(--metro-scale)), 58px) !important; } + +window.addEventListener('resize', scheduleCleanMetronomeLayoutSync); +window.visualViewport?.addEventListener?.('resize', scheduleCleanMetronomeLayoutSync); From df80632e7b07464f442d510dd8b4b378928a0dea Mon Sep 17 00:00:00 2001 From: awj Date: Sun, 21 Jun 2026 14:56:50 +0200 Subject: [PATCH 4/8] fix: reduce padding and margins around metronome buttons --- styles.css | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/styles.css b/styles.css index 95bd926..e2bcbbb 100644 --- a/styles.css +++ b/styles.css @@ -881,14 +881,14 @@ button { font: inherit; } } /* ===================================================== - EasyTune v56 — RESPONSYWNY METRONOM + EasyTune v1.3 — RESPONSYWNY METRONOM ===================================================== */ .metro-clean-screen{ --metro-scale: 1; --metro-visual-width: 360px; --metro-visual-ratio: 1.16; - padding: clamp(12px, 2vh, 20px) clamp(12px, 1.5vw, 18px) clamp(14px, 2vh, 24px) !important; + padding: clamp(12px, 2vh, 20px) clamp(12px, 1.5vw, 18px) clamp(10px, 1.5vh, 16px) !important; } .metro-clean-main{ @@ -1068,7 +1068,7 @@ button { font: inherit; } .metro-clean-actions{ width: min(100%, 520px) !important; - margin: clamp(10px, 1.8vh, 20px) auto 0 !important; + margin: 0 auto 0 !important; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; @@ -1086,6 +1086,3 @@ button { font: inherit; } .metro-clean-screen.metro-clean-landscape .metro-clean-meta button{ min-height: clamp(48px, calc(56px * var(--metro-scale)), 58px) !important; } - -window.addEventListener('resize', scheduleCleanMetronomeLayoutSync); -window.visualViewport?.addEventListener?.('resize', scheduleCleanMetronomeLayoutSync); From cff701631fa3ebdb0cc400f3ce4b097e886d9fa1 Mon Sep 17 00:00:00 2001 From: awj Date: Sun, 21 Jun 2026 14:57:43 +0200 Subject: [PATCH 5/8] bump: version 1.3 - fix padding around metronome buttons --- manifest.webmanifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest.webmanifest b/manifest.webmanifest index ef16f2b..27fd378 100644 --- a/manifest.webmanifest +++ b/manifest.webmanifest @@ -2,7 +2,7 @@ "name": "EasyTune", "short_name": "EasyTune", "description": "Transpozycja, akordy i metronom dla gitarzystów.", - "version": "1.2", + "version": "1.3", "id": "./", "start_url": "./", "scope": "./", From aae6e664ea2565cc478e50fc61e2764190260d2c Mon Sep 17 00:00:00 2001 From: awj Date: Sun, 21 Jun 2026 15:09:36 +0200 Subject: [PATCH 6/8] Load app version from manifest.webmanifest - Replace hardcoded appVersion '1.2' with dynamic loading from manifest - Add proper error handling and fallback to default version - Update splash screen version display to use manifest value - Fixes issue where version number wasn't syncing with package metadata --- app.js | 1649 +------------------------------------------------------- 1 file changed, 29 insertions(+), 1620 deletions(-) diff --git a/app.js b/app.js index 5adf1ac..cf154cd 100644 --- a/app.js +++ b/app.js @@ -216,7 +216,7 @@ function homeHtml(){ `; } function toolCard(view,title,desc,type){ - const dots = type === 'transpose' ? '' : type === 'chords' ? '' : ''; + const dots = type === 'transpose' ? '' : type === 'chords' ? '' : ''; return `
0
-
Wynik
+
Wynik
`; } function chordsHtml(){ - return `

Akordy

+ return `

Akordy

- +
-
+
`; } function metronomeHtml(){ return `

Metronom

-
+
Tap tempo
Presety tempa
Metrum
@@ -303,7 +303,7 @@ function initTranspose(){ document.querySelector('#stepUp').onclick = () => { transposeSteps++; update(); }; document.querySelector('#resetTranspose').onclick = () => { transposeSteps = 0; update(); }; document.querySelector('#clearSong').onclick = () => { input.value = ''; update(); input.focus(); }; - document.querySelector('#copyResult').onclick = async () => { await navigator.clipboard?.writeText(input.value.split('\n').map(l => splitWordsAndSpaces(l).map(p => isChordToken(p) ? transposeOneToken(p, transposeSteps) : p).join('')).join('\n')).catch(()=>{}); }; + document.querySelector('#copyResult').onclick = async () => { await navigator.clipboard?.writeText(input.value.split('\n').map(l => splitWordsAndSpaces(l).map(p => isChordToken(p) ? transposeOneToken(p, transposeSteps) : p).join('')).join('\n')); }; document.querySelector('#transposeResultInfo')?.addEventListener('click', () => openAppModal('transpose-result')); update(); } @@ -480,9 +480,9 @@ function updatePendulumSpeed(){ const pendulum = document.querySelector('.metro-pendulum'); if(pendulum) pendulum.style.animationDuration = `${Math.max(180, 60000 / bpm)}ms`; } -function updateMeter(){ const label = meter === 6 ? '6/8' : `${meter}/4`; const el=document.querySelector('#meterInDial'); if(el) el.textContent = label; const modalMeter=document.querySelector('#metroModalMeter'); if(modalMeter) modalMeter.textContent = label; } +function updateMeter(){ const label = meter === 6 ? '6/8' : `${meter}/4`; const el=document.querySelector('#meterInDial'); if(el) el.textContent = label; const modalMeter=document.querySelector('[data-modal-meter]'); if(modalMeter) modalMeter.textContent = label; } function renderBeats(){ - const markup = Array.from({length:meter}, (_,i) => `${i+1}`).join(''); + const markup = Array.from({length:meter}, (_,i) => `${i+1}${'●'}`).join(''); const beats = document.querySelector('#beats'); if(beats) beats.innerHTML = markup; const modalBeats = document.querySelector('#metroModalBeats'); @@ -554,7 +554,7 @@ function openChordModal(chord){ const clean = mainChord(chord); if(!BASE_CHORDS[clean]) return; if(!chordModal || !chordModalContent) return; - chordModalContent.innerHTML = ``; + chordModalContent.innerHTML = ``; chordModal.classList.add('visible'); chordModal.setAttribute('aria-hidden','false'); } function closeChordModal(){ if(!chordModal) return; chordModal.classList.remove('visible'); chordModal.setAttribute('aria-hidden','true'); } @@ -562,7 +562,7 @@ function openAppModal(kind){ if(!appModal || !appModalContent) return; const installMarkup = isPwaInstalled() ? '' : ''; appModalContent.innerHTML = kind === 'options' - ? `

Opcje

EasyTune działa offline po pierwszym uruchomieniu.${isPwaInstalled() ? ' Aplikacja jest już uruchomiona jako zainstalowane PWA.' : ' Aby działała jako pełne PWA, wybierz „Zainstaluj aplikację”, a nie „Dodaj skrót”.'}

${installMarkup}` + ? `

Opcje

EasyTune działa offline po pierwszym uruchomieniu.${isPwaInstalled() ? ' Aplikacja jest już uruchomiona jako zainstalowane PWA.' : ' Aby działała jako pełne PWA, wybierz „Zainstaluj" z menu przeglądarki.'}

${installMarkup}` : kind === 'transpose-result' ? '

Wynik transpozycji

Kliknij dowolny akord w oknie wyniku, aby otworzyć powiększony diagram tego chwytu.

' : `

EasyTune

Transpozycja, akordy i metronom. Wersja PWA offline ${appVersion}.

`; @@ -572,8 +572,23 @@ function openAppModal(kind){ function closeAppModal(){ if(!appModal) return; appModal.classList.remove('visible'); appModal.setAttribute('aria-hidden','true'); } async function loadManifestVersion(){ - try{ const res = await fetch('manifest.webmanifest'); const m = await res.json(); appVersion = m.version || '1.2'; versionEl.textContent = `v${appVersion}`; } catch { versionEl.textContent = `v${appVersion}`; } + try { + const response = await fetch('./manifest.webmanifest'); + if (!response.ok) throw new Error('Failed to fetch manifest'); + const manifest = await response.json(); + if (manifest.version) { + appVersion = manifest.version; + } + } catch (error) { + console.warn('Failed to load version from manifest:', error); + // appVersion stays as default '1.2' + } finally { + if (versionEl) { + versionEl.textContent = `v${appVersion}`; + } + } } + function showApp(){ app.hidden = false; renderView('home'); setTimeout(()=>splash.classList.add('is-hidden'), 850); setTimeout(()=>splash.remove(), 1300); } menuButton?.addEventListener('click', () => { const open = !optionsMenu.hidden; optionsMenu.hidden = open; menuButton.setAttribute('aria-expanded', String(!open)); }); @@ -619,7 +634,7 @@ window.matchMedia?.('(display-mode: fullscreen)')?.addEventListener?.('change', async function promptPwaInstall(){ if (isPwaInstalled()) { syncInstallButtons(); return; } if (!deferredInstallPrompt) { - alert('Przeglądarka nie zgłosiła jeszcze gotowości instalacji PWA. Upewnij się, że strona działa przez HTTPS lub localhost, odśwież ją raz i wybierz w menu przeglądarki „Zainstaluj aplikację” — nie „Dodaj skrót”.'); + alert('Przeglądarka nie zgłosiła jeszcze gotowości instalacji PWA. Upewnij się, że strona działa przez HTTPS lub localhost, odśwież ją raz i wybierz w menu przeglądarki „Zainstaluj aplikację".'); return; } deferredInstallPrompt.prompt(); @@ -629,1610 +644,4 @@ async function promptPwaInstall(){ syncInstallButtons(); } syncInstallButtons(); -loadManifestVersion().finally(() => { showApp(); syncInstallButtons(); }); - -/* ===================================================== - EasyTune v2.5 — CZYSTY METRONOM - Ten blok nadpisuje wyłącznie widok i logikę metronomu. - Pozostałe widoki i modale pozostają bez zmian. - ===================================================== */ -let cleanTapTimes = []; -let cleanMetroTimer = null; -let metroPendulumFrame = null; -let metroPendulumStartedAt = 0; -let metroWasRunningBeforeModal = false; -let metroPausedByModal = false; -let metroLayoutFrame = null; - -function metronomeHtml(){ - const meterLabel = meter === 6 ? '6/8' : `${meter}/4`; - const accentLabel = accentMode === 'off' ? 'Brak' : accentMode === 'all' ? 'Każdy' : 'Pierwszy'; - return `
-
- -

Metronom

- -
- -
-
- - - -
- -
- -
- - - -
-
- -
- -
- - - - - - - - -
`; -} - -function initMetronome(){ - metroWasRunningBeforeModal = false; - metroPausedByModal = false; - renderMetroControls(); - syncCleanMetronomeUi(); - setBpm(bpm, {restart:false}); - scheduleCleanMetronomeLayoutSync(); - - document.querySelector('#startMetro')?.addEventListener('click', () => metroRunning ? stopMetronome() : startMetronome()); - document.querySelector('#metroResetTop')?.addEventListener('click', resetMetronomeSettings); - document.querySelector('#metroTapInModal')?.addEventListener('click', handleTapTempo); - document.querySelector('#metroBpmDown')?.addEventListener('click', () => setBpm(bpm - 1)); - document.querySelector('#metroBpmUp')?.addEventListener('click', () => setBpm(bpm + 1)); - document.querySelector('#bpmSlider')?.addEventListener('input', e => setBpm(Number(e.target.value))); - document.querySelector('#openTempoModal')?.addEventListener('click', () => openMetroSettings('metroTempoModal')); - document.querySelector('#openMeterModal')?.addEventListener('click', () => openMetroSettings('metroMeterModal')); - document.querySelector('#openAccentModal')?.addEventListener('click', () => openMetroSettings('metroAccentModal')); - document.querySelector('#metroTapInfoClean')?.addEventListener('click', () => { - const modal = document.querySelector('#tapHelpModal'); - pauseMetronomeForModal(); - modal?.classList.add('open'); - modal?.setAttribute('aria-hidden','false'); - }); - document.querySelector('#tapHelpClose')?.addEventListener('click', closeTapHelpModal); - document.querySelector('#tapHelpModal')?.addEventListener('click', e => { - if(e.target === e.currentTarget) closeTapHelpModal(); - }); - - document.querySelectorAll('[data-close-metro-settings]').forEach(btn => btn.addEventListener('click', closeMetroSettings)); - document.querySelectorAll('.metro-settings-modal').forEach(modal => modal.addEventListener('click', e => { - if(e.target === modal) closeMetroSettings(); - })); -} - -function scheduleCleanMetronomeLayoutSync(){ - if(currentView !== 'metronome') return; - if(metroLayoutFrame) cancelAnimationFrame(metroLayoutFrame); - metroLayoutFrame = requestAnimationFrame(() => { - metroLayoutFrame = null; - syncCleanMetronomeLayout(); - }); -} - -function syncCleanMetronomeLayout(){ - const screen = document.querySelector('.metro-clean-screen'); - const main = document.querySelector('#metroCleanMain'); - const visual = document.querySelector('#metroCleanVisual'); - if(!screen || !main || !visual) return; - - const viewportWidth = Math.max(320, Math.round( - window.visualViewport?.width || - window.innerWidth || - document.documentElement.clientWidth || - screen.clientWidth || - 0 - )); - const viewportHeight = Math.max(320, Math.round( - window.visualViewport?.height || - window.innerHeight || - document.documentElement.clientHeight || - screen.clientHeight || - 0 - )); - const landscape = viewportWidth > viewportHeight; - const head = screen.querySelector('.view-head'); - const actions = screen.querySelector('.metro-clean-actions'); - const screenStyle = getComputedStyle(screen); - const mainStyle = getComputedStyle(main); - const actionsStyle = actions ? getComputedStyle(actions) : null; - const screenHeight = screen.clientHeight || Math.round(screen.getBoundingClientRect().height) || viewportHeight; - const availableWidth = Math.max( - 260, - Math.min(main.clientWidth || screen.clientWidth || viewportWidth, viewportWidth - 28) - ); - const availableHeight = Math.max( - 230, - screenHeight - - (head?.offsetHeight || 0) - - ((parseFloat(screenStyle.paddingTop) || 0) + (parseFloat(screenStyle.paddingBottom) || 0)) - - (actions?.offsetHeight || 0) - - (actionsStyle ? (parseFloat(actionsStyle.marginTop) || 0) : 0) - - 16 - ); - - const baseVisualWidth = landscape ? 384 : 360; - const baseVisualRatio = landscape ? 0.98 : 1.16; - const baseVisualHeight = baseVisualWidth * baseVisualRatio; - const baseMainHeight = - baseVisualHeight + - (landscape ? 56 : 62) + - (landscape ? 58 : 62) + - ((parseFloat(mainStyle.rowGap || mainStyle.gap) || 18) * 2); - const scale = Math.max( - 0.56, - Math.min( - availableWidth / baseVisualWidth, - availableHeight / baseMainHeight, - 1.18 - ) - ); - - screen.classList.toggle('metro-clean-landscape', landscape); - screen.classList.toggle('metro-clean-portrait', !landscape); - screen.style.setProperty('--metro-scale', scale.toFixed(3)); - screen.style.setProperty('--metro-visual-width', `${Math.round(baseVisualWidth * scale)}px`); - screen.style.setProperty('--metro-visual-ratio', baseVisualRatio.toFixed(3)); -} - -window.addEventListener('resize', scheduleCleanMetronomeLayoutSync); -window.visualViewport?.addEventListener?.('resize', scheduleCleanMetronomeLayoutSync); - -function pauseMetronomeForModal(){ - if(metroPausedByModal) return; - metroWasRunningBeforeModal = metroRunning; - if(metroRunning) stopMetronome(); - metroPausedByModal = metroWasRunningBeforeModal; -} -function isAnyMetroModalOpen(){ - const settingsOpen = Array.from(document.querySelectorAll('.metro-settings-modal')).some(m => m.classList.contains('visible')); - const tapHelpOpen = document.querySelector('#tapHelpModal')?.classList.contains('open'); - return settingsOpen || Boolean(tapHelpOpen); -} -function resumeMetronomeAfterModal(){ - if(isAnyMetroModalOpen()) return; - const shouldResume = metroPausedByModal && metroWasRunningBeforeModal; - metroPausedByModal = false; - metroWasRunningBeforeModal = false; - if(shouldResume && !metroRunning) startMetronome(); -} - -function openMetroSettings(id){ - pauseMetronomeForModal(); - document.querySelectorAll('.metro-settings-modal').forEach(m => { - m.classList.remove('visible'); - m.setAttribute('aria-hidden','true'); - }); - const modal = document.querySelector('#' + id); - if(!modal) return; - modal.classList.add('visible'); - modal.setAttribute('aria-hidden','false'); -} -function closeMetroSettings(){ - document.querySelectorAll('.metro-settings-modal').forEach(m => { - m.classList.remove('visible'); - m.setAttribute('aria-hidden','true'); - }); - resumeMetronomeAfterModal(); -} - -function closeTapHelpModal(){ - const modal = document.querySelector('#tapHelpModal'); - if(!modal) return; - modal.classList.remove('open'); - modal.setAttribute('aria-hidden','true'); - resumeMetronomeAfterModal(); -} - -function renderMetroControls(){ - const presets = [60, 80, 100, 120, 140, 160]; - const presetGrid = document.querySelector('#presetGrid'); - if(presetGrid){ - presetGrid.innerHTML = presets.map(v => ``).join(''); - presetGrid.onclick = e => { - const btn = e.target.closest('[data-bpm]'); - if(!btn) return; - setBpm(Number(btn.dataset.bpm)); - renderMetroControls(); - }; - } - - const meterButtons = document.querySelector('#meterButtons'); - if(meterButtons){ - meterButtons.innerHTML = [2,3,4,5,6].map(v => ``).join(''); - meterButtons.onclick = e => { - const btn = e.target.closest('[data-meter]'); - if(!btn) return; - meter = Number(btn.dataset.meter); - beatIndex = 0; - saveMetroSettings(); - renderMetroControls(); - renderBeats(); - syncCleanMetronomeUi(); - }; - } - - const accentButtons = document.querySelector('#accentButtons'); - if(accentButtons){ - accentButtons.innerHTML = [ - ['first','Pierwszy'], - ['all','Każdy'], - ['off','Brak'] - ].map(([v,l]) => ``).join(''); - accentButtons.onclick = e => { - const btn = e.target.closest('[data-accent]'); - if(!btn) return; - accentMode = btn.dataset.accent; - beatIndex = 0; - saveMetroSettings(); - renderMetroControls(); - renderBeats(); - syncCleanMetronomeUi(); - }; - } - - renderBeats(); - syncCleanMetronomeUi(); -} - - -function stopPendulumMotion(reset=true){ - if(metroPendulumFrame){ - cancelAnimationFrame(metroPendulumFrame); - metroPendulumFrame = null; - } - if(reset){ - const pendulum = document.querySelector('.metro-clean-pendulum'); - if(pendulum) pendulum.style.setProperty('transform', 'translateX(-50%) rotate(0deg)', 'important'); - } -} - -function startPendulumMotion(){ - stopPendulumMotion(false); - const pendulum = document.querySelector('.metro-clean-pendulum'); - if(!pendulum) return; - const beatMs = Math.max(180, 60000 / bpm); - const maxAngle = 38; - metroPendulumStartedAt = performance.now(); - - const draw = (now) => { - if(!metroRunning){ - metroPendulumFrame = null; - return; - } - - // Jeden mechanizm ruchu: pozycja zależy wyłącznie od czasu i BPM. - // Uderzenia wypadają na skrajach wahadła: lewo, prawo, lewo... - const elapsed = now - metroPendulumStartedAt; - const phase = (elapsed % (beatMs * 2)) / beatMs; - const angle = phase <= 1 - ? -maxAngle + (phase * 2 * maxAngle) - : maxAngle - ((phase - 1) * 2 * maxAngle); - - pendulum.style.setProperty('transform', `translateX(-50%) rotate(${angle.toFixed(2)}deg)`, 'important'); - metroPendulumFrame = requestAnimationFrame(draw); - }; - - pendulum.style.setProperty('transform', `translateX(-50%) rotate(${-maxAngle}deg)`, 'important'); - metroPendulumFrame = requestAnimationFrame(draw); -} - -function syncCleanMetronomeUi(){ - const meterLabel = meter === 6 ? '6/8' : `${meter}/4`; - const accentLabel = accentMode === 'off' ? 'Brak' : accentMode === 'all' ? 'Każdy' : 'Pierwszy'; - - const bpmText = document.querySelector('#bpmValue'); - const modalBpm = document.querySelector('#metroModalBpm'); - const slider = document.querySelector('#bpmSlider'); - const tempoMeta = document.querySelector('#metroTempoMeta'); - const meterMeta = document.querySelector('#meterInDial'); - const accentMeta = document.querySelector('#metroAccentMeta'); - const visual = document.querySelector('#metroCleanVisual'); - const start = document.querySelector('#startMetro'); - - if(bpmText) bpmText.textContent = bpm; - if(modalBpm) modalBpm.textContent = bpm; - if(slider) slider.value = bpm; - if(tempoMeta) tempoMeta.textContent = `${bpm} BPM`; - if(meterMeta) meterMeta.textContent = meterLabel; - if(accentMeta) accentMeta.textContent = accentLabel; - if(start) start.textContent = metroRunning ? 'Stop' : 'Start'; - - if(visual){ - // Jedyny ruch metronomu: wahadło synchronizowane z interwałem BPM. - visual.style.setProperty('--metro-duration', `${60000 / bpm}ms`); - visual.classList.toggle('running', metroRunning); - } - scheduleCleanMetronomeLayoutSync(); -} - -function setBpm(v, opts={restart:true}){ - bpm = Math.max(40, Math.min(240, Math.round(v))); - saveMetroSettings(); - syncCleanMetronomeUi(); - document.querySelectorAll('.preset-bpm').forEach(b => b.classList.toggle('active', Number(b.dataset.bpm) === bpm)); - if(opts.restart && metroRunning){ - stopMetronome(); - startMetronome(); - } -} - -function saveMetroSettings(){ - localStorage.setItem('easytune-metro-bpm', String(bpm)); - localStorage.setItem('easytune-metro-meter', String(meter)); - localStorage.setItem('easytune-metro-accent', accentMode); -} - -function resetMetronomeSettings(){ - stopMetronome(); - bpm = 100; - meter = 4; - accentMode = 'first'; - cleanTapTimes = []; - beatIndex = 0; - saveMetroSettings(); - renderMetroControls(); - syncCleanMetronomeUi(); -} - -function handleTapTempo(){ - const now = Date.now(); - cleanTapTimes = cleanTapTimes.filter(t => now - t < 2200); - cleanTapTimes.push(now); - if(cleanTapTimes.length < 2) return; - const intervals = cleanTapTimes.slice(1).map((t,i)=> t - cleanTapTimes[i]); - const avg = intervals.reduce((a,b)=>a+b,0) / intervals.length; - setBpm(Math.round(60000 / avg)); -} - -function renderBeats(){ - const beats = document.querySelector('#beats'); - if(!beats) return; - beats.innerHTML = Array.from({length:meter}, (_,i)=>{ - const active = i === beatIndex; - const accent = accentMode === 'all' || (accentMode === 'first' && i === 0); - return `${i+1}`; - }).join(''); -} - -function ensureAudio(){ - if(!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)(); - if(audioCtx.state === 'suspended') audioCtx.resume(); -} -function clickSound(accented){ - ensureAudio(); - const osc = audioCtx.createOscillator(); - const gain = audioCtx.createGain(); - osc.type = 'square'; - osc.frequency.value = accented ? 1300 : 820; - gain.gain.setValueAtTime(0.0001, audioCtx.currentTime); - gain.gain.exponentialRampToValueAtTime(accented ? 0.22 : 0.13, audioCtx.currentTime + 0.006); - gain.gain.exponentialRampToValueAtTime(0.0001, audioCtx.currentTime + 0.07); - osc.connect(gain).connect(audioCtx.destination); - osc.start(); - osc.stop(audioCtx.currentTime + 0.08); -} -function tick(){ - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - clickSound(accented); - renderBeats(); - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - if(accented){ - void visual.offsetWidth; - visual.classList.add('accent-hit'); - window.setTimeout(()=>visual.classList.remove('accent-hit'), 220); - } - } - beatIndex = (beatIndex + 1) % meter; -} -function startMetronome(){ - ensureAudio(); - metroRunning = true; - beatIndex = 0; - clearInterval(cleanMetroTimer); - clearInterval(metroTimer); - cleanMetroTimer = null; - metroTimer = null; - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - visual.style.setProperty('--metro-duration', `${60000 / bpm}ms`); - } - syncCleanMetronomeUi(); - startPendulumMotion(); - tick(); - cleanMetroTimer = setInterval(tick, 60000 / bpm); - metroTimer = cleanMetroTimer; -} -function stopMetronome(){ - metroRunning = false; - clearInterval(cleanMetroTimer); - clearInterval(metroTimer); - cleanMetroTimer = null; - metroTimer = null; - stopPendulumMotion(true); - syncCleanMetronomeUi(); - renderBeats(); -} - - -// v2.5.6 help modal -document.addEventListener('click', function(e){ - if(e.target && e.target.id==='tapHelpModal'){ - e.target.classList.remove('open'); - } -}); - -/* EasyTune v40 — metronome unified clock: one trigger for sound, dots, accent light and pendulum */ -let metroUnifiedBeatCount = 0; -let metroUnifiedStartAt = 0; - -function stopPendulumMotion(reset=true){ - if(metroPendulumFrame){ - cancelAnimationFrame(metroPendulumFrame); - metroPendulumFrame = null; - } - const pendulum = document.querySelector('.metro-clean-pendulum'); - if(reset && pendulum){ - pendulum.style.setProperty('transform', 'translateX(-50%) rotate(0deg)', 'important'); - } -} - -function startPendulumMotion(startAt = performance.now()){ - stopPendulumMotion(false); - const pendulum = document.querySelector('.metro-clean-pendulum'); - if(!pendulum) return; - const beatMs = Math.max(180, 60000 / bpm); - const maxAngle = 38; - metroPendulumStartedAt = startAt; - - const draw = (now) => { - if(!metroRunning){ - metroPendulumFrame = null; - return; - } - const elapsed = Math.max(0, now - metroPendulumStartedAt); - const phase = (elapsed % (beatMs * 2)) / beatMs; - const angle = phase <= 1 - ? -maxAngle + (phase * 2 * maxAngle) - : maxAngle - ((phase - 1) * 2 * maxAngle); - pendulum.style.setProperty('transform', `translateX(-50%) rotate(${angle.toFixed(2)}deg)`, 'important'); - metroPendulumFrame = requestAnimationFrame(draw); - }; - - pendulum.style.setProperty('transform', `translateX(-50%) rotate(${-maxAngle}deg)`, 'important'); - metroPendulumFrame = requestAnimationFrame(draw); -} - -function metronomeBeat(){ - if(!metroRunning) return; - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - clickSound(accented); - renderBeats(); - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - if(accented){ - void visual.offsetWidth; - visual.classList.add('accent-hit'); - window.setTimeout(()=>visual.classList.remove('accent-hit'), 180); - } - } - beatIndex = (beatIndex + 1) % meter; -} - -function tick(){ - metronomeBeat(); -} - -function scheduleNextMetronomeBeat(){ - if(!metroRunning) return; - const beatMs = Math.max(180, 60000 / bpm); - metroUnifiedBeatCount += 1; - const dueAt = metroUnifiedStartAt + metroUnifiedBeatCount * beatMs; - const delay = Math.max(0, dueAt - performance.now()); - cleanMetroTimer = window.setTimeout(() => { - metronomeBeat(); - scheduleNextMetronomeBeat(); - }, delay); - metroTimer = cleanMetroTimer; -} - -function startMetronome(){ - ensureAudio(); - stopMetronome(); - metroRunning = true; - beatIndex = 0; - metroUnifiedBeatCount = 0; - metroUnifiedStartAt = performance.now(); - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - visual.style.setProperty('--metro-duration', `${60000 / bpm}ms`); - } - syncCleanMetronomeUi(); - startPendulumMotion(metroUnifiedStartAt); - metronomeBeat(); - scheduleNextMetronomeBeat(); -} - -function stopMetronome(){ - metroRunning = false; - if(cleanMetroTimer) window.clearTimeout(cleanMetroTimer); - if(metroTimer) window.clearTimeout(metroTimer); - window.clearInterval(cleanMetroTimer); - window.clearInterval(metroTimer); - cleanMetroTimer = null; - metroTimer = null; - stopPendulumMotion(true); - syncCleanMetronomeUi(); - renderBeats(); -} - -/* EasyTune v41 — metronome: extrema-driven single trigger - Sound, accent light and beat dots fire ONLY when the needle is at max left/right. - The circle never pulses. The needle transition between extrema is visual only. */ -let metroExtremeSide = -1; -let metroMoveTimer = null; -let metroMoveSerial = 0; - -function metroBeatMs(){ - return Math.max(180, 60000 / bpm); -} - -function setMetroNeedleSide(side, immediate=false){ - const pendulum = document.querySelector('.metro-clean-pendulum'); - if(!pendulum) return; - const angle = side < 0 ? -38 : 38; - if(immediate){ - pendulum.style.setProperty('transition', 'none', 'important'); - pendulum.style.setProperty('transform', `translateX(-50%) rotate(${angle}deg)`, 'important'); - pendulum.getBoundingClientRect(); - } else { - pendulum.style.setProperty('transition', `transform ${metroBeatMs()}ms cubic-bezier(.37,0,.63,1)`, 'important'); - pendulum.style.setProperty('transform', `translateX(-50%) rotate(${angle}deg)`, 'important'); - } -} - -function clearMetroClock(){ - metroMoveSerial += 1; - if(metroMoveTimer) window.clearTimeout(metroMoveTimer); - if(cleanMetroTimer) window.clearTimeout(cleanMetroTimer); - if(metroTimer) window.clearTimeout(metroTimer); - window.clearInterval(cleanMetroTimer); - window.clearInterval(metroTimer); - metroMoveTimer = null; - cleanMetroTimer = null; - metroTimer = null; - if(metroPendulumFrame){ - cancelAnimationFrame(metroPendulumFrame); - metroPendulumFrame = null; - } -} - -function fireMetroExtremeBeat(){ - if(!metroRunning) return; - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - clickSound(accented); - renderBeats(); - - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - if(accented){ - void visual.offsetWidth; - visual.classList.add('accent-hit'); - window.setTimeout(() => visual.classList.remove('accent-hit'), 180); - } - } - beatIndex = (beatIndex + 1) % meter; -} - -function scheduleMetroExtremeLoop(serial){ - if(!metroRunning || serial !== metroMoveSerial) return; - const beatMs = metroBeatMs(); - const nextSide = -metroExtremeSide; - - // After the beat fires at the current extreme, move toward the next extreme. - requestAnimationFrame(() => { - if(!metroRunning || serial !== metroMoveSerial) return; - setMetroNeedleSide(nextSide, false); - }); - - metroMoveTimer = window.setTimeout(() => { - if(!metroRunning || serial !== metroMoveSerial) return; - metroExtremeSide = nextSide; - // Confirm exact endpoint before firing the next beat. - setMetroNeedleSide(metroExtremeSide, true); - fireMetroExtremeBeat(); - scheduleMetroExtremeLoop(serial); - }, beatMs); - cleanMetroTimer = metroMoveTimer; - metroTimer = metroMoveTimer; -} - -function tick(){ - fireMetroExtremeBeat(); -} - -function stopPendulumMotion(reset=true){ - clearMetroClock(); - if(reset){ - const pendulum = document.querySelector('.metro-clean-pendulum'); - if(pendulum){ - pendulum.style.setProperty('transition','none','important'); - pendulum.style.setProperty('transform','translateX(-50%) rotate(0deg)','important'); - } - } -} - -function startPendulumMotion(){ - // Kept for compatibility; real motion is driven by startMetronome(). - setMetroNeedleSide(metroExtremeSide, true); -} - -function startMetronome(){ - ensureAudio(); - stopMetronome(); - metroRunning = true; - beatIndex = 0; - metroExtremeSide = -1; - metroMoveSerial += 1; - const serial = metroMoveSerial; - - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - visual.style.setProperty('--metro-duration', `${metroBeatMs()}ms`); - } - - setMetroNeedleSide(metroExtremeSide, true); - syncCleanMetronomeUi(); - fireMetroExtremeBeat(); - scheduleMetroExtremeLoop(serial); -} - -function stopMetronome(){ - metroRunning = false; - clearMetroClock(); - const pendulum = document.querySelector('.metro-clean-pendulum'); - if(pendulum){ - pendulum.style.setProperty('transition','none','important'); - pendulum.style.setProperty('transform','translateX(-50%) rotate(0deg)','important'); - } - syncCleanMetronomeUi(); - renderBeats(); -} - -let metroEndpointTimer = null; - -/* EasyTune v45 — metronome: single RAF clock, sound/light at needle extrema. - No CSS swing, no circle pulse, no frame flash. The same animation frame sets - the needle endpoint and fires the sound/accent light. */ -let metroRafId = null; -let metroRafStart = 0; -let metroLastBeatOrdinal = -1; -let metroRunSerial = 0; - -function metroBeatMs(){ - return Math.max(180, 60000 / bpm); -} - -function metroMaxAngle(){ return 38; } - -function setMetroNeedleAngle(angle){ - const pendulum = document.querySelector('.metro-clean-pendulum'); - if(!pendulum) return; - pendulum.style.setProperty('animation', 'none', 'important'); - pendulum.style.setProperty('transition', 'none', 'important'); - pendulum.style.setProperty('transform-origin', '50% 100%', 'important'); - pendulum.style.setProperty('transform', `translateX(-50%) rotate(${angle}deg)`, 'important'); -} - -function setMetroNeedleExtreme(side){ - setMetroNeedleAngle(side < 0 ? -metroMaxAngle() : metroMaxAngle()); -} - -function clearMetroEndpointClock(){ - metroRunSerial += 1; - if(metroRafId){ - cancelAnimationFrame(metroRafId); - metroRafId = null; - } - if(cleanMetroTimer) window.clearTimeout(cleanMetroTimer); - if(metroTimer) window.clearTimeout(metroTimer); - window.clearInterval(cleanMetroTimer); - window.clearInterval(metroTimer); - cleanMetroTimer = null; - metroTimer = null; - if(typeof metroEndpointTimer !== 'undefined' && metroEndpointTimer) window.clearTimeout(metroEndpointTimer); - metroEndpointTimer = null; - if(metroPendulumFrame){ - cancelAnimationFrame(metroPendulumFrame); - metroPendulumFrame = null; - } -} - -function fireMetroBeatFromNeedle(beatOrdinal){ - if(!metroRunning) return; - const side = beatOrdinal % 2 === 0 ? -1 : 1; - setMetroNeedleExtreme(side); - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - clickSound(accented); - renderBeats(); - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - if(accented){ - void visual.offsetWidth; - visual.classList.add('accent-hit'); - window.setTimeout(() => visual.classList.remove('accent-hit'), 150); - } - } - beatIndex = (beatIndex + 1) % meter; -} - -function metroAnimationFrame(serial, now){ - if(!metroRunning || serial !== metroRunSerial) return; - const beatMs = metroBeatMs(); - const elapsed = Math.max(0, now - metroRafStart); - const beatOrdinal = Math.floor(elapsed / beatMs); - - if(beatOrdinal !== metroLastBeatOrdinal){ - metroLastBeatOrdinal = beatOrdinal; - fireMetroBeatFromNeedle(beatOrdinal); - } else { - // Left extreme at beat 0, right extreme at beat 1, etc. - const angle = -metroMaxAngle() * Math.cos(Math.PI * elapsed / beatMs); - setMetroNeedleAngle(angle); - } - - metroRafId = requestAnimationFrame(t => metroAnimationFrame(serial, t)); -} - -function startMetronome(){ - ensureAudio(); - clearMetroEndpointClock(); - metroRunning = true; - beatIndex = 0; - metroLastBeatOrdinal = -1; - const serial = metroRunSerial; - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - visual.classList.add('running'); - visual.style.setProperty('--metro-duration', `${metroBeatMs()}ms`); - } - - // Start visibly at the left endpoint, then the RAF clock becomes the single source of truth. - setMetroNeedleExtreme(-1); - syncCleanMetronomeUi(); - requestAnimationFrame(() => { - requestAnimationFrame(t => { - if(!metroRunning || serial !== metroRunSerial) return; - metroRafStart = t; - metroRafId = requestAnimationFrame(tt => metroAnimationFrame(serial, tt)); - }); - }); -} - -function stopMetronome(){ - metroRunning = false; - clearMetroEndpointClock(); - setMetroNeedleAngle(0); - const visual = document.querySelector('#metroCleanVisual'); - if(visual) visual.classList.remove('running','beat-hit','accent-hit'); - syncCleanMetronomeUi(); - renderBeats(); -} - -function tick(){ - fireMetroBeatFromNeedle(Math.max(0, metroLastBeatOrdinal + 1)); -} - -function startPendulumMotion(){ - if(!metroRunning) setMetroNeedleExtreme(-1); -} - -function stopPendulumMotion(reset=true){ - clearMetroEndpointClock(); - if(reset) setMetroNeedleAngle(0); -} - -/* EasyTune v47 — FINAL metronome phase fix. - Start needle at LEFT extreme. Do NOT click at start. - First click/dot/light fires only when the needle reaches RIGHT extreme, - then on every next extreme. Circle/frame pulse stays disabled by CSS. */ -function metroAnimationFrame(serial, now){ - if(!metroRunning || serial !== metroRunSerial) return; - const beatMs = metroBeatMs(); - const elapsed = Math.max(0, now - metroRafStart); - - // Position is the source of truth: t=0 left, t=beatMs right, t=2*beatMs left. - const angle = -metroMaxAngle() * Math.cos(Math.PI * elapsed / beatMs); - setMetroNeedleAngle(angle); - - const beatOrdinal = Math.floor(elapsed / beatMs); - if(beatOrdinal >= 1 && beatOrdinal !== metroLastBeatOrdinal){ - metroLastBeatOrdinal = beatOrdinal; - fireMetroBeatFromNeedle(beatOrdinal); - } - - metroRafId = requestAnimationFrame(t => metroAnimationFrame(serial, t)); -} - -function startMetronome(){ - ensureAudio(); - clearMetroEndpointClock(); - metroRunning = true; - beatIndex = 0; - metroLastBeatOrdinal = 0; // start is visual only; first audible beat is at RIGHT extreme - const serial = metroRunSerial; - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - visual.classList.add('running'); - visual.style.setProperty('--metro-duration', `${metroBeatMs()}ms`); - } - - setMetroNeedleExtreme(-1); - renderBeats(); - syncCleanMetronomeUi(); - - requestAnimationFrame(t => { - if(!metroRunning || serial !== metroRunSerial) return; - metroRafStart = t; - metroRafId = requestAnimationFrame(tt => metroAnimationFrame(serial, tt)); - }); -} - -function stopMetronome(){ - metroRunning = false; - clearMetroEndpointClock(); - setMetroNeedleAngle(0); - const visual = document.querySelector('#metroCleanVisual'); - if(visual) visual.classList.remove('running','beat-hit','accent-hit'); - syncCleanMetronomeUi(); - renderBeats(); -} - -/* EasyTune v48 — metronome endpoint clock final override. - Idle/start needle is LEFT. First sound/dot fires only after the needle reaches RIGHT. - A single timeout-driven endpoint loop controls needle, sound, dots and accent light. */ -let metroEndpointLoopTimer = null; -let metroEndpointSerialFinal = 0; -let metroEndpointSideFinal = -1; - -function metroBeatMs(){ - return Math.max(180, 60000 / bpm); -} -function metroMaxAngle(){ return 38; } -function metroAngleForSide(side){ return side < 0 ? -metroMaxAngle() : metroMaxAngle(); } - -function setMetroNeedleEndpoint(side, animate=false){ - const pendulum = document.querySelector('.metro-clean-pendulum'); - if(!pendulum) return; - pendulum.style.setProperty('animation', 'none', 'important'); - pendulum.style.setProperty('transform-origin', '50% 100%', 'important'); - pendulum.style.setProperty('transition', animate ? `transform ${metroBeatMs()}ms cubic-bezier(.37,0,.63,1)` : 'none', 'important'); - pendulum.style.setProperty('transform', `translateX(-50%) rotate(${metroAngleForSide(side)}deg)`, 'important'); -} - -function clearMetroEndpointLoopFinal(){ - metroEndpointSerialFinal += 1; - if(metroEndpointLoopTimer) window.clearTimeout(metroEndpointLoopTimer); - metroEndpointLoopTimer = null; - if(cleanMetroTimer) window.clearTimeout(cleanMetroTimer); - if(metroTimer) window.clearTimeout(metroTimer); - if(cleanMetroTimer) window.clearInterval(cleanMetroTimer); - if(metroTimer) window.clearInterval(metroTimer); - cleanMetroTimer = null; - metroTimer = null; - if(metroRafId){ cancelAnimationFrame(metroRafId); metroRafId = null; } - if(metroPendulumFrame){ cancelAnimationFrame(metroPendulumFrame); metroPendulumFrame = null; } -} - -function fireMetroEndpointBeatFinal(){ - if(!metroRunning) return; - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - clickSound(accented); - renderBeats(); - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - if(accented){ - void visual.offsetWidth; - visual.classList.add('accent-hit'); - window.setTimeout(() => visual.classList.remove('accent-hit'), 150); - } - } - beatIndex = (beatIndex + 1) % meter; -} - -function runMetroEndpointLoopFinal(serial){ - if(!metroRunning || serial !== metroEndpointSerialFinal) return; - const beatMs = metroBeatMs(); - const nextSide = -metroEndpointSideFinal; - - // Move first. The beat happens only after the visual needle has arrived. - requestAnimationFrame(() => { - if(!metroRunning || serial !== metroEndpointSerialFinal) return; - setMetroNeedleEndpoint(nextSide, true); - }); - - metroEndpointLoopTimer = window.setTimeout(() => { - if(!metroRunning || serial !== metroEndpointSerialFinal) return; - metroEndpointSideFinal = nextSide; - setMetroNeedleEndpoint(metroEndpointSideFinal, false); // snap to exact edge before click - fireMetroEndpointBeatFinal(); - runMetroEndpointLoopFinal(serial); - }, beatMs); - cleanMetroTimer = metroEndpointLoopTimer; - metroTimer = metroEndpointLoopTimer; -} - -function startMetronome(){ - ensureAudio(); - clearMetroEndpointLoopFinal(); - metroRunning = true; - beatIndex = 0; - metroEndpointSideFinal = -1; - const serial = metroEndpointSerialFinal; - const visual = document.querySelector('#metroCleanVisual'); - if(visual){ - visual.classList.remove('beat-hit','accent-hit'); - visual.classList.add('running'); - visual.style.setProperty('--metro-duration', `${metroBeatMs()}ms`); - } - setMetroNeedleEndpoint(-1, false); // visible LEFT start; no sound here - renderBeats(); - syncCleanMetronomeUi(); - runMetroEndpointLoopFinal(serial); -} - -function stopMetronome(){ - metroRunning = false; - clearMetroEndpointLoopFinal(); - metroEndpointSideFinal = -1; - setMetroNeedleEndpoint(-1, false); - const visual = document.querySelector('#metroCleanVisual'); - if(visual) visual.classList.remove('running','beat-hit','accent-hit'); - syncCleanMetronomeUi(); - beatIndex = 0; - renderBeats(); -} - -function tick(){ - fireMetroEndpointBeatFinal(); -} -function startPendulumMotion(){ - if(!metroRunning) setMetroNeedleEndpoint(-1, false); -} -function stopPendulumMotion(reset=true){ - clearMetroEndpointLoopFinal(); - if(reset) setMetroNeedleEndpoint(-1, false); -} - -/* EasyTune v50 — metronom napisany od nowa: start = maksymalny lewy wychył. - Jeden zegar endpointów. Brak dźwięku na starcie. Pierwsze piknięcie dopiero - po dojściu wskazówki do prawego skraju. */ -(function(){ - const LEFT = -1; - const RIGHT = 1; - const MAX_ANGLE = 38; - let endpointTimer = null; - let endpointSerial = 0; - let endpointSide = LEFT; - - function msPerBeat(){ return Math.max(180, 60000 / bpm); } - function angleFor(side){ return side === LEFT ? -MAX_ANGLE : MAX_ANGLE; } - - function needle(){ return document.querySelector('.metro-clean-pendulum'); } - function visual(){ return document.querySelector('#metroCleanVisual'); } - - function forceNeedle(side){ - const p = needle(); - if(!p) return; - p.style.setProperty('animation', 'none', 'important'); - p.style.setProperty('transition', 'none', 'important'); - p.style.setProperty('transform-origin', '50% 100%', 'important'); - p.style.setProperty('transform', `translateX(-50%) rotate(${angleFor(side)}deg)`, 'important'); - } - - function moveNeedle(side){ - const p = needle(); - if(!p) return; - p.style.setProperty('animation', 'none', 'important'); - p.style.setProperty('transition', `transform ${msPerBeat()}ms cubic-bezier(.37,0,.63,1)`, 'important'); - p.style.setProperty('transform-origin', '50% 100%', 'important'); - p.style.setProperty('transform', `translateX(-50%) rotate(${angleFor(side)}deg)`, 'important'); - } - - function clearMetronomeClock(){ - endpointSerial += 1; - if(endpointTimer) window.clearTimeout(endpointTimer); - endpointTimer = null; - if(cleanMetroTimer) { window.clearTimeout(cleanMetroTimer); window.clearInterval(cleanMetroTimer); } - if(metroTimer) { window.clearTimeout(metroTimer); window.clearInterval(metroTimer); } - cleanMetroTimer = null; - metroTimer = null; - if(metroPendulumFrame){ cancelAnimationFrame(metroPendulumFrame); metroPendulumFrame = null; } - if(typeof metroRafId !== 'undefined' && metroRafId){ cancelAnimationFrame(metroRafId); metroRafId = null; } - } - - function fireBeatAtCurrentEdge(){ - if(!metroRunning) return; - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - clickSound(accented); - renderBeats(); - const v = visual(); - if(v){ - v.classList.remove('beat-hit','accent-hit'); - if(accented){ - void v.offsetWidth; - v.classList.add('accent-hit'); - window.setTimeout(() => v.classList.remove('accent-hit'), 150); - } - } - beatIndex = (beatIndex + 1) % meter; - } - - function scheduleMove(serial){ - if(!metroRunning || serial !== endpointSerial) return; - const target = endpointSide === LEFT ? RIGHT : LEFT; - moveNeedle(target); - - endpointTimer = window.setTimeout(() => { - if(!metroRunning || serial !== endpointSerial) return; - endpointSide = target; - forceNeedle(endpointSide); // dokładny skraj PRZED dźwiękiem - fireBeatAtCurrentEdge(); // dźwięk/kropka/światło wyłącznie na skraju - scheduleMove(serial); - }, msPerBeat()); - - cleanMetroTimer = endpointTimer; - metroTimer = endpointTimer; - } - - window.setMetronomeNeedleLeft = function(){ - endpointSide = LEFT; - forceNeedle(LEFT); - }; - - // Nadpisanie poprzednich implementacji. - startMetronome = function(){ - ensureAudio(); - clearMetronomeClock(); - metroRunning = true; - beatIndex = 0; - endpointSide = LEFT; - const serial = endpointSerial; - const v = visual(); - if(v){ - v.classList.remove('beat-hit','accent-hit'); - v.classList.add('running'); - v.style.setProperty('--metro-duration', `${msPerBeat()}ms`); - } - forceNeedle(LEFT); // START: maksymalny lewy wychył - renderBeats(); - syncCleanMetronomeUi(); - requestAnimationFrame(() => scheduleMove(serial)); // pierwsze piknięcie po dojściu do prawego skraju - }; - - stopMetronome = function(){ - metroRunning = false; - clearMetronomeClock(); - endpointSide = LEFT; - forceNeedle(LEFT); // STOP/idle: nadal maksymalny lewy wychył - const v = visual(); - if(v) v.classList.remove('running','beat-hit','accent-hit'); - beatIndex = 0; - syncCleanMetronomeUi(); - renderBeats(); - }; - - startPendulumMotion = function(){ forceNeedle(LEFT); }; - stopPendulumMotion = function(){ clearMetronomeClock(); forceNeedle(LEFT); }; - tick = function(){ fireBeatAtCurrentEdge(); }; - - const previousInitMetronome = initMetronome; - initMetronome = function(){ - previousInitMetronome(); - if(!metroRunning) requestAnimationFrame(() => forceNeedle(LEFT)); - }; -})(); - -/* EasyTune v51 — METRONOME FINAL: RAF is the only clock. - Start/idle needle is max LEFT. No sound at start. First beat fires at max RIGHT. - Sound, dots and accent light are triggered in the same animation frame that draws the endpoint. */ -(function(){ - const LEFT = -1; - const RIGHT = 1; - const MAX_ANGLE = 38; - let rafId = null; - let runSerial = 0; - let runStart = 0; - let lastEndpoint = 0; // 0 means visual start only; first audible endpoint is 1 (RIGHT) - - function beatMs(){ return Math.max(180, 60000 / bpm); } - function needle(){ return document.querySelector('.metro-clean-pendulum'); } - function visual(){ return document.querySelector('#metroCleanVisual'); } - function angleForEndpoint(endpoint){ return endpoint % 2 === 0 ? -MAX_ANGLE : MAX_ANGLE; } - - function drawNeedle(angle){ - const p = needle(); - if(!p) return; - p.style.setProperty('animation', 'none', 'important'); - p.style.setProperty('transition', 'none', 'important'); - p.style.setProperty('transform-origin', '50% 100%', 'important'); - p.style.setProperty('transform', `translateX(-50%) rotate(${angle}deg)`, 'important'); - } - - function drawLeftStart(){ drawNeedle(-MAX_ANGLE); } - - function clearRafClock(){ - runSerial += 1; - if(rafId){ cancelAnimationFrame(rafId); rafId = null; } - if(cleanMetroTimer){ clearTimeout(cleanMetroTimer); clearInterval(cleanMetroTimer); cleanMetroTimer = null; } - if(metroTimer){ clearTimeout(metroTimer); clearInterval(metroTimer); metroTimer = null; } - if(typeof metroEndpointTimer !== 'undefined' && metroEndpointTimer){ clearTimeout(metroEndpointTimer); metroEndpointTimer = null; } - if(typeof metroEndpointLoopTimer !== 'undefined' && metroEndpointLoopTimer){ clearTimeout(metroEndpointLoopTimer); metroEndpointLoopTimer = null; } - if(typeof metroPendulumFrame !== 'undefined' && metroPendulumFrame){ cancelAnimationFrame(metroPendulumFrame); metroPendulumFrame = null; } - if(typeof metroRafId !== 'undefined' && metroRafId){ cancelAnimationFrame(metroRafId); metroRafId = null; } - } - - function fireBeat(){ - if(!metroRunning) return; - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - clickSound(accented); - renderBeats(); - const v = visual(); - if(v){ - v.classList.remove('beat-hit', 'accent-hit'); - if(accented){ - void v.offsetWidth; - v.classList.add('accent-hit'); - setTimeout(() => v.classList.remove('accent-hit'), 140); - } - } - beatIndex = (beatIndex + 1) % meter; - } - - function frame(serial, now){ - if(!metroRunning || serial !== runSerial) return; - const ms = beatMs(); - const elapsed = Math.max(0, now - runStart); - - // One half-swing per beat: 0=LEFT, 1=RIGHT, 2=LEFT... - const endpoint = Math.floor(elapsed / ms); - const inHalf = (elapsed - endpoint * ms) / ms; - - // Draw position first. At endpoint boundaries this is exactly LEFT or RIGHT. - const angle = -MAX_ANGLE * Math.cos(Math.PI * (endpoint + inHalf)); - drawNeedle(Number(angle.toFixed(3))); - - // First sound is endpoint 1 (RIGHT), never endpoint 0 (LEFT start). - if(endpoint >= 1 && endpoint !== lastEndpoint){ - lastEndpoint = endpoint; - drawNeedle(angleForEndpoint(endpoint)); // exact endpoint before audio/UI trigger - fireBeat(); - } - - rafId = requestAnimationFrame(t => frame(serial, t)); - } - - startMetronome = function(){ - ensureAudio(); - clearRafClock(); - metroRunning = true; - beatIndex = 0; - lastEndpoint = 0; - const serial = runSerial; - const v = visual(); - if(v){ - v.classList.add('running'); - v.classList.remove('beat-hit', 'accent-hit'); - v.style.setProperty('--metro-duration', `${beatMs()}ms`); - } - drawLeftStart(); - renderBeats(); - syncCleanMetronomeUi(); - requestAnimationFrame(t => { - if(!metroRunning || serial !== runSerial) return; - runStart = t; - drawLeftStart(); - rafId = requestAnimationFrame(tt => frame(serial, tt)); - }); - }; - - stopMetronome = function(){ - metroRunning = false; - clearRafClock(); - beatIndex = 0; - const v = visual(); - if(v) v.classList.remove('running', 'beat-hit', 'accent-hit'); - drawLeftStart(); - syncCleanMetronomeUi(); - renderBeats(); - }; - - startPendulumMotion = drawLeftStart; - stopPendulumMotion = function(){ clearRafClock(); drawLeftStart(); }; - tick = fireBeat; - - const previousInit = initMetronome; - initMetronome = function(){ - previousInit(); - if(!metroRunning) requestAnimationFrame(drawLeftStart); - }; -})(); - - -/* EasyTune v52 — metronome sync rewrite. - One RAF draws the needle. Audio, dot and accent light are scheduled ahead for - the exact endpoint time, so they happen when the needle reaches LEFT/RIGHT. - Start/idle is always max LEFT. No frame/circle/border blinking. */ -(function(){ - const LEFT = -1; - const RIGHT = 1; - const MAX_ANGLE = 38; - const LOOKAHEAD_MS = 90; - let rafId = null; - let serial = 0; - let startTs = 0; - let nextEndpoint = 1; // endpoint 0 is the silent LEFT start; endpoint 1 is first audible RIGHT - let scheduledUiTimers = []; - - function beatMs(){ return Math.max(180, 60000 / bpm); } - function angleAt(elapsed){ return -MAX_ANGLE * Math.cos(Math.PI * elapsed / beatMs()); } - function needle(){ return document.querySelector('.metro-clean-pendulum'); } - function visual(){ return document.querySelector('#metroCleanVisual'); } - - function setNeedle(angle){ - const p = needle(); - if(!p) return; - p.style.setProperty('animation', 'none', 'important'); - p.style.setProperty('transition', 'none', 'important'); - p.style.setProperty('transform-origin', '50% 100%', 'important'); - p.style.setProperty('transform', `translateX(-50%) rotate(${angle.toFixed(3)}deg)`, 'important'); - } - - function setLeftStart(){ setNeedle(-MAX_ANGLE); } - - function clearAllMetronomeClocks(){ - serial += 1; - if(rafId){ cancelAnimationFrame(rafId); rafId = null; } - scheduledUiTimers.forEach(id => clearTimeout(id)); - scheduledUiTimers = []; - if(cleanMetroTimer){ clearTimeout(cleanMetroTimer); clearInterval(cleanMetroTimer); cleanMetroTimer = null; } - if(metroTimer){ clearTimeout(metroTimer); clearInterval(metroTimer); metroTimer = null; } - if(typeof metroEndpointTimer !== 'undefined' && metroEndpointTimer){ clearTimeout(metroEndpointTimer); metroEndpointTimer = null; } - if(typeof metroEndpointLoopTimer !== 'undefined' && metroEndpointLoopTimer){ clearTimeout(metroEndpointLoopTimer); metroEndpointLoopTimer = null; } - if(typeof metroPendulumFrame !== 'undefined' && metroPendulumFrame){ cancelAnimationFrame(metroPendulumFrame); metroPendulumFrame = null; } - if(typeof metroRafId !== 'undefined' && metroRafId){ cancelAnimationFrame(metroRafId); metroRafId = null; } - } - - function scheduleClickSound(accented, when){ - ensureAudio(); - const osc = audioCtx.createOscillator(); - const gain = audioCtx.createGain(); - osc.type = 'square'; - osc.frequency.setValueAtTime(accented ? 1300 : 820, when); - gain.gain.setValueAtTime(0.0001, when); - gain.gain.exponentialRampToValueAtTime(accented ? 0.22 : 0.13, when + 0.006); - gain.gain.exponentialRampToValueAtTime(0.0001, when + 0.075); - osc.connect(gain).connect(audioCtx.destination); - osc.start(when); - osc.stop(when + 0.085); - } - - function fireUiBeat(accented){ - if(!metroRunning) return; - renderBeats(); - const v = visual(); - if(v){ - v.classList.remove('beat-hit', 'accent-hit'); - if(accented){ - void v.offsetWidth; - v.classList.add('accent-hit'); - const off = setTimeout(() => v.classList.remove('accent-hit'), 140); - scheduledUiTimers.push(off); - } - } - beatIndex = (beatIndex + 1) % meter; - } - - function scheduleEndpointBeat(endpoint, delayMs){ - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - const audioWhen = audioCtx.currentTime + Math.max(0, delayMs) / 1000; - scheduleClickSound(accented, audioWhen); - const id = setTimeout(() => fireUiBeat(accented), Math.max(0, delayMs)); - scheduledUiTimers.push(id); - } - - function frame(mySerial, now){ - if(!metroRunning || mySerial !== serial) return; - const elapsed = Math.max(0, now - startTs); - setNeedle(angleAt(elapsed)); - - const ms = beatMs(); - while(nextEndpoint * ms - elapsed <= LOOKAHEAD_MS){ - const delay = nextEndpoint * ms - elapsed; - if(nextEndpoint >= 1) scheduleEndpointBeat(nextEndpoint, delay); - nextEndpoint += 1; - } - - rafId = requestAnimationFrame(t => frame(mySerial, t)); - } - - startMetronome = function(){ - ensureAudio(); - clearAllMetronomeClocks(); - metroRunning = true; - beatIndex = 0; - nextEndpoint = 1; - const mySerial = serial; - const v = visual(); - if(v){ - v.classList.add('running'); - v.classList.remove('beat-hit', 'accent-hit'); - v.style.setProperty('--metro-duration', `${beatMs()}ms`); - } - setLeftStart(); - renderBeats(); - syncCleanMetronomeUi(); - requestAnimationFrame(t => { - if(!metroRunning || mySerial !== serial) return; - startTs = t; - setLeftStart(); - rafId = requestAnimationFrame(tt => frame(mySerial, tt)); - }); - }; - - stopMetronome = function(){ - metroRunning = false; - clearAllMetronomeClocks(); - beatIndex = 0; - const v = visual(); - if(v) v.classList.remove('running', 'beat-hit', 'accent-hit'); - setLeftStart(); - syncCleanMetronomeUi(); - renderBeats(); - }; - - startPendulumMotion = setLeftStart; - stopPendulumMotion = function(){ clearAllMetronomeClocks(); setLeftStart(); }; - tick = function(){ - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - clickSound(accented); - fireUiBeat(accented); - }; - - const prevInit = initMetronome; - initMetronome = function(){ - prevInit(); - if(!metroRunning) requestAnimationFrame(setLeftStart); - }; -})(); - -/* EasyTune v53 — metronome perceptual-centre sync. - Needle remains the visual clock. For every endpoint, sound, dot transition and - accent light are started early by half of their own duration, so the CENTER - of the beep / dot transition / flash lands on the exact left/right extreme. - This compensates for fixed animation and click lengths at every BPM. */ -(function(){ - const MAX_ANGLE = 38; - const CLICK_DUR_MS = 85; - const DOT_TRANSITION_MS = 80; - const ACCENT_FLASH_MS = 140; - const SCHED_LOOKAHEAD_MS = 180; - let rafId = null; - let serial = 0; - let startTs = 0; - let nextEndpoint = 1; - let timers = []; - - function beatMs(){ return Math.max(180, 60000 / bpm); } - function needle(){ return document.querySelector('.metro-clean-pendulum'); } - function visual(){ return document.querySelector('#metroCleanVisual'); } - function endpointTimeMs(endpoint){ return endpoint * beatMs(); } - function angleAtElapsed(elapsed){ return -MAX_ANGLE * Math.cos(Math.PI * elapsed / beatMs()); } - function angleForEndpoint(endpoint){ return endpoint % 2 === 0 ? -MAX_ANGLE : MAX_ANGLE; } - - function addTimer(id){ timers.push(id); return id; } - - function setNeedleAngle(angle){ - const p = needle(); - if(!p) return; - p.style.setProperty('animation', 'none', 'important'); - p.style.setProperty('transition', 'none', 'important'); - p.style.setProperty('transform-origin', '50% 100%', 'important'); - p.style.setProperty('transform', `translateX(-50%) rotate(${angle.toFixed(3)}deg)`, 'important'); - } - - function setNeedleLeft(){ setNeedleAngle(-MAX_ANGLE); } - - function clearMetroSync(){ - serial += 1; - if(rafId){ cancelAnimationFrame(rafId); rafId = null; } - timers.forEach(id => clearTimeout(id)); - timers = []; - if(cleanMetroTimer){ clearTimeout(cleanMetroTimer); clearInterval(cleanMetroTimer); cleanMetroTimer = null; } - if(metroTimer){ clearTimeout(metroTimer); clearInterval(metroTimer); metroTimer = null; } - if(typeof metroEndpointTimer !== 'undefined' && metroEndpointTimer){ clearTimeout(metroEndpointTimer); metroEndpointTimer = null; } - if(typeof metroEndpointLoopTimer !== 'undefined' && metroEndpointLoopTimer){ clearTimeout(metroEndpointLoopTimer); metroEndpointLoopTimer = null; } - if(typeof metroPendulumFrame !== 'undefined' && metroPendulumFrame){ cancelAnimationFrame(metroPendulumFrame); metroPendulumFrame = null; } - if(typeof metroRafId !== 'undefined' && metroRafId){ cancelAnimationFrame(metroRafId); metroRafId = null; } - } - - function scheduleAudio(accented, endpointDelayMs){ - ensureAudio(); - const startWhen = audioCtx.currentTime + Math.max(0, endpointDelayMs - CLICK_DUR_MS / 2) / 1000; - const osc = audioCtx.createOscillator(); - const gain = audioCtx.createGain(); - osc.type = 'square'; - osc.frequency.setValueAtTime(accented ? 1300 : 820, startWhen); - gain.gain.setValueAtTime(0.0001, startWhen); - gain.gain.exponentialRampToValueAtTime(accented ? 0.22 : 0.13, startWhen + 0.006); - gain.gain.exponentialRampToValueAtTime(0.0001, startWhen + CLICK_DUR_MS / 1000); - osc.connect(gain).connect(audioCtx.destination); - osc.start(startWhen); - osc.stop(startWhen + (CLICK_DUR_MS + 8) / 1000); - } - - function applyBeatUi(accented){ - if(!metroRunning) return; - renderBeats(); - const v = visual(); - if(v){ - v.classList.remove('beat-hit', 'accent-hit'); - if(accented){ - void v.offsetWidth; - v.classList.add('accent-hit'); - addTimer(setTimeout(() => v.classList.remove('accent-hit'), ACCENT_FLASH_MS)); - } - } - beatIndex = (beatIndex + 1) % meter; - } - - function scheduleEndpoint(endpoint, endpointDelayMs){ - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - scheduleAudio(accented, endpointDelayMs); - - const dotStart = Math.max(0, endpointDelayMs - DOT_TRANSITION_MS / 2); - addTimer(setTimeout(() => applyBeatUi(accented), dotStart)); - } - - function frame(mySerial, now){ - if(!metroRunning || mySerial !== serial) return; - const elapsed = Math.max(0, now - startTs); - setNeedleAngle(angleAtElapsed(elapsed)); - - const endpointDelay = endpointTimeMs(nextEndpoint) - elapsed; - while(endpointDelay <= SCHED_LOOKAHEAD_MS){ - if(nextEndpoint >= 1){ - scheduleEndpoint(nextEndpoint, endpointTimeMs(nextEndpoint) - elapsed); - } - nextEndpoint += 1; - if(endpointTimeMs(nextEndpoint) - elapsed > SCHED_LOOKAHEAD_MS) break; - } - - rafId = requestAnimationFrame(t => frame(mySerial, t)); - } - - startMetronome = function(){ - ensureAudio(); - clearMetroSync(); - metroRunning = true; - beatIndex = 0; - nextEndpoint = 1; - const mySerial = serial; - const v = visual(); - if(v){ - v.classList.add('running'); - v.classList.remove('beat-hit', 'accent-hit'); - v.style.setProperty('--metro-duration', `${beatMs()}ms`); - } - setNeedleLeft(); - renderBeats(); - syncCleanMetronomeUi(); - requestAnimationFrame(t => { - if(!metroRunning || mySerial !== serial) return; - startTs = t; - setNeedleLeft(); - rafId = requestAnimationFrame(tt => frame(mySerial, tt)); - }); - }; - - stopMetronome = function(){ - metroRunning = false; - clearMetroSync(); - beatIndex = 0; - const v = visual(); - if(v) v.classList.remove('running', 'beat-hit', 'accent-hit'); - setNeedleLeft(); - syncCleanMetronomeUi(); - renderBeats(); - }; - - startPendulumMotion = setNeedleLeft; - stopPendulumMotion = function(){ clearMetroSync(); setNeedleLeft(); }; - tick = function(){ - const accented = accentMode === 'all' || (accentMode === 'first' && beatIndex === 0); - scheduleAudio(accented, CLICK_DUR_MS / 2); - applyBeatUi(accented); - }; - - const prevInit = initMetronome; - initMetronome = function(){ - prevInit(); - if(!metroRunning) requestAnimationFrame(setNeedleLeft); - }; -})(); - -/* EasyTune v55 — BPM display button opens Tempo modal */ -(function(){ - var prevInit = initMetronome; - initMetronome = function(){ - prevInit(); - document.querySelector('#metroCleanBpmButton')?.addEventListener('click', function(){ - openMetroSettings('metroTempoModal'); - }); - }; -})(); +loadManifestVersion().then(() => { showApp(); syncInstallButtons(); }); From 4e53a6dc72fb2598d693ca92d4711e04e6dfef4e Mon Sep 17 00:00:00 2001 From: awj Date: Sun, 21 Jun 2026 15:31:20 +0200 Subject: [PATCH 7/8] Delete styles.css --- styles.css | 1088 ---------------------------------------------------- 1 file changed, 1088 deletions(-) delete mode 100644 styles.css diff --git a/styles.css b/styles.css deleted file mode 100644 index e2bcbbb..0000000 --- a/styles.css +++ /dev/null @@ -1,1088 +0,0 @@ -:root { - --bg: #120904; - --bg-soft: #1a0f08; - --panel: #2b190f; - --panel-2: #3b2112; - --text: #fff7ed; - --muted: #c9a98e; - --accent: #EA9516; - --green: #22c55e; - --line: rgba(255, 247, 237, .12); - --header-height: clamp(90px, 13vh, 110px); - --shell-radius: 32px; -} - -* { box-sizing: border-box; } - -html, -body { - margin: 0; - min-height: 100%; -} - -body { - font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; - color: var(--text); - background: - radial-gradient(circle at 50% -90px, rgba(234,149,22,.18), transparent 310px), - linear-gradient(180deg, var(--bg-soft), var(--bg)); - overflow-x: hidden; -} - -button { font: inherit; } - -/* SPLASH */ - -.splash { - position: fixed; - inset: 0; - z-index: 20; - display: grid; - place-items: center; - padding: max(24px, env(safe-area-inset-top)) 24px max(28px, env(safe-area-inset-bottom)); - background: - radial-gradient(circle at 50% 45%, rgba(234,149,22,.22), transparent 360px), - linear-gradient(180deg, #2b190f 0%, #1a0f08 48%, #120904 100%); - transition: opacity .38s ease, visibility .38s ease; -} - -.splash.is-hidden { - opacity: 0; - visibility: hidden; -} - -.splash-logo { - width: min(64vw, 420px); - height: auto; - display: block; - object-fit: contain; - filter: drop-shadow(0 18px 36px rgba(0,0,0,.34)); -} - -.splash-version { - position: fixed; - left: 0; - right: 0; - bottom: max(18px, env(safe-area-inset-bottom)); - text-align: center; - color: rgba(255,247,237,.42); - font-size: 11px; - letter-spacing: .14em; - font-weight: 700; -} - -/* APP SHELL */ - -.app { - min-height: 100svh; - padding: 14px 16px max(18px, env(safe-area-inset-bottom)); - background: - radial-gradient(circle at 50% -60px, rgba(234,149,22,.14), transparent 260px), - linear-gradient(180deg, #1a0f08 0%, #120904 100%); -} - -.app-header { - position: sticky; - top: 0; - z-index: 10; - width: 100%; - min-height: var(--header-height); - height: var(--header-height); - padding: calc(env(safe-area-inset-top) + 12px) 14px 12px 28px; - display: flex; - align-items: center; - justify-content: space-between; - gap: 16px; - background: - radial-gradient(circle at 24% 12%, rgba(234,149,22,.16), transparent 220px), - linear-gradient(180deg, #321a0b 0%, #1d0f08 100%); - border: 1px solid var(--line); - border-bottom: 0; - border-radius: var(--shell-radius) var(--shell-radius) 0 0; - box-shadow: - inset 0 1px 0 rgba(255,255,255,.07), - 0 10px 26px rgba(0,0,0,.32); -} - -.header-logo { - width: min(48vw, 300px); - max-height: calc(var(--header-height) - 42px); - height: auto; - display: block; - object-fit: contain; - object-position: left center; - flex: 0 1 auto; -} - -.options-button { - flex: 0 0 34px; - width: 34px; - height: 44px; - border: 0; - border-radius: 16px; - background: transparent; - display: inline-flex; - align-items: center; - justify-content: center; - cursor: pointer; - color: rgba(255,247,237,.58); - font-size: 24px; - line-height: 1; - -webkit-tap-highlight-color: transparent; -} - -.options-button::before { - content: "⋮"; - display: block; - transform: translateY(-1px); -} - -.options-button span { display: none; } -.options-button:active { transform: scale(.96); } - -/* CONTENT */ - -.content { - padding: 0; - margin: 0; -} - -.start-panel { - width: 100%; - min-height: calc(100svh - var(--header-height) - 42px); - margin: 0; - border-left: 1px solid var(--line); - border-right: 1px solid var(--line); - border-bottom: 1px solid var(--line); - border-top: 0; - border-radius: 0 0 var(--shell-radius) var(--shell-radius); - background: - linear-gradient(180deg, rgba(59,33,18,.52), rgba(43,25,15,.32)); - box-shadow: - inset 0 1px 0 rgba(255,255,255,.04), - 0 18px 44px rgba(0,0,0,.22); -} - -.home-screen { - position: relative; - overflow: hidden; - display: grid; - gap: 18px; - padding: 24px 20px 28px; - background: - linear-gradient(90deg, rgba(18,9,4,.92), rgba(18,9,4,.55), rgba(18,9,4,.92)), - linear-gradient(180deg, rgba(59,33,18,.45), rgba(18,9,4,.56)); -} - -.home-card-bg { - position: absolute; - inset: 0; - pointer-events: none; - opacity: .33; - background-image: - linear-gradient(90deg, transparent 0 18%, rgba(255,247,237,.08) 18.2% 18.45%, transparent 18.65% 34%, rgba(255,247,237,.08) 34.2% 34.45%, transparent 34.65% 50%, rgba(255,247,237,.08) 50.2% 50.5%, transparent 50.7%), - linear-gradient(180deg, transparent 0 17%, rgba(234,149,22,.08) 17.1% 17.45%, transparent 17.55% 34%, rgba(234,149,22,.08) 34.1% 34.45%, transparent 34.55% 51%, rgba(234,149,22,.08) 51.1% 51.45%, transparent 51.65%); - background-size: 190px 190px; - transform: rotate(-.4deg) scale(1.08); - transform-origin: center; - mask-image: linear-gradient(90deg, transparent 0, black 16%, black 84%, transparent 100%); -} - -.tool-card { - position: relative; - isolation: isolate; - overflow: hidden; - width: 100%; - min-height: 104px; - padding: 22px 56px 20px 22px; - border: 1px solid rgba(255,247,237,.13); - border-radius: 28px; - background: - radial-gradient(circle at 18% 10%, rgba(234,149,22,.12), transparent 210px), - linear-gradient(90deg, rgba(78,42,21,.92) 0%, rgba(55,30,16,.88) 48%, rgba(30,16,8,.92) 100%); - color: var(--text); - text-align: left; - box-shadow: - inset 0 1px 0 rgba(255,255,255,.08), - inset 0 -1px 0 rgba(0,0,0,.28), - 0 16px 30px rgba(0,0,0,.24); - cursor: pointer; - -webkit-tap-highlight-color: transparent; -} - -.tool-card::before { - content: ""; - position: absolute; - inset: 0; - z-index: -2; - background: - linear-gradient(110deg, rgba(234,149,22,.17), transparent 34%), - radial-gradient(circle at 82% 45%, rgba(234,149,22,.13), transparent 160px); - opacity: .82; -} - -.tool-card::after { - content: ""; - position: absolute; - inset: 0; - z-index: -1; - background: linear-gradient(90deg, rgba(0,0,0,0) 0 43%, rgba(0,0,0,.18) 62%, rgba(0,0,0,.36) 100%); -} - -.tool-card:active { - transform: scale(.985); -} - -.tool-copy { - position: relative; - z-index: 2; - display: block; - max-width: 58%; -} - -.tool-title { - display: block; - font-size: clamp(24px, 5.4vw, 34px); - line-height: 1; - font-weight: 850; - letter-spacing: -.045em; - color: var(--text); - text-shadow: 0 2px 8px rgba(0,0,0,.34); -} - -.tool-desc { - display: block; - margin-top: 8px; - color: rgba(229,200,176,.92); - font-size: clamp(13px, 3.2vw, 18px); - line-height: 1.18; - font-weight: 500; - letter-spacing: -.025em; -} - -.tool-arrow { - position: absolute; - right: 22px; - top: 50%; - z-index: 4; - transform: translateY(-50%); - color: var(--accent); - font-size: 42px; - line-height: .8; - font-weight: 300; - text-shadow: 0 0 18px rgba(234,149,22,.28); -} - -.fret-art { - position: absolute; - right: 44px; - top: 50%; - z-index: 1; - width: 36%; - height: 92%; - transform: translateY(-50%) rotate(-7deg); - opacity: .52; - background-image: - linear-gradient(90deg, transparent 0 19%, rgba(255,247,237,.20) 19.3% 19.9%, transparent 20.2% 38%, rgba(255,247,237,.20) 38.3% 38.9%, transparent 39.2% 57%, rgba(255,247,237,.20) 57.3% 57.9%, transparent 58.1%), - linear-gradient(180deg, transparent 0 18%, rgba(255,247,237,.18) 18.4% 19.9%, transparent 20.3% 35%, rgba(255,247,237,.18) 35.4% 36.9%, transparent 37.3% 52%, rgba(255,247,237,.18) 52.4% 53.9%, transparent 54.3%); - filter: drop-shadow(0 14px 22px rgba(0,0,0,.18)); - mask-image: linear-gradient(90deg, transparent 0, black 18%, black 90%, transparent 100%); -} - -.dot { - position: absolute; - width: 20px; - height: 20px; - border-radius: 999px; - background: #c77a0a; - box-shadow: - inset 0 1px 0 rgba(255,255,255,.20), - 0 6px 14px rgba(0,0,0,.32), - 0 0 20px rgba(234,149,22,.18); -} - -.fret-art-transpose .dot-a { left: 30%; top: 34%; } -.fret-art-transpose .dot-b { left: 68%; top: 55%; } -.fret-art-chords .dot-a { left: 24%; top: 60%; } -.fret-art-chords .dot-b { left: 52%; top: 36%; } -.fret-art-chords .dot-c { left: 76%; top: 50%; } -.fret-art-metronome .dot-green { - left: 54%; - top: 50%; - background: var(--green); - box-shadow: - inset 0 1px 0 rgba(255,255,255,.20), - 0 6px 14px rgba(0,0,0,.32), - 0 0 20px rgba(34,197,94,.20); -} - -/* OPTIONS MENU */ - -.options-menu { - position: fixed; - top: calc(var(--header-height) + 4px); - right: 16px; - z-index: 30; - min-width: 220px; - padding: 8px; - border: 1px solid rgba(255,247,237,.12); - border-radius: 20px; - background: rgba(43,25,15,.98); - box-shadow: 0 22px 46px rgba(0,0,0,.44); -} - -.options-menu button { - width: 100%; - border: 0; - border-radius: 14px; - background: transparent; - color: var(--text); - padding: 12px 14px; - text-align: left; -} - -.options-menu button:active { - background: rgba(255,247,237,.08); -} - -/* SMALL SCREENS */ - -@media (max-width: 430px) { - :root { - --header-height: clamp(88px, 13vh, 106px); - --shell-radius: 30px; - } - - .app { - padding: 12px 14px max(16px, env(safe-area-inset-bottom)); - } - - .app-header { - padding-left: 24px; - padding-right: 14px; - } - - .header-logo { - width: min(54vw, 245px); - max-height: calc(var(--header-height) - 38px); - } - - .options-button { - width: 32px; - flex-basis: 32px; - font-size: 22px; - } - - .home-screen { - gap: 14px; - padding: 20px 16px 24px; - } - - .tool-card { - min-height: 100px; - padding: 20px 48px 18px 18px; - border-radius: 26px; - } - - .tool-copy { - max-width: 62%; - } - - .tool-title { - font-size: clamp(23px, 6.4vw, 31px); - } - - .tool-desc { - margin-top: 7px; - font-size: clamp(12px, 3.6vw, 16px); - } - - .fret-art { - right: 34px; - width: 34%; - height: 86%; - } - - .tool-arrow { - right: 18px; - font-size: 38px; - } - - .dot { - width: 18px; - height: 18px; - } -} - -/* FUNCTIONAL VIEWS */ -.logo-button{ - border:0; - padding:0; - margin:0; - background:transparent; - display:flex; - align-items:center; - min-width:0; - cursor:pointer; - -webkit-tap-highlight-color:transparent; -} -.logo-button:active{transform:scale(.985)} - -.view-screen{ - position:relative; - overflow:hidden; - padding:16px 14px 20px; - background: - radial-gradient(circle at 50% 0%, rgba(234,149,22,.07), transparent 18rem), - linear-gradient(180deg, rgba(59,33,18,.44), rgba(18,9,4,.60)); -} - -.view-head{ - display:flex; - align-items:center; - justify-content:space-between; - gap:12px; - margin:0 0 14px; -} - -.view-title{ - margin:0; - font-size:clamp(22px,5.4vw,30px); - line-height:1; - letter-spacing:-.045em; - font-weight:850; -} - -.back-btn, -.small-action, -.ghost-btn, -.primary-btn, -.round-btn, -.filter-chip, -.preset-bpm, -.meter-btn, -.accent-btn{ - border:1px solid rgba(255,247,237,.13); - color:var(--text); - background:rgba(59,33,18,.72); - border-radius:12px!important; - cursor:pointer; - -webkit-tap-highlight-color:transparent; -} -.back-btn{width:42px;height:42px;font-size:28px;line-height:1;display:grid;place-items:center;color:var(--accent)} -.small-action{padding:10px 12px;font-size:13px;font-weight:800;color:var(--muted)} -.ghost-btn{padding:12px 14px;color:var(--muted);font-weight:800} -.primary-btn{padding:13px 16px;background:linear-gradient(180deg,#EA9516,#b96c0c);color:#2a1204;font-weight:950;border-color:rgba(255,218,160,.28)} -.round-btn{width:48px;height:48px;border-radius:999px;font-size:24px;color:var(--accent);display:grid;place-items:center} -.back-btn:active,.small-action:active,.ghost-btn:active,.primary-btn:active,.round-btn:active{transform:scale(.97)} - -.view-card{ - position:relative; - border:1px solid rgba(255,255,255,.10); - border-radius:14px; - padding:14px; - background: - radial-gradient(circle at 16% 0%, rgba(234,149,22,.08), transparent 180px), - linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,.012)), - linear-gradient(145deg, rgba(43,25,15,.72), rgba(18,9,4,.72)); - box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 12px 28px rgba(0,0,0,.22); -} -.view-card + .view-card{margin-top:12px} - -.form-label,.group-label,.transpose-heading{ - display:block; - color:#f8fafc!important; - font-size:13px!important; - font-weight:650!important; - letter-spacing:.02em!important; - text-transform:none!important; - margin:0 0 10px; -} - -.song-input, -.search-input, -.output-box{ - width:100%; - border:1px solid rgba(255,255,255,.08)!important; - border-radius:12px!important; - background:#111827!important; - color:var(--text); - padding:14px; - outline:0; - box-shadow:inset 0 1px 0 rgba(255,255,255,.04); -} -.song-input{min-height:160px;resize:vertical;line-height:1.45;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:14px} -.search-input{height:48px;font-size:15px} -.song-input:focus,.search-input:focus{border-color:rgba(234,149,22,.48);box-shadow:0 0 0 3px rgba(234,149,22,.12)} - -.transpose-controls{ - display:grid; - grid-template-columns:48px 1fr 48px; - align-items:center; - gap:10px; - margin:14px auto 12px; - max-width:210px; -} -.transpose-value{ - text-align:center; - color:var(--muted); - font-weight:850; - line-height:1.15; - border-radius:12px; - background:#111827; - border:1px solid rgba(255,255,255,.08); - padding:7px 8px; -} -.transpose-value span{ - display:block; - font-size:11px; - color:rgba(248,250,252,.62); -} -.transpose-value strong{ - display:block; - color:var(--accent); - font-size:28px!important; - font-weight:300!important; - color:#f8fafc!important; - letter-spacing:-.05em; -} -.transpose-actions{display:flex;gap:10px;margin-top:12px;flex-wrap:wrap} - -.output-line{min-height:1.55em} -.chord-token{ - display:inline-flex; - align-items:center; - justify-content:center; - margin:0 2px 2px; - padding:2px 8px 3px; - border:0; - border-radius:10px; - background:linear-gradient(180deg,#FFB83D,#EA9516); - color:#111827; - font:inherit; - font-weight:850; - cursor:pointer; - vertical-align:baseline; - box-shadow:0 4px 10px rgba(234,149,22,.18), inset 0 1px 0 rgba(255,255,255,.22); -} -.chord-token:active{transform:scale(.96)} - -.filter-row{display:flex;gap:8px;overflow:auto;padding:2px 2px 12px;margin:0 -2px 10px;scrollbar-width:none} -.filter-row::-webkit-scrollbar{display:none} -.filter-chip{flex:0 0 auto;padding:9px 12px;cursor:pointer} -.filter-chip.active{background:rgba(234,149,22,.18);border-color:rgba(234,149,22,.44);color:var(--accent)} - -.chord-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px} -.chord-card{ - border:1px solid rgba(255,255,255,.10); - border-radius:14px; - background: - radial-gradient(circle at 20% 0%, rgba(234,149,22,.10), transparent 120px), - linear-gradient(180deg,rgba(255,255,255,.035),rgba(255,255,255,.012)), - linear-gradient(145deg,rgba(43,25,15,.78),rgba(18,9,4,.68)); - padding:12px; - color:var(--text); - cursor:pointer; - box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 10px 22px rgba(0,0,0,.16); -} -.chord-card:active{transform:scale(.985)} -.chord-card-head{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:8px} -.chord-name{font-size:24px;line-height:1;font-weight:950;color:var(--accent);letter-spacing:-.04em} -.chord-card .chord-name, -#chordGrid .chord-name{ - display:inline-flex; - align-items:center; - justify-content:center; - min-width:56px; - padding:5px 12px; - border-radius:11px; - background:linear-gradient(180deg,#FFB83D,#EA9516); - color:#111827; - font-weight:850; - box-shadow:0 6px 16px rgba(234,149,22,.22), inset 0 1px 0 rgba(255,255,255,.25); -} -.chord-notes{font-size:11px;color:var(--muted);line-height:1.25;text-align:right} -.diagram{width:100%;height:auto;display:block;background:rgba(17,24,39,.70);border-radius:12px;padding:4px;border:1px solid rgba(255,255,255,.07)} -.diagram line{stroke:rgba(255,247,237,.42);stroke-width:2;stroke-linecap:round} -.diagram .fret{stroke:rgba(234,149,22,.40);stroke-width:3} -.diagram circle{fill:var(--accent);filter:drop-shadow(0 4px 8px rgba(0,0,0,.32))} -.diagram text{fill:rgba(255,247,237,.78);font-size:10px;font-weight:800} - -/* CHORD MODAL */ -.chord-modal, -.app-modal, -.metro-visual-modal{ - position:fixed; - inset:0; - z-index:90; - display:none; - align-items:center; - justify-content:center; - padding:14px; - background:rgba(0,0,0,.68); - backdrop-filter:blur(10px); -} -.chord-modal.visible, -.app-modal.visible, -.metro-visual-modal.visible{display:flex} - -.chord-modal-card{ - position:relative; - width:min(390px,94vw); - min-height:min(760px,92vh); - max-height:92vh; - overflow:auto; - border-radius:28px; - padding:58px 24px 24px; - background: - radial-gradient(circle at 50% 0%, rgba(234,149,22,.08), transparent 19rem), - linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.018)), - linear-gradient(145deg,#111a22,#070d13); - border:1px solid rgba(255,255,255,.12); - box-shadow:0 28px 80px rgba(0,0,0,.62); - color:#f8fafc; -} -.modal-close, -.app-modal-close, -.metro-visual-close{ - position:absolute; - top:16px; - right:16px; - width:38px; - height:38px; - padding:0; - border:0; - border-radius:50%; - background:transparent; - color:#f8fafc; - font-size:34px; - font-weight:300; - line-height:1; - cursor:pointer; - z-index:3; -} -.modal-chord-title{ - display:inline-flex; - align-items:center; - justify-content:center; - min-width:132px; - min-height:88px; - margin:0 auto 14px; - padding:10px 18px; - border-radius:16px; - background:linear-gradient(180deg,#FFB83D,#EA9516); - color:#111827; - font-size:58px; - font-weight:850; - line-height:1; - letter-spacing:-.06em; - box-shadow:0 8px 22px rgba(234,149,22,.28), inset 0 1px 0 rgba(255,255,255,.25); -} -.modal-chord-sub{ - margin:0 0 18px; - color:rgba(248,250,252,.76); - font-size:15px; - text-align:center; -} -.modal-chord-sub::before{content:"Dźwięki: ";color:rgba(248,250,252,.64)} -.modal-diagram{ - width:min(300px,82vw); - max-width:300px; - margin:8px auto 20px; - display:block; - background:transparent; - border:0; - border-radius:0; - padding:0; - filter:drop-shadow(0 14px 30px rgba(0,0,0,.35)); -} -.modal-diagram line{stroke:rgba(248,250,252,.72)!important;stroke-width:2.2;stroke-linecap:round} -.modal-diagram .fret{stroke:rgba(248,250,252,.72)!important;stroke-width:3.2} -.modal-diagram circle{fill:#EA9516!important;filter:drop-shadow(0 6px 10px rgba(0,0,0,.36))} -.modal-diagram text{fill:#f8fafc!important;font-weight:700!important} -#chord-modal-content::after{ - content:"x – nie graj\A O – graj otwartą strunę\A 1, 2, 3, 4 – nr progu"; - display:block; - white-space:pre-line; - text-align:left; - margin:8px auto 0; - width:min(300px,82vw); - color:rgba(248,250,252,.78); - font-size:14px; - line-height:1.65; -} - -.app-modal-card{ - position:relative; - width:min(360px,94vw); - border-radius:24px; - padding:22px 18px 18px; - background: - radial-gradient(circle at 50% 0%, rgba(234,149,22,.10), transparent 18rem), - linear-gradient(145deg,#151f29,#081018); - border:1px solid rgba(255,255,255,.14); - box-shadow:0 34px 90px rgba(0,0,0,.56); - color:#f8fafc; -} -.app-modal-card h2{margin:0 42px 14px 0;font-size:22px;letter-spacing:-.03em} -.app-modal-card p{color:rgba(248,250,252,.78);line-height:1.45;margin:0 0 14px} - -/* Metronom — responsywne skalowanie */ -.metro-layout{display:grid;gap:12px} -.metro-display{display:grid;place-items:center;gap:14px;text-align:center;padding:16px!important} -.bpm-dial{ - width:190px; - height:190px; - border-radius:50%; - display:grid; - place-items:center; - position:relative; - background: - radial-gradient(circle at 50% 36%, rgba(234,149,22,.16), transparent 48%), - linear-gradient(145deg,#17212b,#081018); - border:1px solid rgba(255,255,255,.13); - box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 20px 44px rgba(0,0,0,.32); -} -.bpm{display:grid;text-align:center;line-height:1} -.bpm span{font-size:52px;font-weight:300;color:#f8fafc;letter-spacing:-.06em} -.bpm small{font-size:12px;color:rgba(248,250,252,.62);letter-spacing:.16em;margin-top:6px} -.meter-in-dial{position:absolute;bottom:32px;color:rgba(248,250,252,.62);font-size:13px} -.bpm-slider{width:100%;accent-color:var(--accent)} -.preset-grid,.meter-buttons,.accent-buttons{display:grid;grid-template-columns:repeat(3,1fr);gap:8px} -.preset-bpm,.meter-btn,.accent-btn{ - min-height:42px; - border:1px solid rgba(255,255,255,.10); - background:rgba(17,24,39,.66); - color:#f8fafc; - font-weight:700; - padding:10px 6px; -} -.preset-bpm.active,.meter-btn.active,.accent-btn.active{ - background:rgba(234,149,22,.18); - border-color:rgba(234,149,22,.48); - color:#EA9516; -} -.beats{ - display:flex; - justify-content:center; - align-items:center; - gap:12px; - min-height:56px; - cursor:pointer; - position:relative; -} -.beats::after{ - content:"dotknij, aby powiększyć"; - position:absolute; - top:-24px; - left:50%; - transform:translateX(-50%); - white-space:nowrap; - color:rgba(248,250,252,.52); - font-size:11px; -} -.beat{ - width:18px; - height:18px; - border-radius:50%; - background:rgba(248,250,252,.18); - border:1px solid rgba(255,255,255,.10); -} -.beat.accent{box-shadow:0 0 0 2px rgba(234,149,22,.16)} -.beat.active{background:#EA9516;box-shadow:0 0 22px rgba(234,149,22,.45)} -.beat.active.accent{background:#22c55e;box-shadow:0 0 22px rgba(34,197,94,.42)} - -.metro-visual-card{ - position:relative; - width:min(380px,94vw); - border-radius:28px; - padding:54px 22px 22px; - background: - radial-gradient(circle at 50% 0%, rgba(234,149,22,.10), transparent 18rem), - linear-gradient(145deg,#151f29,#081018); - border:1px solid rgba(255,255,255,.14); - box-shadow:0 34px 90px rgba(0,0,0,.56); - color:#f8fafc; - text-align:center; -} -.metro-visual-card h2{margin:0 44px 14px 0;font-size:24px;letter-spacing:-.04em;text-align:left} -.metro-visual{ - width:min(260px,74vw); - height:300px; - margin:0 auto 14px; - position:relative; - display:grid; - place-items:center; -} -.metro-arc{ - position:absolute; - inset:28px 28px 56px; - border-radius:160px 160px 28px 28px; - border:1px solid rgba(255,255,255,.12); - background:radial-gradient(circle at 50% 0%,rgba(234,149,22,.12),transparent 66%); -} -.metro-pendulum{ - position:absolute; - bottom:62px; - left:50%; - width:4px; - height:190px; - transform-origin:50% 100%; - transform:translateX(-50%) rotate(-24deg); - background:linear-gradient(180deg,rgba(248,250,252,.76),rgba(234,149,22,.76)); - border-radius:999px; - animation:metroSwing 1s ease-in-out infinite alternate; - animation-play-state:paused; -} -.metro-visual-modal.running .metro-pendulum{animation-play-state:running} -.metro-pendulum span{ - position:absolute; - top:40px; - left:50%; - transform:translateX(-50%); - width:34px; - height:34px; - border-radius:50%; - background:linear-gradient(180deg,#FFB83D,#EA9516); - box-shadow:0 10px 26px rgba(234,149,22,.28); -} -.metro-weight{ - position:absolute; - bottom:52px; - left:50%; - transform:translateX(-50%); - width:94px; - height:38px; - border-radius:50%; - background:linear-gradient(180deg,#FFB83D,#EA9516); - box-shadow:0 12px 28px rgba(234,149,22,.35); -} -.metro-visual-center{position:absolute;display:grid;place-items:center;gap:2px} -.metro-visual-center strong{font-size:48px;font-weight:300;letter-spacing:-.06em} -.metro-visual-center span{font-size:11px;color:rgba(248,250,252,.62);letter-spacing:.16em} -.metro-visual-center em{font-style:normal;color:rgba(248,250,252,.62);font-size:13px} -.metro-big-beats{display:flex;justify-content:center;gap:10px;margin:8px 0 14px} -.metro-modal-controls{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:12px} - -@keyframes metroSwing{ - from{transform:translateX(-50%) rotate(-24deg)} - to{transform:translateX(-50%) rotate(24deg)} -} - -@media (max-width:430px){ - .view-screen{padding:14px 12px 18px} - .view-card{padding:12px;border-radius:12px} - .modal-chord-title{font-size:48px;min-height:78px;min-width:118px} - .chord-modal-card{width:calc(100vw - 24px);min-height:calc(100svh - 42px);border-radius:24px;padding:54px 20px 22px} - .modal-diagram,#chord-modal-content::after{width:min(286px,84vw)} - .bpm-dial{width:176px;height:176px} - .bpm span{font-size:46px} - .preset-grid,.meter-buttons,.accent-buttons{grid-template-columns:repeat(3,1fr)} -} - -/* ===================================================== - EasyTune v1.3 — RESPONSYWNY METRONOM - ===================================================== */ - -.metro-clean-screen{ - --metro-scale: 1; - --metro-visual-width: 360px; - --metro-visual-ratio: 1.16; - padding: clamp(12px, 2vh, 20px) clamp(12px, 1.5vw, 18px) clamp(10px, 1.5vh, 16px) !important; -} - -.metro-clean-main{ - width: min(100%, 760px) !important; - margin: 0 auto !important; - display: grid; - gap: clamp(10px, 1.8vh, 18px) !important; - justify-items: stretch !important; -} - -.metro-clean-visual{ - --metro-duration: .6s; - width: min(100%, var(--metro-visual-width)) !important; - height: calc(var(--metro-visual-width) * var(--metro-visual-ratio)) !important; - min-height: 0 !important; - margin: 0 auto !important; - position: relative; - border-radius: clamp(18px, calc(24px * var(--metro-scale)), 28px) !important; - overflow: hidden; - display: grid; - place-items: center; - background: - radial-gradient(circle at 50% 46%, rgba(234,149,22,.14), transparent 54%), - linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.018)), - linear-gradient(145deg, #111a22, #070d13); - border: 1px solid rgba(234,149,22,.24); - box-shadow: inset 0 1px 0 rgba(255,255,255,.06), 0 24px 60px rgba(0,0,0,.35); -} - -.metro-clean-visual::before{ - content: ""; - position: absolute; - left: 50%; - top: 50%; - width: calc(300px * var(--metro-scale)) !important; - height: calc(300px * var(--metro-scale)) !important; - transform: translate(-50%, -50%); - border-radius: 50%; - border: 2px solid rgba(234,149,22,.22); - background: radial-gradient(circle, rgba(234,149,22,.10), transparent 62%); -} - -.metro-clean-scale{ - position: absolute; - top: calc(56px * var(--metro-scale)) !important; - left: 50%; - transform: translateX(-50%); - width: calc(190px * var(--metro-scale)) !important; - height: calc(78px * var(--metro-scale)) !important; - border-radius: calc(190px * var(--metro-scale)) calc(190px * var(--metro-scale)) 0 0 !important; - border: 1px solid rgba(234,149,22,.22); - background: radial-gradient(circle at 50% 0%, rgba(234,149,22,.12), transparent 66%); -} - -.metro-clean-scale::before, -.metro-clean-scale::after{ - content: ""; - position: absolute; - top: calc(44px * var(--metro-scale)) !important; - width: calc(36px * var(--metro-scale)) !important; - height: calc(36px * var(--metro-scale)) !important; - border-radius: 50%; - background: rgba(234,149,22,.16); - box-shadow: inset 0 1px 0 rgba(255,255,255,.08); -} - -.metro-clean-scale::before{ - left: calc(18px * var(--metro-scale)) !important; -} - -.metro-clean-scale::after{ - right: calc(18px * var(--metro-scale)) !important; -} - -.metro-clean-pendulum{ - position: absolute; - top: calc(74px * var(--metro-scale)) !important; - left: 50%; - width: max(3px, calc(4px * var(--metro-scale))) !important; - height: calc(230px * var(--metro-scale)) !important; - transform-origin: 50% 0; - transform: translateX(-50%) rotate(-38deg); - background: linear-gradient(180deg, rgba(248,250,252,.76), rgba(234,149,22,.76)); - border-radius: 999px; - animation: metroSwing var(--metro-duration) ease-in-out infinite alternate; - animation-play-state: paused; -} - -.metro-clean-visual.running .metro-clean-pendulum{ - animation-play-state: running; -} - -.metro-clean-pendulum span{ - position: absolute; - bottom: calc(-17px * var(--metro-scale)) !important; - left: 50%; - transform: translateX(-50%); - width: calc(34px * var(--metro-scale)) !important; - height: calc(34px * var(--metro-scale)) !important; - border-radius: 50%; - background: linear-gradient(180deg, #FFB83D, #EA9516); - box-shadow: 0 10px 26px rgba(234,149,22,.28); -} - -.metro-clean-bpm{ - position: relative; - z-index: 2; - min-width: 0 !important; - padding: calc(10px * var(--metro-scale)) calc(16px * var(--metro-scale)) !important; - display: grid; - text-align: center; - line-height: 1; -} - -.metro-clean-bpm strong{ - font-size: clamp(52px, calc(112px * var(--metro-scale)), 112px) !important; - font-weight: 300; - color: #f8fafc; - letter-spacing: -.06em; -} - -.metro-clean-bpm span{ - margin-top: clamp(6px, calc(10px * var(--metro-scale)), 12px) !important; - font-size: clamp(13px, calc(16px * var(--metro-scale)), 16px) !important; - color: rgba(248,250,252,.62); - letter-spacing: .16em; -} - -.metro-clean-beats{ - display: flex; - justify-content: center; - align-items: center; - min-height: clamp(48px, calc(62px * var(--metro-scale)), 68px) !important; - padding: clamp(10px, calc(16px * var(--metro-scale)), 16px) clamp(8px, calc(12px * var(--metro-scale)), 12px) !important; - gap: clamp(8px, calc(12px * var(--metro-scale)), 14px) !important; - cursor: pointer; - position: relative; -} - -.beat-wrap{ - display: flex; - flex-direction: column; - align-items: center; - gap: clamp(4px, calc(6px * var(--metro-scale)), 6px) !important; -} - -.beat-number{ - font-size: clamp(10px, calc(12px * var(--metro-scale)), 12px) !important; - color: rgba(248,250,252,.52); -} - -.metro-clean-beats .beat{ - width: clamp(14px, calc(18px * var(--metro-scale)), 18px) !important; - height: clamp(14px, calc(18px * var(--metro-scale)), 18px) !important; -} - -.metro-clean-meta{ - width: 100% !important; - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: clamp(8px, calc(10px * var(--metro-scale)), 12px) !important; -} - -.metro-clean-meta button{ - min-height: clamp(50px, calc(62px * var(--metro-scale)), 64px) !important; - padding: clamp(8px, calc(10px * var(--metro-scale)), 10px) clamp(4px, calc(8px * var(--metro-scale)), 8px) !important; - font-size: clamp(11px, calc(12px * var(--metro-scale)), 12px) !important; -} - -.metro-clean-meta span{ - font-size: clamp(11px, calc(12px * var(--metro-scale)), 12px) !important; -} - -.metro-clean-meta strong{ - font-size: clamp(15px, calc(18px * var(--metro-scale)), 18px) !important; -} - -.metro-clean-actions{ - width: min(100%, 520px) !important; - margin: 0 auto 0 !important; - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; -} - -.metro-clean-actions .primary-btn{ - min-height: clamp(50px, calc(56px * var(--metro-scale)), 58px) !important; - font-size: clamp(17px, calc(18px * var(--metro-scale)), 18px) !important; -} - -.metro-clean-screen.metro-clean-landscape .metro-clean-main{ - gap: clamp(8px, 1.3vh, 14px) !important; -} - -.metro-clean-screen.metro-clean-landscape .metro-clean-meta button{ - min-height: clamp(48px, calc(56px * var(--metro-scale)), 58px) !important; -} From 36d097823927a7810f52f016076fdd924e4a471c Mon Sep 17 00:00:00 2001 From: awj Date: Sun, 21 Jun 2026 15:32:51 +0200 Subject: [PATCH 8/8] Add files via upload --- styles.css | 4692 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4692 insertions(+) create mode 100644 styles.css diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..bb8c88a --- /dev/null +++ b/styles.css @@ -0,0 +1,4692 @@ +:root { + --bg: #120904; + --bg-soft: #1a0f08; + --panel: #2b190f; + --panel-2: #3b2112; + --text: #fff7ed; + --muted: #c9a98e; + --accent: #EA9516; + --green: #22c55e; + --line: rgba(255, 247, 237, .12); + --header-height: clamp(90px, 13vh, 110px); + --shell-radius: 32px; +} + +* { box-sizing: border-box; } + +html, +body { + margin: 0; + min-height: 100%; +} + +body { + font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + color: var(--text); + background: + radial-gradient(circle at 50% -90px, rgba(234,149,22,.18), transparent 310px), + linear-gradient(180deg, var(--bg-soft), var(--bg)); + overflow-x: hidden; +} + +button { font: inherit; } + +/* SPLASH */ + +.splash { + position: fixed; + inset: 0; + z-index: 20; + display: grid; + place-items: center; + padding: max(24px, env(safe-area-inset-top)) 24px max(28px, env(safe-area-inset-bottom)); + background: + radial-gradient(circle at 50% 45%, rgba(234,149,22,.22), transparent 360px), + linear-gradient(180deg, #2b190f 0%, #1a0f08 48%, #120904 100%); + transition: opacity .38s ease, visibility .38s ease; +} + +.splash.is-hidden { + opacity: 0; + visibility: hidden; +} + +.splash-logo { + width: min(64vw, 420px); + height: auto; + display: block; + object-fit: contain; + filter: drop-shadow(0 18px 36px rgba(0,0,0,.34)); +} + +.splash-version { + position: fixed; + left: 0; + right: 0; + bottom: max(18px, env(safe-area-inset-bottom)); + text-align: center; + color: rgba(255,247,237,.42); + font-size: 11px; + letter-spacing: .14em; + font-weight: 700; +} + +/* APP SHELL */ + +.app { + min-height: 100svh; + padding: 14px 16px max(18px, env(safe-area-inset-bottom)); + background: + radial-gradient(circle at 50% -60px, rgba(234,149,22,.14), transparent 260px), + linear-gradient(180deg, #1a0f08 0%, #120904 100%); +} + +.app-header { + position: sticky; + top: 0; + z-index: 10; + width: 100%; + min-height: var(--header-height); + height: var(--header-height); + padding: calc(env(safe-area-inset-top) + 12px) 14px 12px 28px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + background: + radial-gradient(circle at 24% 12%, rgba(234,149,22,.16), transparent 220px), + linear-gradient(180deg, #321a0b 0%, #1d0f08 100%); + border: 1px solid var(--line); + border-bottom: 0; + border-radius: var(--shell-radius) var(--shell-radius) 0 0; + box-shadow: + inset 0 1px 0 rgba(255,255,255,.07), + 0 10px 26px rgba(0,0,0,.32); +} + +.header-logo { + width: min(48vw, 300px); + max-height: calc(var(--header-height) - 42px); + height: auto; + display: block; + object-fit: contain; + object-position: left center; + flex: 0 1 auto; +} + +.options-button { + flex: 0 0 34px; + width: 34px; + height: 44px; + border: 0; + border-radius: 16px; + background: transparent; + display: inline-flex; + align-items: center; + justify-content: center; + cursor: pointer; + color: rgba(255,247,237,.58); + font-size: 24px; + line-height: 1; + -webkit-tap-highlight-color: transparent; +} + +.options-button::before { + content: "⋮"; + display: block; + transform: translateY(-1px); +} + +.options-button span { display: none; } +.options-button:active { transform: scale(.96); } + +/* CONTENT */ + +.content { + padding: 0; + margin: 0; +} + +.start-panel { + width: 100%; + min-height: calc(100svh - var(--header-height) - 42px); + margin: 0; + border-left: 1px solid var(--line); + border-right: 1px solid var(--line); + border-bottom: 1px solid var(--line); + border-top: 0; + border-radius: 0 0 var(--shell-radius) var(--shell-radius); + background: + linear-gradient(180deg, rgba(59,33,18,.52), rgba(43,25,15,.32)); + box-shadow: + inset 0 1px 0 rgba(255,255,255,.04), + 0 18px 44px rgba(0,0,0,.22); +} + +.home-screen { + position: relative; + overflow: hidden; + display: grid; + gap: 18px; + padding: 24px 20px 28px; + background: + linear-gradient(90deg, rgba(18,9,4,.92), rgba(18,9,4,.55), rgba(18,9,4,.92)), + linear-gradient(180deg, rgba(59,33,18,.45), rgba(18,9,4,.56)); +} + +.home-card-bg { + position: absolute; + inset: 0; + pointer-events: none; + opacity: .33; + background-image: + linear-gradient(90deg, transparent 0 18%, rgba(255,247,237,.08) 18.2% 18.45%, transparent 18.65% 34%, rgba(255,247,237,.08) 34.2% 34.45%, transparent 34.65% 50%, rgba(255,247,237,.08) 50.2% 50.45%, transparent 50.65% 66%, rgba(255,247,237,.08) 66.2% 66.45%, transparent 66.65% 82%, rgba(255,247,237,.08) 82.2% 82.45%, transparent 82.65%), + linear-gradient(180deg, transparent 0 17%, rgba(234,149,22,.08) 17.1% 17.45%, transparent 17.55% 34%, rgba(234,149,22,.08) 34.1% 34.45%, transparent 34.55% 51%, rgba(234,149,22,.08) 51.1% 51.45%, transparent 51.55% 68%, rgba(234,149,22,.08) 68.1% 68.45%, transparent 68.55% 85%, rgba(234,149,22,.08) 85.1% 85.45%, transparent 85.55%); + background-size: 190px 190px; + transform: rotate(-.4deg) scale(1.08); + transform-origin: center; + mask-image: linear-gradient(90deg, transparent 0, black 16%, black 84%, transparent 100%); +} + +.tool-card { + position: relative; + isolation: isolate; + overflow: hidden; + width: 100%; + min-height: 104px; + padding: 22px 56px 20px 22px; + border: 1px solid rgba(255,247,237,.13); + border-radius: 28px; + background: + radial-gradient(circle at 18% 10%, rgba(234,149,22,.12), transparent 210px), + linear-gradient(90deg, rgba(78,42,21,.92) 0%, rgba(55,30,16,.88) 48%, rgba(30,16,8,.92) 100%); + color: var(--text); + text-align: left; + box-shadow: + inset 0 1px 0 rgba(255,255,255,.08), + inset 0 -1px 0 rgba(0,0,0,.28), + 0 16px 30px rgba(0,0,0,.24); + cursor: pointer; + -webkit-tap-highlight-color: transparent; +} + +.tool-card::before { + content: ""; + position: absolute; + inset: 0; + z-index: -2; + background: + linear-gradient(110deg, rgba(234,149,22,.17), transparent 34%), + radial-gradient(circle at 82% 45%, rgba(234,149,22,.13), transparent 160px); + opacity: .82; +} + +.tool-card::after { + content: ""; + position: absolute; + inset: 0; + z-index: -1; + background: linear-gradient(90deg, rgba(0,0,0,0) 0 43%, rgba(0,0,0,.18) 62%, rgba(0,0,0,.36) 100%); +} + +.tool-card:active { + transform: scale(.985); +} + +.tool-copy { + position: relative; + z-index: 2; + display: block; + max-width: 58%; +} + +.tool-title { + display: block; + font-size: clamp(24px, 5.4vw, 34px); + line-height: 1; + font-weight: 850; + letter-spacing: -.045em; + color: var(--text); + text-shadow: 0 2px 8px rgba(0,0,0,.34); +} + +.tool-desc { + display: block; + margin-top: 8px; + color: rgba(229,200,176,.92); + font-size: clamp(13px, 3.2vw, 18px); + line-height: 1.18; + font-weight: 500; + letter-spacing: -.025em; +} + +.tool-arrow { + position: absolute; + right: 22px; + top: 50%; + z-index: 4; + transform: translateY(-50%); + color: var(--accent); + font-size: 42px; + line-height: .8; + font-weight: 300; + text-shadow: 0 0 18px rgba(234,149,22,.28); +} + +.fret-art { + position: absolute; + right: 44px; + top: 50%; + z-index: 1; + width: 36%; + height: 92%; + transform: translateY(-50%) rotate(-7deg); + opacity: .52; + background-image: + linear-gradient(90deg, transparent 0 19%, rgba(255,247,237,.20) 19.3% 19.9%, transparent 20.2% 38%, rgba(255,247,237,.20) 38.3% 38.9%, transparent 39.2% 57%, rgba(255,247,237,.20) 57.3% 57.9%, transparent 58.2% 76%, rgba(255,247,237,.20) 76.3% 76.9%, transparent 77.2%), + linear-gradient(180deg, transparent 0 18%, rgba(255,247,237,.18) 18.4% 19.9%, transparent 20.3% 35%, rgba(255,247,237,.18) 35.4% 36.9%, transparent 37.3% 52%, rgba(255,247,237,.18) 52.4% 53.9%, transparent 54.3% 69%, rgba(255,247,237,.18) 69.4% 70.9%, transparent 71.3% 86%, rgba(255,247,237,.18) 86.4% 87.9%, transparent 88.3%); + filter: drop-shadow(0 14px 22px rgba(0,0,0,.18)); + mask-image: linear-gradient(90deg, transparent 0, black 18%, black 90%, transparent 100%); +} + +.dot { + position: absolute; + width: 20px; + height: 20px; + border-radius: 999px; + background: #c77a0a; + box-shadow: + inset 0 1px 0 rgba(255,255,255,.20), + 0 6px 14px rgba(0,0,0,.32), + 0 0 20px rgba(234,149,22,.18); +} + +.fret-art-transpose .dot-a { left: 30%; top: 34%; } +.fret-art-transpose .dot-b { left: 68%; top: 55%; } +.fret-art-chords .dot-a { left: 24%; top: 60%; } +.fret-art-chords .dot-b { left: 52%; top: 36%; } +.fret-art-chords .dot-c { left: 76%; top: 50%; } +.fret-art-metronome .dot-green { + left: 54%; + top: 50%; + background: var(--green); + box-shadow: + inset 0 1px 0 rgba(255,255,255,.20), + 0 6px 14px rgba(0,0,0,.32), + 0 0 20px rgba(34,197,94,.20); +} + +/* OPTIONS MENU */ + +.options-menu { + position: fixed; + top: calc(var(--header-height) + 4px); + right: 16px; + z-index: 30; + min-width: 220px; + padding: 8px; + border: 1px solid rgba(255,247,237,.12); + border-radius: 20px; + background: rgba(43,25,15,.98); + box-shadow: 0 22px 46px rgba(0,0,0,.44); +} + +.options-menu button { + width: 100%; + border: 0; + border-radius: 14px; + background: transparent; + color: var(--text); + padding: 12px 14px; + text-align: left; +} + +.options-menu button:active { + background: rgba(255,247,237,.08); +} + +/* SMALL SCREENS */ + +@media (max-width: 430px) { + :root { + --header-height: clamp(88px, 13vh, 106px); + --shell-radius: 30px; + } + + .app { + padding: 12px 14px max(16px, env(safe-area-inset-bottom)); + } + + .app-header { + padding-left: 24px; + padding-right: 14px; + } + + .header-logo { + width: min(54vw, 245px); + max-height: calc(var(--header-height) - 38px); + } + + .options-button { + width: 32px; + flex-basis: 32px; + font-size: 22px; + } + + .home-screen { + gap: 14px; + padding: 20px 16px 24px; + } + + .tool-card { + min-height: 100px; + padding: 20px 48px 18px 18px; + border-radius: 26px; + } + + .tool-copy { + max-width: 62%; + } + + .tool-title { + font-size: clamp(23px, 6.4vw, 31px); + } + + .tool-desc { + margin-top: 7px; + font-size: clamp(12px, 3.6vw, 16px); + } + + .fret-art { + right: 34px; + width: 34%; + height: 86%; + } + + .tool-arrow { + right: 18px; + font-size: 38px; + } + + .dot { + width: 18px; + height: 18px; + } +} + +/* FUNCTIONAL VIEWS */ +.logo-button{ + border:0; + padding:0; + margin:0; + background:transparent; + display:flex; + align-items:center; + min-width:0; + cursor:pointer; + -webkit-tap-highlight-color:transparent; +} +.logo-button:active{transform:scale(.985)} + +.view-screen{ + position:relative; + overflow:hidden; + padding:22px 18px 26px; + background: + linear-gradient(90deg, rgba(18,9,4,.92), rgba(18,9,4,.60), rgba(18,9,4,.92)), + linear-gradient(180deg, rgba(59,33,18,.45), rgba(18,9,4,.56)); +} + +.view-head{ + display:flex; + align-items:center; + justify-content:space-between; + gap:12px; + margin:0 0 18px; +} + +.view-title{ + margin:0; + font-size:clamp(24px,6.2vw,34px); + line-height:1; + letter-spacing:-.05em; + font-weight:850; +} + +.back-btn, +.small-action, +.ghost-btn, +.primary-btn, +.round-btn{ + border:1px solid rgba(255,247,237,.13); + color:var(--text); + background:rgba(59,33,18,.72); + border-radius:16px; + cursor:pointer; + -webkit-tap-highlight-color:transparent; +} +.back-btn{width:42px;height:42px;font-size:28px;line-height:1;display:grid;place-items:center;color:var(--accent)} +.small-action{padding:10px 12px;font-size:13px;font-weight:800;color:var(--muted)} +.ghost-btn{padding:12px 14px;color:var(--muted);font-weight:800} +.primary-btn{padding:13px 16px;background:linear-gradient(180deg,#EA9516,#b96c0c);color:#2a1204;font-weight:950;border-color:rgba(255,218,160,.28)} +.round-btn{width:48px;height:48px;border-radius:999px;font-size:24px;color:var(--accent);display:grid;place-items:center} +.back-btn:active,.small-action:active,.ghost-btn:active,.primary-btn:active,.round-btn:active{transform:scale(.97)} + +.view-card{ + position:relative; + border:1px solid rgba(255,247,237,.12); + border-radius:24px; + padding:16px; + background: + radial-gradient(circle at 15% 0%, rgba(234,149,22,.10), transparent 180px), + linear-gradient(180deg, rgba(59,33,18,.62), rgba(43,25,15,.42)); + box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 14px 30px rgba(0,0,0,.18); +} +.view-card + .view-card{margin-top:14px} + +.form-label,.group-label{ + display:block; + color:var(--accent); + font-size:11px; + font-weight:950; + letter-spacing:.15em; + text-transform:uppercase; + margin:0 0 10px; +} + +.song-input, +.search-input{ + width:100%; + border:1px solid rgba(255,247,237,.13); + border-radius:20px; + background:rgba(18,9,4,.58); + color:var(--text); + padding:14px; + outline:0; + box-shadow:inset 0 1px 0 rgba(255,255,255,.04); +} +.song-input{min-height:160px;resize:vertical;line-height:1.45;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:14px} +.search-input{height:48px;font-size:15px} +.song-input:focus,.search-input:focus{border-color:rgba(234,149,22,.48);box-shadow:0 0 0 3px rgba(234,149,22,.12)} + +.transpose-controls{ + display:grid; + grid-template-columns:48px 1fr 48px; + align-items:center; + gap:10px; + margin:14px 0; +} +.transpose-value{text-align:center;color:var(--muted);font-weight:850;line-height:1.15} +.transpose-value strong{display:block;color:var(--accent);font-size:28px;letter-spacing:-.05em} +.transpose-actions{display:flex;gap:10px;margin-top:12px;flex-wrap:wrap} +.output-box{ + min-height:145px; + padding:14px; + border-radius:20px; + background:rgba(18,9,4,.46); + border:1px solid rgba(255,247,237,.10); + overflow:auto; + font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; + font-size:14px; + line-height:1.55; + white-space:pre-wrap; +} +.output-line{min-height:1.55em} +.chord-token{ + display:inline-flex; + align-items:center; + justify-content:center; + margin:0 2px 2px; + padding:2px 8px 3px; + border:1px solid rgba(234,149,22,.40); + border-radius:999px; + background:rgba(234,149,22,.14); + color:var(--accent); + font:inherit; + font-weight:900; + cursor:pointer; + vertical-align:baseline; +} +.chord-token:active{transform:scale(.96)} + +.filter-row{display:flex;gap:8px;overflow:auto;padding:2px 2px 12px;margin:0 -2px 10px;scrollbar-width:none} +.filter-row::-webkit-scrollbar{display:none} +.filter-chip{flex:0 0 auto;border:1px solid rgba(255,247,237,.13);border-radius:999px;background:rgba(18,9,4,.48);color:var(--muted);font-weight:850;padding:9px 12px;cursor:pointer} +.filter-chip.active{background:rgba(234,149,22,.18);border-color:rgba(234,149,22,.44);color:var(--accent)} +.chord-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px} +.chord-card{ + border:1px solid rgba(255,247,237,.13); + border-radius:22px; + background:linear-gradient(180deg,rgba(71,40,21,.78),rgba(43,25,15,.56)); + padding:12px; + color:var(--text); + cursor:pointer; + box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 10px 22px rgba(0,0,0,.16); +} +.chord-card:active{transform:scale(.985)} +.chord-card-head{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;margin-bottom:8px} +.chord-name{font-size:24px;line-height:1;font-weight:950;color:var(--accent);letter-spacing:-.04em} +.chord-notes{font-size:11px;color:var(--muted);line-height:1.25;text-align:right} +.diagram{width:100%;height:auto;display:block;background:rgba(18,9,4,.30);border-radius:14px;padding:4px} +.diagram line{stroke:rgba(255,247,237,.42);stroke-width:2;stroke-linecap:round} +.diagram .fret{stroke:rgba(234,149,22,.40);stroke-width:3} +.diagram circle{fill:var(--accent);filter:drop-shadow(0 4px 8px rgba(0,0,0,.32))} +.diagram text{fill:rgba(255,247,237,.78);font-size:10px;font-weight:800} + +/* CHORD MODAL */ +.chord-modal,.app-modal{ + position:fixed;inset:0;z-index:80;display:none;align-items:center;justify-content:center;padding:22px;background:rgba(5,2,1,.72);backdrop-filter:blur(10px) +} +.chord-modal.visible,.app-modal.visible{display:flex} +.chord-modal-card,.app-modal-card{ + position:relative;width:min(92vw,390px);max-height:88svh;overflow:auto;border-radius:30px;border:1px solid rgba(255,247,237,.14);background:linear-gradient(180deg,#3b2112,#1a0f08);box-shadow:0 28px 70px rgba(0,0,0,.55);padding:18px +} +.modal-close,.app-modal-close{position:absolute;right:12px;top:10px;width:40px;height:40px;border:0;border-radius:999px;background:rgba(18,9,4,.58);color:var(--muted);font-size:26px;line-height:1;cursor:pointer;z-index:3} +.modal-chord-title{margin:10px 44px 6px 0;font-size:42px;line-height:1;font-weight:950;color:var(--accent);letter-spacing:-.06em} +.modal-chord-sub{margin:0 44px 16px 0;color:var(--muted);font-size:13px;line-height:1.35} +.modal-diagram{width:100%;max-width:320px;margin:0 auto;display:block;background:rgba(18,9,4,.38);border-radius:24px;padding:12px;border:1px solid rgba(255,247,237,.10)} +.modal-diagram line{stroke:rgba(255,247,237,.46);stroke-width:2.2;stroke-linecap:round} +.modal-diagram .fret{stroke:rgba(234,149,22,.48);stroke-width:4} +.modal-diagram circle{fill:var(--accent);filter:drop-shadow(0 6px 10px rgba(0,0,0,.36))} +.modal-diagram text{fill:rgba(255,247,237,.82);font-size:12px;font-weight:900} + +/* METRONOME */ +.metro-layout{display:grid;gap:14px} +.metro-display{display:grid;place-items:center;gap:14px;text-align:center} +.bpm-dial{ + width:190px;height:190px;border-radius:999px;display:grid;place-items:center;position:relative;touch-action:none;user-select:none;cursor:pointer; + background:radial-gradient(circle at 50% 38%,rgba(234,149,22,.18),transparent 52%),linear-gradient(180deg,rgba(59,33,18,.92),rgba(18,9,4,.68)); + border:1px solid rgba(255,247,237,.13);box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 18px 36px rgba(0,0,0,.28) +} +.bpm-dial::before{content:"";position:absolute;inset:12px;border-radius:999px;border:1px dashed rgba(234,149,22,.25)} +.bpm{position:relative;z-index:2;font-size:54px;font-weight:950;line-height:.9;color:var(--text);letter-spacing:-.06em} +.bpm small{display:block;margin-top:6px;font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)} +.meter-in-dial{position:absolute;bottom:40px;z-index:2;color:var(--accent);font-weight:900;font-size:13px} +.bpm-slider{width:100%;accent-color:var(--accent)} +.preset-grid,.meter-buttons,.accent-buttons{display:grid;grid-template-columns:repeat(3,1fr);gap:8px} +.preset-bpm,.meter-btn,.accent-btn{border:1px solid rgba(255,247,237,.13);border-radius:16px;background:rgba(18,9,4,.48);color:var(--muted);padding:10px 6px;font-weight:850;cursor:pointer} +.preset-bpm.active,.meter-btn.active,.accent-btn.active{background:rgba(234,149,22,.18);border-color:rgba(234,149,22,.44);color:var(--accent)} +.beats{position:relative;display:flex;justify-content:center;gap:10px;padding:14px;border-radius:22px;background:rgba(18,9,4,.42);border:1px solid rgba(255,247,237,.10)} +.beat{width:18px;height:18px;border-radius:999px;background:rgba(255,247,237,.18);box-shadow:inset 0 1px 0 rgba(255,255,255,.12);transition:transform .08s ease,background .08s ease,box-shadow .08s ease} +.beat.active{transform:scale(1.24);background:var(--accent);box-shadow:0 0 18px rgba(234,149,22,.45)} +.beat.accent{border:2px solid rgba(34,197,94,.85)} +.metro-controls{display:grid;grid-template-columns:1fr 1fr;gap:10px} +.metro-start{font-size:18px;padding:15px 16px;border-radius:20px} +.metro-reset{padding:15px 16px;border-radius:20px} + +@media (max-width:430px){ + .view-screen{padding:20px 14px 22px} + .view-card{padding:14px;border-radius:22px} + .chord-grid{grid-template-columns:1fr 1fr;gap:10px} + .chord-name{font-size:21px} + .diagram text{font-size:9px} + .bpm-dial{width:170px;height:170px} + .bpm{font-size:48px} + .preset-grid,.meter-buttons,.accent-buttons{gap:7px} + .preset-bpm,.meter-btn,.accent-btn{font-size:12px;padding:9px 4px} +} + +/* ===================================================== + IMPORT Z PLIKU WZORCOWEGO — FORMATOWANIE WIDOKÓW I MODALI + ===================================================== */ + +/* widoki narzędzi: bardziej zwarte, jednolita karta jak w pliku wzorcowym */ +.view-screen{ + position:relative; + overflow:hidden; + padding:16px 14px 20px; + background: + radial-gradient(circle at 50% 0%, rgba(234,149,22,.07), transparent 18rem), + linear-gradient(180deg, rgba(59,33,18,.44), rgba(18,9,4,.60)); +} + +.view-head{ + margin:0 0 14px; +} + +.view-title{ + font-size:clamp(22px,5.4vw,30px); + font-weight:850; + letter-spacing:-.045em; +} + +.view-card{ + padding:14px; + border-radius:14px; + background: + radial-gradient(circle at 16% 0%, rgba(234,149,22,.08), transparent 180px), + linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,.012)), + linear-gradient(145deg, rgba(43,25,15,.72), rgba(18,9,4,.72)); + border:1px solid rgba(255,255,255,.10); + box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 12px 28px rgba(0,0,0,.22); +} +.view-card + .view-card{margin-top:12px} + +.back-btn, +.small-action, +.ghost-btn, +.primary-btn, +.round-btn, +.filter-chip, +.preset-bpm, +.meter-btn, +.accent-btn{ + border-radius:12px!important; +} + +.form-label, +.group-label, +.transpose-heading{ + font-size:13px!important; + font-weight:650!important; + color:#f8fafc!important; + letter-spacing:.02em!important; + text-transform:none!important; +} + +.song-input, +.search-input, +.output-box{ + border-radius:12px!important; + background:#111827!important; + border:1px solid rgba(255,255,255,.08)!important; +} + +.transpose-controls{ + max-width:210px; + margin:14px auto 12px; +} +.transpose-value{ + border-radius:12px; + background:#111827; + border:1px solid rgba(255,255,255,.08); + padding:7px 8px; +} +.transpose-value span{ + display:block; + font-size:11px; + color:rgba(248,250,252,.62); +} +.transpose-value strong{ + font-size:28px!important; + font-weight:300!important; + color:#f8fafc!important; +} + +/* klikalne akordy w wyniku transpozycji */ +.chord-token{ + border-radius:10px; + background:linear-gradient(180deg,#FFB83D,#EA9516); + color:#111827; + border:0; + font-weight:850; + box-shadow:0 4px 10px rgba(234,149,22,.18), inset 0 1px 0 rgba(255,255,255,.22); +} + +/* Akordy — siatka i karta diagramu */ +.chord-grid{ + gap:10px; +} +.chord-card{ + border-radius:14px; + background: + radial-gradient(circle at 20% 0%, rgba(234,149,22,.10), transparent 120px), + linear-gradient(180deg,rgba(255,255,255,.035),rgba(255,255,255,.012)), + linear-gradient(145deg,rgba(43,25,15,.78),rgba(18,9,4,.68)); + border:1px solid rgba(255,255,255,.10); +} +.chord-card .chord-name, +#chordGrid .chord-name{ + display:inline-flex; + align-items:center; + justify-content:center; + min-width:56px; + padding:5px 12px; + border-radius:11px; + background:linear-gradient(180deg,#FFB83D,#EA9516); + color:#111827; + font-weight:850; + box-shadow:0 6px 16px rgba(234,149,22,.22), inset 0 1px 0 rgba(255,255,255,.25); +} +.diagram{ + background:rgba(17,24,39,.70); + border:1px solid rgba(255,255,255,.07); + border-radius:12px; +} + +/* Modal akordu — powiększona karta z legendą jak w pliku wzorcowym */ +.chord-modal, +.app-modal, +.metro-visual-modal{ + position:fixed; + inset:0; + z-index:90; + display:none; + align-items:center; + justify-content:center; + padding:14px; + background:rgba(0,0,0,.68); + backdrop-filter:blur(10px); +} +.chord-modal.visible, +.app-modal.visible, +.metro-visual-modal.visible{display:flex} + +.chord-modal-card{ + position:relative; + width:min(390px,94vw); + min-height:min(760px,92vh); + max-height:92vh; + overflow:auto; + border-radius:28px; + padding:58px 24px 24px; + background: + radial-gradient(circle at 50% 0%, rgba(234,149,22,.08), transparent 19rem), + linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.018)), + linear-gradient(145deg,#111a22,#070d13); + border:1px solid rgba(255,255,255,.12); + box-shadow:0 28px 80px rgba(0,0,0,.62); + color:#f8fafc; +} +.modal-close, +.app-modal-close, +.metro-visual-close{ + position:absolute; + top:16px; + right:16px; + width:38px; + height:38px; + padding:0; + border:0; + border-radius:50%; + background:transparent; + color:#f8fafc; + font-size:34px; + font-weight:300; + line-height:1; + cursor:pointer; + z-index:3; +} +.modal-chord-title{ + display:inline-flex; + align-items:center; + justify-content:center; + min-width:132px; + min-height:88px; + margin:0 auto 14px; + padding:10px 18px; + border-radius:16px; + background:linear-gradient(180deg,#FFB83D,#EA9516); + color:#111827; + font-size:58px; + font-weight:850; + line-height:1; + letter-spacing:-.06em; + box-shadow:0 8px 22px rgba(234,149,22,.28), inset 0 1px 0 rgba(255,255,255,.25); +} +.modal-chord-sub{ + margin:0 0 18px; + color:rgba(248,250,252,.76); + font-size:15px; + text-align:center; +} +.modal-chord-sub::before{content:"Dźwięki: ";color:rgba(248,250,252,.64)} +.modal-diagram{ + width:min(300px,82vw); + max-width:300px; + margin:8px auto 20px; + display:block; + background:transparent; + border:0; + border-radius:0; + padding:0; + filter:drop-shadow(0 14px 30px rgba(0,0,0,.35)); +} +.modal-diagram line{stroke:rgba(248,250,252,.72)!important;stroke-width:2.2;stroke-linecap:round} +.modal-diagram .fret{stroke:rgba(248,250,252,.72)!important;stroke-width:3.2} +.modal-diagram circle{fill:#EA9516!important;filter:drop-shadow(0 6px 10px rgba(0,0,0,.36))} +.modal-diagram text{fill:#f8fafc!important;font-weight:700!important} +#chord-modal-content::after{ + content:"x – nie graj\A O – graj otwartą strunę\A 1, 2, 3, 4 – nr progu"; + display:block; + white-space:pre-line; + text-align:left; + margin:8px auto 0; + width:min(300px,82vw); + color:rgba(248,250,252,.78); + font-size:14px; + line-height:1.65; +} + +.app-modal-card{ + position:relative; + width:min(360px,94vw); + border-radius:24px; + padding:22px 18px 18px; + background: + radial-gradient(circle at 50% 0%, rgba(234,149,22,.10), transparent 18rem), + linear-gradient(145deg,#151f29,#081018); + border:1px solid rgba(255,255,255,.14); + box-shadow:0 34px 90px rgba(0,0,0,.56); + color:#f8fafc; +} +.app-modal-card h2{margin:0 42px 14px 0;font-size:22px;letter-spacing:-.03em} +.app-modal-card p{color:rgba(248,250,252,.78);line-height:1.45;margin:0 0 14px} + +/* Metronom — czytelne sekcje i modal wizualny */ +.metro-layout{display:grid;gap:12px} +.metro-display{padding:16px!important} +.bpm-dial{ + width:190px; + height:190px; + border-radius:50%; + display:grid; + place-items:center; + position:relative; + background: + radial-gradient(circle at 50% 36%, rgba(234,149,22,.16), transparent 48%), + linear-gradient(145deg,#17212b,#081018); + border:1px solid rgba(255,255,255,.13); + box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 20px 44px rgba(0,0,0,.32); +} +.bpm{display:grid;text-align:center;line-height:1} +.bpm span{font-size:52px;font-weight:300;color:#f8fafc;letter-spacing:-.06em} +.bpm small{font-size:12px;color:rgba(248,250,252,.62);letter-spacing:.16em;margin-top:6px} +.meter-in-dial{position:absolute;bottom:32px;color:rgba(248,250,252,.62);font-size:13px} +.bpm-slider{width:100%;accent-color:var(--accent)} +.preset-grid,.meter-buttons,.accent-buttons{display:grid;grid-template-columns:repeat(3,1fr);gap:8px} +.preset-bpm,.meter-btn,.accent-btn{ + min-height:42px; + border:1px solid rgba(255,255,255,.10); + background:rgba(17,24,39,.66); + color:#f8fafc; + font-weight:700; +} +.preset-bpm.active,.meter-btn.active,.accent-btn.active{ + background:rgba(234,149,22,.18); + border-color:rgba(234,149,22,.48); + color:#EA9516; +} +.beats{ + display:flex; + justify-content:center; + align-items:center; + gap:12px; + min-height:56px; + cursor:pointer; + position:relative; +} +.beats::after{ + content:"dotknij, aby powiększyć"; + position:absolute; + top:-24px; + left:50%; + transform:translateX(-50%); + white-space:nowrap; + color:rgba(248,250,252,.52); + font-size:11px; +} +.beat{ + width:18px; + height:18px; + border-radius:50%; + background:rgba(248,250,252,.18); + border:1px solid rgba(255,255,255,.10); +} +.beat.accent{box-shadow:0 0 0 2px rgba(234,149,22,.16)} +.beat.active{background:#EA9516;box-shadow:0 0 22px rgba(234,149,22,.45)} +.beat.active.accent{background:#22c55e;box-shadow:0 0 22px rgba(34,197,94,.42)} + +.metro-visual-card{ + position:relative; + width:min(380px,94vw); + border-radius:28px; + padding:54px 22px 22px; + background: + radial-gradient(circle at 50% 0%, rgba(234,149,22,.10), transparent 18rem), + linear-gradient(145deg,#151f29,#081018); + border:1px solid rgba(255,255,255,.14); + box-shadow:0 34px 90px rgba(0,0,0,.56); + color:#f8fafc; + text-align:center; +} +.metro-visual-card h2{margin:0 44px 14px 0;font-size:24px;letter-spacing:-.04em;text-align:left} +.metro-visual{ + width:min(260px,74vw); + height:300px; + margin:0 auto 14px; + position:relative; + display:grid; + place-items:center; +} +.metro-arc{ + position:absolute; + inset:28px 28px 56px; + border-radius:160px 160px 28px 28px; + border:1px solid rgba(255,255,255,.12); + background:radial-gradient(circle at 50% 0%,rgba(234,149,22,.12),transparent 66%); +} +.metro-pendulum{ + position:absolute; + bottom:62px; + left:50%; + width:4px; + height:190px; + transform-origin:50% 100%; + transform:translateX(-50%) rotate(-24deg); + background:linear-gradient(180deg,rgba(248,250,252,.76),rgba(234,149,22,.76)); + border-radius:999px; + animation:metroSwing 1s ease-in-out infinite alternate; + animation-play-state:paused; +} +.metro-visual-modal.running .metro-pendulum{animation-play-state:running} +.metro-pendulum span{ + position:absolute; + top:40px; + left:50%; + transform:translateX(-50%); + width:34px; + height:34px; + border-radius:50%; + background:linear-gradient(180deg,#FFB83D,#EA9516); + box-shadow:0 10px 26px rgba(234,149,22,.28); +} +.metro-weight{ + position:absolute; + bottom:52px; + left:50%; + transform:translateX(-50%); + width:94px; + height:38px; + border-radius:18px; + background:rgba(255,255,255,.08); + border:1px solid rgba(255,255,255,.12); +} +.metro-visual-center{position:absolute;display:grid;place-items:center;gap:2px} +.metro-visual-center strong{font-size:48px;font-weight:300;letter-spacing:-.06em} +.metro-visual-center span{font-size:11px;color:rgba(248,250,252,.62);letter-spacing:.16em} +.metro-visual-center em{font-style:normal;color:rgba(248,250,252,.62);font-size:13px} +.metro-big-beats{display:flex;justify-content:center;gap:10px;margin:8px 0 14px} +.metro-modal-controls{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:12px} +@keyframes metroSwing{ + from{transform:translateX(-50%) rotate(-24deg)} + to{transform:translateX(-50%) rotate(24deg)} +} + +@media (max-width:430px){ + .view-screen{padding:14px 12px 18px} + .view-card{padding:12px;border-radius:12px} + .modal-chord-title{font-size:48px;min-height:78px;min-width:118px} + .chord-modal-card{width:calc(100vw - 24px);min-height:calc(100svh - 42px);border-radius:24px;padding:54px 20px 22px} + .modal-diagram,#chord-modal-content::after{width:min(286px,84vw)} + .bpm-dial{width:176px;height:176px} + .bpm span{font-size:46px} + .preset-grid,.meter-buttons,.accent-buttons{grid-template-columns:repeat(3,1fr)} +} + +/* ===================================================== + EasyTune v2.5 — CZYSTY METRONOM + ===================================================== */ +.metro-clean-screen{ + padding:16px 14px 20px!important; +} +.metro-clean-screen .view-head{ + margin-bottom:14px!important; +} +.metro-clean-main{ + display:grid; + gap:14px; +} +.metro-clean-visual{ + --metro-duration:.6s; + position:relative; + width:100%; + min-height:420px; + border-radius:24px; + overflow:hidden; + display:grid; + place-items:center; + background: + radial-gradient(circle at 50% 46%, rgba(234,149,22,.14), transparent 54%), + linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.018)), + linear-gradient(145deg,#111a22,#070d13); + border:1px solid rgba(234,149,22,.24); + box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35); +} +.metro-clean-visual::before{ + content:""; + position:absolute; + left:50%; + top:50%; + width:min(300px,68vw); + height:min(300px,68vw); + transform:translate(-50%,-50%); + border-radius:50%; + border:2px solid rgba(234,149,22,.22); + background:radial-gradient(circle, rgba(234,149,22,.10), transparent 62%); +} +.metro-clean-visual.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit{ + border-color:rgba(234,149,22,.82); + box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 0 0 3px rgba(234,149,22,.16),0 0 64px rgba(234,149,22,.24),0 24px 60px rgba(0,0,0,.40); +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .22s ease-out 1; + border-color:rgba(234,149,22,.86); +} +@keyframes metroBeatFlash{ + 0%{transform:translate(-50%,-50%) scale(.92);opacity:.56} + 50%{transform:translate(-50%,-50%) scale(1.10);opacity:1} + 100%{transform:translate(-50%,-50%) scale(1);opacity:.72} +} +@keyframes metroAccentFlash{ + 0%{transform:translate(-50%,-50%) scale(.90);opacity:.68} + 50%{transform:translate(-50%,-50%) scale(1.16);opacity:1;box-shadow:0 0 110px rgba(234,149,22,.55)} + 100%{transform:translate(-50%,-50%) scale(1);opacity:.78} +} +.metro-clean-scale{ + position:absolute; + left:50%; + top:56px; + width:190px; + height:78px; + transform:translateX(-50%); + border:2px solid rgba(255,214,160,.24); + border-bottom:0; + border-radius:190px 190px 0 0; +} +.metro-clean-scale::before, +.metro-clean-scale::after{ + content:""; + position:absolute; + top:44px; + width:36px; + height:2px; + background:rgba(255,214,160,.30); +} +.metro-clean-scale::before{left:18px;transform:rotate(32deg)} +.metro-clean-scale::after{right:18px;transform:rotate(-32deg)} +.metro-clean-pendulum{ + position:absolute; + left:50%; + top:74px; + z-index:2; + width:4px; + height:230px; + transform-origin:50% 100%; + background:linear-gradient(180deg,#ffd68a,#EA9516); + border-radius:999px; + box-shadow:0 0 22px rgba(234,149,22,.38); + animation:metroCleanSwing var(--metro-duration) ease-in-out infinite alternate paused; +} +.metro-clean-visual.running .metro-clean-pendulum{animation-play-state:running} +.metro-clean-pendulum span{ + position:absolute; + left:50%; + bottom:-17px; + width:34px; + height:34px; + transform:translateX(-50%); + border-radius:50%; + background:#EA9516; + box-shadow:0 0 26px rgba(234,149,22,.70); +} +@keyframes metroCleanSwing{ + from{transform:translateX(-50%) rotate(-38deg)} + to{transform:translateX(-50%) rotate(38deg)} +} +.metro-clean-bpm{ + position:relative; + z-index:3; + border:0!important; + background:transparent!important; + box-shadow:none!important; + color:#f8fafc!important; + display:grid!important; + place-items:center!important; + padding:10px 16px!important; + min-width:150px; + border-radius:18px!important; +} +.metro-clean-bpm strong{ + font-size:clamp(72px,18vw,112px); + line-height:.9; + font-weight:250; + letter-spacing:-.08em; +} +.metro-clean-bpm span{ + margin-top:10px; + font-size:16px; + font-weight:300; + letter-spacing:.12em; + color:rgba(248,250,252,.72); +} +.metro-clean-beats{ + display:flex; + justify-content:center; + align-items:center; + gap:12px; + min-height:62px; + padding:16px 12px; + border-radius:16px; + background:rgba(4,9,14,.42); + border:1px solid rgba(255,255,255,.10); +} +.beat-wrap{display:grid;justify-items:center;gap:6px} +.beat-number{font-size:12px;font-weight:600;color:rgba(248,250,252,.54)} +.beat-number.active{color:#ffd68a} +.metro-clean-beats .beat{ + width:18px;height:18px;border-radius:50%;background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.10); +} +.metro-clean-beats .beat.active{background:#EA9516;box-shadow:0 0 18px rgba(234,149,22,.65);transform:scale(1.16)} +.metro-clean-beats .beat.accent{border-color:#ffd68a;box-shadow:0 0 0 2px rgba(234,149,22,.14)} +.metro-clean-meta{ + display:grid; + grid-template-columns:repeat(3,1fr); + gap:10px; + margin:0; +} +.metro-clean-meta button{ + min-height:62px!important; + border-radius:14px!important; + padding:10px 8px!important; + display:grid!important; + gap:6px!important; + text-align:center!important; + background:rgba(4,9,14,.42)!important; + border:1px solid rgba(255,255,255,.10)!important; +} +.metro-clean-meta span{font-size:12px;font-weight:300;color:rgba(248,250,252,.62)} +.metro-clean-meta strong{font-size:18px;font-weight:350;color:#ffd68a;line-height:1} +.metro-clean-actions{display:grid;grid-template-columns:1fr 1.4fr;gap:10px} +.metro-clean-actions .primary-btn,.metro-clean-actions .ghost-btn{min-height:56px!important;border-radius:14px!important;font-size:18px!important} +.metro-settings-modal{ + position:fixed; + inset:0; + z-index:100; + display:none; + align-items:center; + justify-content:center; + padding:14px; + background:rgba(0,0,0,.68); + backdrop-filter:blur(10px); +} +.metro-settings-modal.visible{display:flex} +.metro-settings-card{ + position:relative; + width:min(410px,94vw); + max-height:calc(100dvh - 28px); + overflow:auto; + border-radius:22px; + padding:24px 18px 18px; + background:radial-gradient(circle at 50% 0%, rgba(234,149,22,.10), transparent 18rem),linear-gradient(145deg,#121b25,#050a10); + border:1px solid rgba(255,255,255,.14); + box-shadow:0 34px 90px rgba(0,0,0,.56); +} +.metro-settings-card h2{margin:0 44px 18px 0;font-size:22px;font-weight:300;color:#f8fafc} +.metro-settings-close{ + position:absolute!important;right:12px!important;top:12px!important;width:36px!important;height:36px!important;min-width:36px!important;padding:0!important;border:0!important;border-radius:50%!important;background:rgba(255,255,255,.045)!important;color:#f8fafc!important;font-size:28px!important;line-height:1!important; +} +.metro-bpm-stepper{display:grid;grid-template-columns:56px 1fr 56px;align-items:center;gap:8px;margin:0 0 14px} +.metro-bpm-stepper button{height:54px!important;border-radius:14px!important;font-size:28px!important;color:#EA9516!important} +.metro-bpm-stepper strong{text-align:center;font-size:56px;font-weight:250;line-height:1;color:#f8fafc} +.metro-settings-card .bpm-slider{width:100%;accent-color:#EA9516;margin:6px 0 16px} +.metro-settings-card .preset-grid,.metro-settings-card .meter-buttons,.metro-settings-card .accent-buttons{display:grid;grid-template-columns:repeat(3,1fr);gap:8px} +.metro-settings-card .preset-bpm,.metro-settings-card .meter-btn,.metro-settings-card .accent-btn{min-height:46px!important;border-radius:12px!important;font-size:15px!important;font-weight:400!important} +.metro-settings-card .preset-bpm.active,.metro-settings-card .meter-btn.active,.metro-settings-card .accent-btn.active{background:linear-gradient(180deg,#FFB83D,#EA9516)!important;color:#111827!important;border-color:rgba(255,210,120,.70)!important} +@media(max-width:430px){ + .metro-clean-screen{padding:14px 12px 18px!important} + .metro-clean-visual{min-height:390px;border-radius:22px} + .metro-clean-scale{top:52px;width:168px;height:70px} + .metro-clean-pendulum{top:68px;height:205px} + .metro-clean-meta{gap:8px} + .metro-clean-meta button{min-height:58px!important;padding:9px 4px!important} + .metro-clean-meta strong{font-size:16px} + .metro-clean-actions{grid-template-columns:1fr 1fr} +} + + +/* ===================================================== + EasyTune v2.5.1 — Metronom bez dodatkowego półkola/skali + ===================================================== */ + +/* Usuwa dodatkowy rysunek półkola ze wskazówkami nad wahadłem */ +.metro-clean-scale, +.metro-arc { + display: none !important; +} + +/* Czyści ewentualne pseudo-elementy skali */ +.metro-clean-scale::before, +.metro-clean-scale::after, +.metro-arc::before, +.metro-arc::after { + content: none !important; + display: none !important; +} + +/* Metronom zostaje prostszy: tło + wahadło + BPM */ +.metro-clean-visual { + background: + radial-gradient(circle at center, rgba(234,149,22,.10), transparent 58%), + linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,.018)), + #081018 !important; +} + + +/* v2.5.2 metronome cleanup */ +#tapTempoBtn, .tap-tempo, .tap-tempo-wrap { display:none !important; } + +.metro-visual-card{ + display:flex; + flex-direction:column; +} +.metro-big-beats{ + order:2 !important; + margin:0 0 16px 0 !important; +} +.metro-pendulum, +.metro-visual, +.metro-clean-visual{ + order:3 !important; +} + + +/* v2.5.3 */ +#tapTempoBtnMain,.tap-tempo-main,.metro-main-tap{display:none!important;} + +/* Start/Stop wider */ +.metro-start-stop, +#startStopBtn, +.start-stop-btn{ + width:100%!important; + min-width:220px!important; +} + +/* BPM modal Tap Tempo centered and wider */ +#tapTempoBtn, +.tap-tempo-btn{ + display:block!important; + margin:12px auto!important; + min-width:220px!important; + width:70%!important; +} + +/* tooltip/help */ +.tap-tempo-help{ + text-align:center; + font-size:.9rem; + opacity:.8; + margin-top:6px; +} + + +/* v2.5.6 metronome cleanup */ +.metro-main-tap, +#tapTempoBtnMain{ + display:none !important; +} + +#startStopBtn, +.start-stop-btn, +.metro-start-stop{ + width:100% !important; + max-width:none !important; +} + +.tap-help-modal{ + position:fixed; + inset:0; + display:none; + align-items:center; + justify-content:center; + background:rgba(0,0,0,.65); + z-index:9999; +} +.tap-help-modal.open{display:flex;} +.tap-help-card{ + max-width:320px; + padding:20px; + border-radius:18px; + background:#2b190f; + color:#fff; + text-align:center; +} +.tap-help-trigger{ + cursor:pointer; + display:inline-block; + margin-top:10px; +} + + +/* ===================================================== + EasyTune v2.5.7 — poprawiony Tap Tempo i modal informacji + ===================================================== */ + +/* Tap Tempo usunięte z głównego ekranu metronomu */ +#tapTempo { + display: none !important; +} + +/* Duży metronom/BPM nie udaje już wejścia do ustawień tempa */ +#metroCleanBpmButton { + cursor: default !important; +} + +/* Start/Stop po usunięciu Tap Tempo zajmuje całą szerokość */ +.metro-clean-actions { + display: grid !important; + grid-template-columns: 1fr !important; + gap: 10px !important; +} + +.metro-clean-actions #startMetro, +.metro-clean-actions .metro-start { + width: 100% !important; + min-height: 58px !important; +} + +/* Tap Tempo tylko w modalu tempa */ +.metro-tap-row { + display: flex !important; + align-items: center !important; + justify-content: center !important; + gap: 10px !important; + width: 100% !important; + margin: 14px auto 0 !important; +} + +#metroTapInModal.metro-tap-modal-btn { + width: min(260px, 72vw) !important; + min-width: 220px !important; + min-height: 46px !important; + margin: 0 !important; + display: inline-flex !important; + align-items: center !important; + justify-content: center !important; +} + +.metro-tap-info-btn { + width: 34px !important; + height: 34px !important; + min-width: 34px !important; + padding: 0 !important; + border-radius: 999px !important; + display: inline-flex !important; + align-items: center !important; + justify-content: center !important; + font-weight: 850 !important; + color: var(--accent, #EA9516) !important; + background: rgba(255,255,255,.06) !important; + border: 1px solid rgba(234,149,22,.45) !important; +} + +/* Modal pomocy Tap Tempo */ +.tap-help-modal { + position: fixed !important; + inset: 0 !important; + z-index: 10000 !important; + display: none !important; + align-items: center !important; + justify-content: center !important; + padding: 18px !important; + background: rgba(0,0,0,.68) !important; + backdrop-filter: blur(10px) !important; +} + +.tap-help-modal.open { + display: flex !important; +} + +.tap-help-card { + position: relative !important; + width: min(360px, 92vw) !important; + padding: 24px 20px 20px !important; + border-radius: 22px !important; + background: + radial-gradient(circle at 50% 0%, rgba(234,149,22,.12), transparent 18rem), + linear-gradient(145deg,#151f29,#081018) !important; + color: #f8fafc !important; + border: 1px solid rgba(255,255,255,.14) !important; + box-shadow: 0 34px 90px rgba(0,0,0,.56) !important; +} + +.tap-help-card h2 { + margin: 0 42px 12px 0 !important; + font-size: 22px !important; + line-height: 1.1 !important; +} + +.tap-help-card p { + margin: 0 !important; + color: rgba(248,250,252,.82) !important; + font-size: 15px !important; + line-height: 1.45 !important; +} + +.tap-help-close { + position: absolute !important; + top: 10px !important; + right: 10px !important; + width: 36px !important; + height: 36px !important; + padding: 0 !important; + border-radius: 999px !important; + background: rgba(255,255,255,.06) !important; + color: #f8fafc !important; + font-size: 26px !important; + line-height: 1 !important; +} + + +/* === EasyTune formatting polish: hierarchy, spacing, active states, radius consistency, centered chords === */ +.logo-button{ + flex-direction:column !important; + align-items:flex-start !important; + justify-content:center !important; + gap:5px !important; +} +.header-logo{ + width:min(56vw,330px) !important; + max-height:calc(var(--header-height) - 52px) !important; +} +.header-subtitle{ + display:block; + color:rgba(255,247,237,.68); + font-size:clamp(11px,2.8vw,13px); + line-height:1; + font-weight:750; + letter-spacing:.12em; + text-transform:uppercase; + white-space:nowrap; +} +.view-head{ + margin-bottom:18px !important; +} +.view-title{ + font-size:clamp(34px,8.2vw,42px) !important; + line-height:.96 !important; + letter-spacing:-.06em !important; +} +.view-card{ + border-radius:24px !important; + padding:18px !important; + margin:16px 0 24px !important; +} +.view-card + .view-card{ + margin-top:24px !important; +} +.form-label,.group-label{ + margin-bottom:12px !important; +} +.song-input,.search-input,.output-box{ + border-radius:18px !important; +} +.back-btn,.small-action,.ghost-btn,.primary-btn,.filter-chip,.preset-bpm,.meter-btn,.accent-btn,.visual-mode-btn{ + border-radius:18px !important; +} +.filter-chip.active,.preset-bpm.active,.meter-btn.active,.accent-btn.active,.visual-mode-btn.active{ + position:relative; + transform:translateY(-1px); + background:linear-gradient(180deg,rgba(255,184,61,.26),rgba(234,149,22,.18)) !important; + border-color:rgba(255,184,61,.68) !important; + color:#ffd68a !important; + box-shadow:inset 0 2px 0 rgba(255,216,138,.42),0 8px 18px rgba(0,0,0,.18) !important; +} +.tool-card{ + border-radius:24px !important; +} +.chord-card{ + border-radius:24px !important; + padding:14px 12px 16px !important; +} +.chord-card-head{ + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:8px !important; + margin:0 0 12px !important; + text-align:center !important; +} +.chord-card .chord-name,#chordGrid .chord-name{ + min-width:64px !important; + margin:0 auto !important; + font-size:24px !important; +} +.chord-notes{ + display:block !important; + width:100% !important; + color:rgba(255,247,237,.74) !important; + font-size:12px !important; + line-height:1.25 !important; + text-align:center !important; + letter-spacing:.03em !important; +} +.modal-chord-title{ + display:flex !important; + margin-left:auto !important; + margin-right:auto !important; +} +.modal-chord-sub{ + text-align:center !important; + font-size:16px !important; + letter-spacing:.03em !important; +} +@media (max-width:430px){ + .header-logo{width:min(58vw,260px) !important;} + .header-subtitle{font-size:10px;letter-spacing:.10em;} + .view-card{padding:16px !important;margin:16px 0 22px !important;} + .chord-card .chord-name,#chordGrid .chord-name{font-size:22px !important;} + .chord-notes{font-size:11px !important;} +} + +/* === EasyTune correction 2026-06-18: cleaner header, lighter text, card title spacing === */ +.header-subtitle{ + display:none !important; +} +.logo-button{ + height:var(--header-height) !important; + min-height:var(--header-height) !important; + justify-content:center !important; + align-items:flex-start !important; +} +.header-logo{ + width:min(64vw,380px) !important; + max-height:calc(var(--header-height) - 30px) !important; + object-fit:contain !important; +} +body, +button, +input, +textarea, +select, +strong, +b, +h1, +h2, +h3, +.tool-title, +.tool-desc, +.view-title, +.form-label, +.group-label, +.chord-name, +.chord-notes, +.filter-chip, +.small-action, +.primary-btn, +.ghost-btn, +.back-btn, +.round-btn, +.tap-btn, +.metro-clean-bpm strong, +.metro-clean-bpm span, +.metro-clean-meta span, +.metro-clean-meta strong, +.metro-bpm-stepper strong, +.metro-settings-card h2, +.tap-help-card h2, +.app-modal-card h2, +.modal-chord-title, +.modal-chord-sub{ + font-weight:400 !important; +} +.view-card{ + padding:20px 22px 20px !important; +} +.view-card > .form-label, +.view-card > .group-label{ + display:block !important; + padding-left:10px !important; + margin-bottom:14px !important; +} +.metro-settings-card h2, +.tap-help-card h2, +.app-modal-card h2{ + padding-left:10px !important; +} +.chord-card-head{ + padding-left:0 !important; + padding-right:0 !important; +} +.chord-card .chord-name, +#chordGrid .chord-name, +.chord-notes{ + text-align:center !important; + font-weight:400 !important; +} +@media (max-width:430px){ + .header-logo{ + width:min(66vw,300px) !important; + max-height:calc(var(--header-height) - 28px) !important; + } + .view-card{ + padding:18px 20px 18px !important; + } + .view-card > .form-label, + .view-card > .group-label{ + padding-left:8px !important; + } +} + + +/* === EasyTune verified correction: logo restored, card-title weight 500 === */ +.logo-button{ + height:var(--header-height) !important; + min-height:var(--header-height) !important; + justify-content:center !important; + align-items:flex-start !important; +} +.header-logo{ + width:min(48vw,300px) !important; + max-height:calc(var(--header-height) - 42px) !important; + height:auto !important; + object-fit:contain !important; +} +.tool-title, +.view-card > .form-label, +.view-card > .group-label, +.metro-settings-card h2, +.tap-help-card h2, +.app-modal-card h2{ + font-weight:500 !important; +} +@media (max-width:430px){ + .header-logo{ + width:min(54vw,245px) !important; + max-height:calc(var(--header-height) - 38px) !important; + } +} + +/* === EasyTune final fixes: PWA install visibility, chord diagrams, chord filters, metronome accents === */ +html.pwa-installed [data-pwa-install]{ + display:none !important; +} +#chordSearch.search-input{ + margin-bottom:18px !important; +} +#filterRow.filter-row{ + gap:6px !important; + padding:6px 2px 16px !important; + margin:2px -2px 16px !important; +} +#filterRow .filter-chip{ + font-size:11px !important; + font-weight:400 !important; + line-height:1 !important; + padding:7px 9px !important; + border-radius:999px !important; + letter-spacing:.01em !important; +} +.chord-card{ + text-align:center !important; +} +.chord-card-head{ + align-items:center !important; + justify-content:center !important; + text-align:center !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + display:inline-flex !important; + align-items:center !important; + justify-content:center !important; + min-width:58px !important; + padding:7px 12px !important; + border:1px solid rgba(255,247,237,.18) !important; + background:rgba(255,247,237,.035) !important; + box-shadow:none !important; +} +.chord-notes{ + text-align:center !important; + margin-top:0 !important; +} +.diagram, +.modal-diagram{ + display:block !important; + margin-left:auto !important; + margin-right:auto !important; + height:auto !important; +} +.diagram{width:min(170px,100%) !important;} +.modal-diagram{width:min(280px,86vw) !important;} +.diagram line, +.modal-diagram line{ + stroke:rgba(255,247,237,.48); + stroke-width:1.15; + stroke-linecap:round; +} +.diagram .fret, +.modal-diagram .fret{ + stroke:rgba(255,247,237,.62); +} +.diagram .nut, +.modal-diagram .nut{ + stroke:rgba(255,247,237,.88); + stroke-width:3.6; +} +.diagram text, +.modal-diagram text{ + fill:rgba(255,247,237,.70); + font-size:12px; + font-weight:400; + text-anchor:middle; + dominant-baseline:middle; +} +.modal-diagram text{font-size:14px;} +.diagram .fret-number, +.modal-diagram .fret-number{ + fill:rgba(255,247,237,.62); + font-size:11px; +} +.modal-diagram .fret-number{font-size:13px;} +.diagram circle, +.modal-diagram circle{ + fill:#EA9516 !important; +} + +.diagram .string-state, +.modal-diagram .string-state{ + font-size:22px !important; + font-weight:800 !important; + line-height:1 !important; + text-anchor:middle !important; + dominant-baseline:middle !important; +} +.diagram .state-open, +.modal-diagram .state-open{ + fill:#55d36a !important; + color:#55d36a !important; +} +.diagram .state-muted, +.modal-diagram .state-muted{ + fill:#ff6b6b !important; + color:#ff6b6b !important; +} +.diagram .state-open{font-size:20px !important;} +.diagram .state-muted{font-size:20px !important;} +.modal-diagram .state-open{font-size:24px !important;} +.modal-diagram .state-muted{font-size:24px !important;} +.metro-clean-beats .beat{ + border:2px solid transparent !important; +} +.metro-clean-beats .beat.accent{ + border-color:rgba(255,214,138,.86) !important; + box-shadow:0 0 0 2px rgba(234,149,22,.13) !important; +} +.metro-clean-beats .beat.active{ + background:#EA9516 !important; + box-shadow:0 0 18px rgba(234,149,22,.65) !important; +} +.metro-clean-beats .beat.active.accent{ + background:#22c55e !important; + box-shadow:0 0 18px rgba(34,197,94,.42),0 0 0 2px rgba(234,149,22,.13) !important; +} +@media (max-width:430px){ + #filterRow .filter-chip{font-size:10.5px !important;padding:6px 8px !important;} + .diagram{width:min(158px,100%) !important;} +} + +/* === EasyTune chord verification fixes: correct fret positions and O/X markers === */ +.diagram .finger-dot, +.modal-diagram .finger-dot{ + fill:#EA9516 !important; + stroke:none !important; +} +.diagram .state-open, +.modal-diagram .state-open{ + fill:rgba(0,0,0,0) !important; + stroke:#55d36a !important; + stroke-width:2.4 !important; + filter:none !important; +} +.diagram .state-muted line, +.modal-diagram .state-muted line{ + stroke:#ff6b6b !important; + stroke-width:2.4 !important; + stroke-linecap:round !important; + filter:none !important; +} + +/* === EasyTune follow-up: colored chord legend and compact chord cards === */ +#chord-modal-content::after{ + content:none !important; + display:none !important; +} +.chord-legend{ + display:flex !important; + flex-direction:column !important; + gap:4px !important; + width:min(300px,82vw) !important; + margin:6px auto 0 !important; + color:rgba(248,250,252,.78) !important; + font-size:14px !important; + line-height:1.45 !important; + text-align:left !important; +} +.chord-legend span{ + display:flex !important; + align-items:center !important; + gap:9px !important; +} +.chord-legend b{ + display:inline-flex !important; + align-items:center !important; + justify-content:center !important; + min-width:22px !important; + height:22px !important; + font-size:18px !important; + line-height:1 !important; + font-weight:800 !important; +} +.chord-legend .legend-o{color:#55d36a !important;} +.chord-legend .legend-x{color:#ff6b6b !important;} +.chord-legend .legend-fret{ + color:rgba(255,247,237,.78) !important; + font-size:13px !important; + font-weight:500 !important; + min-width:58px !important; + justify-content:flex-start !important; +} +.chord-card{ + padding:12px 10px 8px !important; + gap:0 !important; +} +.chord-card-head{ + margin:0 0 6px !important; + gap:6px !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + color:#fff7ed !important; + background:linear-gradient(135deg, rgba(234,149,22,.98), rgba(251,176,59,.84)) !important; + border:1px solid rgba(255,214,138,.44) !important; + box-shadow:0 8px 18px rgba(234,149,22,.18) !important; + padding:6px 13px !important; +} +.chord-notes{ + margin-top:0 !important; + margin-bottom:0 !important; + line-height:1.18 !important; +} +.chord-card .diagram{ + margin-top:0 !important; + margin-bottom:-8px !important; +} +@media (max-width:430px){ + .chord-card{padding:10px 8px 6px !important;} + .chord-card-head{margin-bottom:4px !important;} + .chord-card .diagram{margin-bottom:-10px !important;} +} + + +/* === EasyTune v6: calmer chord controls and balanced chord cards === */ +#chordSearch.search-input{ + display:block !important; + width:min(280px, 100%) !important; + max-width:280px !important; + margin:0 auto 16px !important; + text-align:center !important; + padding-left:18px !important; + padding-right:18px !important; +} +#filterRow.filter-row{ + display:flex !important; + flex-wrap:wrap !important; + justify-content:center !important; + align-items:center !important; + gap:6px !important; + max-width:330px !important; + margin:0 auto 18px !important; + padding:0 !important; +} +#filterRow .filter-chip{ + flex:0 0 auto !important; + min-width:0 !important; + font-size:10.5px !important; + font-weight:400 !important; + padding:6px 8px !important; + border-width:1px !important; + box-shadow:none !important; +} +.chord-card{ + padding:11px 9px 8px !important; +} +.chord-card-head{ + margin-bottom:5px !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + min-width:46px !important; + padding:4px 10px !important; + border-width:1px !important; + border-color:rgba(255,214,138,.30) !important; + border-radius:12px !important; + box-shadow:0 5px 12px rgba(234,149,22,.12) !important; +} +.chord-card .diagram{ + width:min(164px,100%) !important; + margin-bottom:-4px !important; +} +@media (max-width:430px){ + #chordSearch.search-input{width:min(250px,100%) !important;max-width:250px !important;} + #filterRow.filter-row{max-width:310px !important;gap:5px !important;} + #filterRow .filter-chip{font-size:10px !important;padding:6px 7px !important;} + .chord-card{padding:10px 8px 7px !important;} + .chord-card .diagram{width:min(160px,100%) !important;margin-bottom:-4px !important;} +} + + +/* === EasyTune v7: chord tile spacing and centered diagrams === */ +.chord-grid{ + gap:16px 12px !important; + align-items:start !important; +} +.chord-card{ + padding:10px 9px 10px !important; + overflow:visible !important; + min-height:auto !important; +} +.chord-card-head{ + margin-bottom:5px !important; +} +.chord-card .diagram{ + display:block !important; + width:min(166px,100%) !important; + height:auto !important; + margin:0 auto !important; +} +.chord-card .chord-name,#chordGrid .chord-name{ + padding:3px 8px !important; + min-width:40px !important; + border-radius:10px !important; + border-color:rgba(255,214,138,.26) !important; + box-shadow:0 3px 8px rgba(234,149,22,.10) !important; +} +.diagram .fret-number{ + font-size:14px !important; + font-weight:700 !important; +} +.modal-diagram .fret-number{ + font-size:15px !important; + font-weight:700 !important; +} +.diagram .state-open{ + stroke-width:2 !important; +} +.diagram .state-muted line{ + stroke-width:2.2 !important; +} +.modal-diagram .state-open{ + stroke-width:2.4 !important; +} +.modal-diagram .state-muted line{ + stroke-width:2.6 !important; +} +@media (max-width:430px){ + .chord-grid{gap:15px 10px !important;} + .chord-card{padding:9px 8px 10px !important;} + .chord-card .diagram{width:min(162px,100%) !important;margin:0 auto !important;} +} + + +/* === EasyTune v8: compact unified chord cards === */ +.chord-grid{ + gap:22px 12px !important; + align-items:start !important; +} +.chord-card{ + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:flex-start !important; + padding:11px 9px 12px !important; + overflow:visible !important; + border:1px solid rgba(234,149,22,.18) !important; + background:linear-gradient(180deg,rgba(255,255,255,.055),rgba(255,255,255,.025)) !important; +} +.chord-card-head{ + width:100% !important; + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:3px !important; + margin:0 0 4px !important; + padding:0 !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + display:block !important; + min-width:0 !important; + padding:0 !important; + border:0 !important; + border-radius:0 !important; + background:transparent !important; + box-shadow:none !important; + color:var(--accent) !important; + font-size:19px !important; + line-height:1.05 !important; + font-weight:760 !important; + letter-spacing:-.025em !important; + text-align:center !important; +} +.chord-card .chord-notes, +#chordGrid .chord-notes{ + display:block !important; + width:100% !important; + max-width:100% !important; + text-align:center !important; + font-size:10.5px !important; + line-height:1.15 !important; + font-weight:520 !important; + color:rgba(248,250,252,.72) !important; + padding:0 !important; + margin:0 !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; +} +.chord-card .diagram{ + display:block !important; + width:min(166px,100%) !important; + height:auto !important; + margin:0 auto !important; + padding:0 !important; + overflow:visible !important; +} +.diagram .fret-number{ + font-size:15px !important; + font-weight:760 !important; +} +.diagram .state-open{ + stroke-width:1.9 !important; +} +.diagram .state-muted line{ + stroke-width:2 !important; +} +.modal-diagram .state-open{ + stroke-width:2.2 !important; +} +.modal-diagram .state-muted line{ + stroke-width:2.35 !important; +} +@media (max-width:430px){ + .chord-grid{gap:20px 10px !important;} + .chord-card{padding:10px 8px 11px !important;} + .chord-card .chord-name,#chordGrid .chord-name{font-size:18px !important;} + .chord-card .diagram{width:min(162px,100%) !important;margin:0 auto !important;} +} + + +/* === EasyTune v9: unified chord surfaces, balanced string states, no white focus frame === */ +.tool-card:focus, +.tool-card:focus-visible, +.chord-card:focus, +.chord-card:focus-visible, +.back-btn:focus, +.back-btn:focus-visible, +.small-action:focus, +.small-action:focus-visible, +.ghost-btn:focus, +.ghost-btn:focus-visible, +.primary-btn:focus, +.primary-btn:focus-visible, +.round-btn:focus, +.round-btn:focus-visible, +.options-button:focus, +.options-button:focus-visible{ + outline:0 !important; + box-shadow:inherit !important; +} +.tool-card{ -webkit-tap-highlight-color:transparent !important; } +.chord-grid{ + gap:20px 12px !important; +} +.chord-card{ + padding:12px 10px 14px !important; + border:1px solid rgba(255,255,255,.12) !important; + border-radius:24px !important; + background: + radial-gradient(circle at 50% 0%, rgba(234,149,22,.08), transparent 12rem), + linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.018)), + linear-gradient(145deg,#111a22,#070d13) !important; + box-shadow:0 12px 30px rgba(0,0,0,.26), inset 0 1px 0 rgba(255,255,255,.05) !important; +} +.chord-card-head{ + margin:0 0 5px !important; +} +.chord-card .chord-name, +#chordGrid .chord-name, +.modal-chord-title{ + display:inline-flex !important; + align-items:center !important; + justify-content:center !important; + background:linear-gradient(180deg,#FFB83D,#EA9516) !important; + color:#111827 !important; + border:1px solid rgba(255,218,160,.28) !important; + box-shadow:0 4px 12px rgba(234,149,22,.18), inset 0 1px 0 rgba(255,255,255,.25) !important; + letter-spacing:-.035em !important; + text-align:center !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + min-width:42px !important; + min-height:30px !important; + padding:4px 10px !important; + border-radius:11px !important; + font-size:16px !important; + line-height:1 !important; + font-weight:780 !important; +} +.modal-chord-title{ + min-width:82px !important; + min-height:54px !important; + padding:6px 12px !important; + border-radius:13px !important; + font-size:36px !important; + line-height:1 !important; + font-weight:820 !important; + margin:0 auto 10px !important; +} +.chord-card .chord-notes, +#chordGrid .chord-notes{ + font-size:10.5px !important; + margin-top:1px !important; +} +.diagram, +.modal-diagram{ + background:transparent !important; + border:0 !important; + border-radius:0 !important; + padding:0 !important; + box-shadow:none !important; +} +.chord-card .diagram{ + width:min(164px,100%) !important; + margin:0 auto !important; +} +.diagram .fret-number{ + font-size:15px !important; + font-weight:780 !important; +} +.modal-diagram .fret-number{ + font-size:15px !important; + font-weight:780 !important; +} +.diagram .state-open, +.modal-diagram .state-open{ + fill:#38d66b !important; + stroke:#38d66b !important; + stroke-width:1.2 !important; +} +.diagram .state-muted line, +.modal-diagram .state-muted line{ + stroke:#ff4d4d !important; + stroke-width:1.7 !important; + stroke-linecap:round !important; +} +.legend-o{color:#38d66b !important;} +.legend-x{color:#ff4d4d !important;} +@media (max-width:430px){ + .chord-grid{gap:18px 10px !important;} + .chord-card{padding:11px 9px 13px !important;} + .chord-card .chord-name,#chordGrid .chord-name{font-size:15px !important;min-height:28px !important;padding:4px 9px !important;} + .chord-card .diagram{width:min(160px,100%) !important;} + .modal-chord-title{font-size:34px !important;min-width:78px !important;min-height:52px !important;} +} + + +/* === EasyTune v10: unified chord title box + home frame cleanup === */ +.start-panel.home-screen{ + border:0 !important; + outline:0 !important; + box-shadow:none !important; + border-radius:0 !important; +} +.start-panel.home-screen::before, +.start-panel.home-screen::after, +.home-screen::before, +.home-screen::after{ + border:0 !important; + outline:0 !important; + box-shadow:none !important; +} +.content:focus, +.content:focus-visible, +.start-panel:focus, +.start-panel:focus-visible, +.home-screen:focus, +.home-screen:focus-visible{ + outline:0 !important; + box-shadow:none !important; +} + +.chord-card{ + padding:12px 10px 13px !important; + gap:5px !important; +} +.chord-title-box, +.chord-card-head.chord-title-box, +.modal-chord-title-box{ + width:100% !important; + max-width:126px !important; + margin:0 auto 5px !important; + padding:0 !important; + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + overflow:hidden !important; + border-radius:13px !important; + border:1px solid rgba(255,218,160,.24) !important; + background:linear-gradient(180deg,#FFB83D,#EA9516) !important; + box-shadow:0 4px 12px rgba(234,149,22,.16), inset 0 1px 0 rgba(255,255,255,.23) !important; +} +.modal-chord-title-box{ + max-width:154px !important; + margin:0 auto 12px !important; + border-radius:14px !important; +} +.chord-card .chord-name, +#chordGrid .chord-name, +.modal-chord-title{ + display:block !important; + width:100% !important; + min-width:0 !important; + min-height:0 !important; + margin:0 !important; + padding:5px 9px 4px !important; + border:0 !important; + border-radius:0 !important; + background:transparent !important; + box-shadow:none !important; + color:#111827 !important; + text-align:center !important; + line-height:1 !important; + letter-spacing:-.03em !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + font-size:17px !important; + font-weight:800 !important; +} +.modal-chord-title{ + font-size:28px !important; + font-weight:820 !important; + padding:7px 10px 5px !important; +} +.chord-title-divider{ + display:block !important; + width:100% !important; + height:1px !important; + flex:0 0 1px !important; + background:rgba(17,24,39,.26) !important; + box-shadow:0 1px 0 rgba(255,255,255,.17) !important; +} +.chord-card .chord-notes, +#chordGrid .chord-notes, +.modal-chord-sub{ + display:block !important; + width:100% !important; + margin:0 !important; + padding:4px 7px 5px !important; + border:0 !important; + background:transparent !important; + color:rgba(17,24,39,.82) !important; + font-size:8.5px !important; + font-weight:650 !important; + line-height:1.05 !important; + text-align:center !important; + letter-spacing:.01em !important; +} +.modal-chord-sub{ + font-size:14px !important; + padding:5px 8px 7px !important; +} +.modal-chord-sub::before{content:"" !important;} +.diagram, +.modal-diagram{ + background:transparent !important; + border:0 !important; + box-shadow:none !important; + filter:none !important; +} +.chord-card .diagram{ + margin:0 auto !important; +} +.diagram .state-open, +.modal-diagram .state-open{ + r:3.4px; + stroke-width:1.1 !important; +} +.modal-diagram .state-open{r:5px;} +.diagram .state-muted line, +.modal-diagram .state-muted line{ + stroke-width:1.45 !important; +} +@media (max-width:430px){ + .chord-title-box,.chord-card-head.chord-title-box{max-width:118px !important;} + .chord-card .chord-name,#chordGrid .chord-name{font-size:16px !important;} + .chord-card .chord-notes,#chordGrid .chord-notes{font-size:8px !important;} + .modal-chord-title{font-size:27px !important;} +} + +/* === EasyTune v11: chord title geometry, legend alignment, home focus frame cleanup === */ +:focus, +:focus-visible{ + outline:0 !important; +} +#content, +#content:focus, +#content:focus-visible, +.app, +.app:focus, +.app:focus-visible, +.start-panel.home-screen, +.start-panel.home-screen:focus, +.start-panel.home-screen:focus-visible{ + outline:0 !important; + border-color:transparent !important; + box-shadow:none !important; +} +.start-panel.home-screen{ + border:0 !important; + background-clip:padding-box !important; +} +.home-screen .home-card-bg{ + border:0 !important; + box-shadow:none !important; +} +.tool-card:focus, +.tool-card:focus-visible, +.tool-card:active, +.logo-button:focus, +.logo-button:focus-visible, +.options-button:focus, +.options-button:focus-visible{ + outline:0 !important; +} + +.tool-title, +.view-card > .form-label, +.view-card > .group-label, +.metro-settings-card h2, +.tap-help-card h2, +.app-modal-card h2{ + font-weight:500 !important; + letter-spacing:.018em !important; +} + +.chord-title-box, +.chord-card-head.chord-title-box{ + width:110px !important; + min-width:110px !important; + max-width:110px !important; + margin:0 auto 6px !important; + padding:0 !important; + gap:0 !important; +} +.modal-chord-title-box{ + width:180px !important; + min-width:180px !important; + max-width:180px !important; + margin:0 auto 12px !important; + padding:0 !important; + gap:0 !important; +} +.chord-card .chord-name, +#chordGrid .chord-name, +.modal-chord-title{ + padding:6px 7px !important; + border:0 !important; + box-shadow:none !important; + background:transparent !important; + min-height:0 !important; + line-height:1 !important; + letter-spacing:-.015em !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + font-size:17px !important; + font-weight:760 !important; +} +.modal-chord-title{ + font-size:28px !important; + font-weight:760 !important; +} +.chord-title-divider{ + margin:0 !important; + height:1px !important; + flex:0 0 1px !important; +} +.chord-card .chord-notes, +#chordGrid .chord-notes, +.modal-chord-sub{ + padding:6px 7px !important; + margin:0 !important; + line-height:1 !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; +} +.chord-card .chord-notes, +#chordGrid .chord-notes{ + font-size:8.5px !important; + font-weight:620 !important; +} +.modal-chord-sub{ + font-size:14px !important; + font-weight:620 !important; +} + +.chord-legend{ + width:180px !important; + max-width:180px !important; + margin:8px auto 0 !important; + padding:0 !important; + align-items:flex-start !important; + text-align:left !important; +} +.chord-legend span{ + width:100% !important; + display:flex !important; + align-items:center !important; + justify-content:flex-start !important; + gap:8px !important; + margin:0 !important; + padding:0 !important; + text-align:left !important; +} +.chord-legend b{ + flex:0 0 18px !important; + width:18px !important; + min-width:18px !important; + max-width:18px !important; + height:18px !important; + margin:0 !important; + padding:0 !important; + display:inline-flex !important; + align-items:center !important; + justify-content:center !important; + text-align:center !important; +} +.chord-legend .legend-fret{ + flex-basis:46px !important; + width:46px !important; + min-width:46px !important; + max-width:46px !important; + justify-content:flex-start !important; + text-align:left !important; +} +@media (max-width:430px){ + .chord-title-box, + .chord-card-head.chord-title-box{ + width:110px !important; + min-width:110px !important; + max-width:110px !important; + } + .modal-chord-title-box{ + width:180px !important; + min-width:180px !important; + max-width:180px !important; + } + .chord-card .chord-name,#chordGrid .chord-name{font-size:17px !important;} + .chord-card .chord-notes,#chordGrid .chord-notes{font-size:8.5px !important;} +} + + +/* === EasyTune v12: card title weight 600 + chord card title only === */ +.tool-title, +.view-card > .form-label, +.view-card > .group-label, +.metro-settings-card h2, +.tap-help-card h2, +.app-modal-card h2, +.card-title, +.view-title, +.section-title, +.panel-title{ + font-weight:600 !important; + letter-spacing:.022em !important; +} + +.chord-card .chord-title-box, +.chord-card-head.chord-title-box{ + width:110px !important; + min-width:110px !important; + max-width:110px !important; + min-height:30px !important; + margin:0 auto 6px !important; + padding:0 !important; + border-radius:12px !important; +} + +.chord-card .chord-name, +#chordGrid .chord-name{ + font-size:17px !important; + font-weight:600 !important; + letter-spacing:.012em !important; + padding:7px 8px !important; + line-height:1 !important; +} + +.chord-card .chord-title-divider, +.chord-card .chord-notes, +#chordGrid .chord-notes{ + display:none !important; +} + +.modal-chord-title-box{ + width:180px !important; + min-width:180px !important; + max-width:180px !important; +} +.modal-chord-title{ + font-weight:600 !important; +} +@media (max-width:430px){ + .chord-card .chord-title-box, + .chord-card-head.chord-title-box{ + width:110px !important; + min-width:110px !important; + max-width:110px !important; + } + .chord-card .chord-name,#chordGrid .chord-name{font-size:17px !important;} +} + + +/* === EasyTune v13: chord layout normalization === */ +:root{ + --chord-fretboard-small:110px; + --chord-fretboard-modal:180px; +} + +/* Kafelki i modal akordu: jeden rytm paddingów, środek optyczny, zawartość ok. 80% */ +.chord-card{ + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:7px !important; + padding:12px 10px 14px !important; + min-height:auto !important; + overflow:visible !important; +} +.chord-modal-card{ + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:12px !important; +} +#chord-modal-content{ + width:100% !important; + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:12px !important; +} + +/* Ramka nazwy = szerokość właściwego gryfu, bez osobnej ramki diagramu */ +.chord-card .chord-title-box, +.chord-card-head.chord-title-box{ + width:var(--chord-fretboard-small) !important; + min-width:var(--chord-fretboard-small) !important; + max-width:var(--chord-fretboard-small) !important; + margin:0 auto 2px !important; + padding:0 !important; + border-radius:12px !important; +} +.modal-chord-title-box{ + width:var(--chord-fretboard-modal) !important; + min-width:var(--chord-fretboard-modal) !important; + max-width:var(--chord-fretboard-modal) !important; + margin:0 auto 2px !important; + padding:0 !important; + border-radius:14px !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + font-size:16px !important; + font-weight:600 !important; + letter-spacing:.012em !important; + padding:6px 7px !important; + line-height:1.05 !important; +} +.modal-chord-title{ + font-size:28px !important; + font-weight:600 !important; + letter-spacing:.01em !important; + padding:8px 9px !important; + line-height:1.05 !important; +} +.chord-title-divider{ + margin:0 !important; +} +.modal-chord-sub{ + font-size:14px !important; + font-weight:600 !important; + padding:8px 9px !important; + line-height:1.05 !important; +} +.chord-card .chord-title-divider, +.chord-card .chord-notes, +#chordGrid .chord-notes{ + display:none !important; +} + +/* Diagram jako część tego samego kontenera, bez ramki; środek zgodny z ramką nazwy */ +.chord-card .diagram{ + width:min(170px,100%) !important; + margin:0 auto !important; + padding:0 !important; + background:transparent !important; + border:0 !important; + box-shadow:none !important; + overflow:visible !important; +} +.modal-diagram{ + width:min(280px,80vw) !important; + margin:0 auto !important; + padding:0 !important; + background:transparent !important; + border:0 !important; + box-shadow:none !important; + overflow:visible !important; +} +.diagram .fret-number, +.modal-diagram .fret-number{ + font-size:16px !important; + font-weight:780 !important; + fill:rgba(255,247,237,.78) !important; +} + +/* Otwarte kółka granych pustych strun + X optycznie równe kółku */ +.diagram .state-open, +.modal-diagram .state-open{ + fill:transparent !important; + stroke:#38d66b !important; + stroke-width:1.45 !important; + filter:none !important; +} +.diagram .state-muted line, +.modal-diagram .state-muted line{ + stroke:#ff4d4d !important; + stroke-width:1.35 !important; + stroke-linecap:round !important; + filter:none !important; +} + +/* Legenda: wyrównanie i skrócona numeracja */ +.chord-legend{ + width:var(--chord-fretboard-modal) !important; + max-width:var(--chord-fretboard-modal) !important; + margin:0 auto !important; + padding:0 !important; + display:flex !important; + flex-direction:column !important; + align-items:stretch !important; + gap:5px !important; + text-align:left !important; +} +.chord-legend span{ + display:grid !important; + grid-template-columns:38px 1fr !important; + align-items:center !important; + justify-items:start !important; + gap:7px !important; + width:100% !important; + margin:0 !important; + padding:0 !important; + text-align:left !important; +} +.chord-legend b, +.chord-legend .legend-fret{ + width:38px !important; + min-width:38px !important; + max-width:38px !important; + height:auto !important; + margin:0 !important; + padding:0 !important; + display:inline-flex !important; + align-items:center !important; + justify-content:flex-start !important; + text-align:left !important; +} +.legend-o{color:#38d66b !important;} +.legend-x{color:#ff4d4d !important;} + +@media (max-width:430px){ + .chord-card{padding:11px 8px 13px !important;gap:6px !important;} + .chord-card .chord-title-box, + .chord-card-head.chord-title-box{ + width:var(--chord-fretboard-small) !important; + min-width:var(--chord-fretboard-small) !important; + max-width:var(--chord-fretboard-small) !important; + } + .chord-card .chord-name,#chordGrid .chord-name{font-size:15.5px !important;} + .modal-chord-title{font-size:27px !important;} +} + + +/* v14 adjustments */ +.chord-card{ + padding:12px 12px 8px !important; /* equal top/side */ +} +.chord-card .chord-name, +#chordGrid .chord-name{ + width:85% !important; + max-width:85% !important; + margin:0 auto !important; +} +.chord-modal-card,.app-modal-card{ + padding:12px !important; +} + + +/* === EasyTune v15: fret-number spacing and more natural titles === */ +.diagram .fret-number, +.modal-diagram .fret-number{ + text-anchor:end !important; +} + +.card-title, +.view-title, +.section-title, +.tool-title, +.panel-title, +.option-title, +.app-modal-card h2, +.metro-visual-card h2{ + font-weight:600 !important; + letter-spacing:0 !important; + line-height:1.18 !important; +} + +.card-title, +.section-title{ + text-transform:none !important; +} + +.chord-card .chord-name, +#chordGrid .chord-name, +.modal-chord-title{ + letter-spacing:0 !important; + font-weight:600 !important; +} + +.chord-card .chord-title-box, +.chord-card-head.chord-title-box{ + width:94px !important; + min-width:94px !important; + max-width:94px !important; +} + +.chord-card .chord-name, +#chordGrid .chord-name{ + width:100% !important; + max-width:100% !important; +} + +@media (max-width:430px){ + .chord-card .chord-title-box, + .chord-card-head.chord-title-box{ + width:94px !important; + min-width:94px !important; + max-width:94px !important; + } +} + + +/* === EasyTune v16: final chord geometry polish === */ +:root{ + --chord-fretboard-small:110px; + --chord-fretboard-modal:180px; +} + +/* Ramka nazwy w kafelkach dokładnie jak szerokość gryfu */ +.chord-card .chord-title-box, +.chord-card-head.chord-title-box{ + width:var(--chord-fretboard-small) !important; + min-width:var(--chord-fretboard-small) !important; + max-width:var(--chord-fretboard-small) !important; + box-sizing:border-box !important; + margin:0 auto 6px !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + width:100% !important; + max-width:100% !important; + box-sizing:border-box !important; + padding:6px 7px !important; + text-align:center !important; +} + +/* Mniejsze otwarte kółka strun granych, bez optycznej przewagi nad X */ +.diagram .state-open, +.modal-diagram .state-open{ + r:2.45px !important; + fill:transparent !important; + stroke:#38d66b !important; + stroke-width:1.25 !important; +} +.modal-diagram .state-open{ + r:3.4px !important; +} +.diagram .state-muted line, +.modal-diagram .state-muted line{ + stroke-width:1.25 !important; +} + +/* Legenda w modalu zaczyna się w osi numerów progów */ +.chord-legend{ + width:212px !important; + max-width:212px !important; + min-width:212px !important; + margin:2px auto 0 !important; + padding:0 !important; + align-self:center !important; +} +.chord-legend span{ + grid-template-columns:32px 1fr !important; + gap:8px !important; +} +.chord-legend b, +.chord-legend .legend-fret{ + width:32px !important; + min-width:32px !important; + max-width:32px !important; +} + +@media (max-width:430px){ + .chord-card .chord-title-box, + .chord-card-head.chord-title-box{ + width:var(--chord-fretboard-small) !important; + min-width:var(--chord-fretboard-small) !important; + max-width:var(--chord-fretboard-small) !important; + } +} + +/* === EasyTune v17: unified subviews and letter chord filters === */ +.view-screen .view-card{ + border:1px solid rgba(255,255,255,.055) !important; + background:linear-gradient(180deg,rgba(255,255,255,.035),rgba(255,255,255,.018)) !important; + box-shadow:none !important; +} +.view-screen .view-card + .view-card{margin-top:12px !important;} +.view-screen .view-head{ + border:0 !important; + box-shadow:none !important; +} +.chords-panel{ + padding:0 !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; +} +.letter-filter-row, +.type-filter-row{ + width:100% !important; + display:flex !important; + flex-wrap:wrap !important; + justify-content:center !important; + align-items:center !important; + gap:7px !important; + margin:0 auto 10px !important; + padding:0 !important; +} +.type-filter-row{margin-bottom:14px !important;} +.letter-chip, +.filter-chip{ + appearance:none !important; + border:1px solid rgba(255,255,255,.10) !important; + background:rgba(255,255,255,.035) !important; + color:rgba(248,250,252,.78) !important; + border-radius:999px !important; + min-height:30px !important; + padding:6px 10px !important; + font-size:12px !important; + line-height:1 !important; + font-weight:560 !important; + letter-spacing:.01em !important; + box-shadow:none !important; +} +.letter-chip:not([data-letter="all"]){ + width:30px !important; + min-width:30px !important; + max-width:30px !important; + padding-left:0 !important; + padding-right:0 !important; +} +.letter-chip.active, +.filter-chip.active{ + border-color:rgba(234,149,22,.42) !important; + background:rgba(234,149,22,.18) !important; + color:#fff7ed !important; +} +#chordSearch, +label[for="chordSearch"]{ + display:none !important; +} +.chord-grid{ + margin-top:0 !important; +} +/* reduce nested-border feeling in metronome/transpose while keeping sections readable */ +.metro-layout .view-card, +.view-card .output-box, +.song-input{ + border-color:rgba(255,255,255,.07) !important; + box-shadow:none !important; +} +@media (max-width:430px){ + .letter-filter-row,.type-filter-row{gap:6px !important;} + .letter-chip,.filter-chip{font-size:11.5px !important;min-height:29px !important;padding:6px 9px !important;} + .letter-chip:not([data-letter="all"]){width:29px !important;min-width:29px !important;max-width:29px !important;} +} + +/* === EasyTune v20: v18/v19 fixes reapplied on v17 base === */ +/* Chords view: no extra frame around the main chord container */ +.view-screen > .chords-panel, +.view-card.chords-panel, +.chords-panel{ + border:0 !important; + outline:0 !important; + background:transparent !important; + box-shadow:none !important; + padding:0 !important; +} +.chords-panel::before, +.chords-panel::after{display:none !important;content:none !important;} + +/* Multi-select filters: top row letters only, second row chord traits including # */ +.letter-filter-row, +.type-filter-row{ + display:flex !important; + flex-wrap:wrap !important; + justify-content:center !important; + align-items:center !important; + gap:7px !important; + width:100% !important; + margin:0 auto 10px !important; + padding:0 !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; +} +.type-filter-row{margin-bottom:14px !important;} +.letter-chip, +.filter-chip{ + appearance:none !important; + border:1px solid rgba(255,255,255,.10) !important; + background:rgba(255,255,255,.035) !important; + color:rgba(248,250,252,.78) !important; + border-radius:999px !important; + min-height:30px !important; + padding:6px 10px !important; + font-size:12px !important; + line-height:1 !important; + font-weight:560 !important; + letter-spacing:.01em !important; + box-shadow:none !important; +} +.letter-chip{ + width:30px !important; + min-width:30px !important; + max-width:30px !important; + padding-left:0 !important; + padding-right:0 !important; +} +.letter-chip.active, +.filter-chip.active{ + border-color:rgba(234,149,22,.50) !important; + background:rgba(234,149,22,.22) !important; + color:#fff7ed !important; +} + +/* Chord cards: title border locked to fretboard width and centered */ +:root{--chord-fretboard-small:144px;--chord-fretboard-large:232px;} +.chord-card-head.chord-title-box{ + width:var(--chord-fretboard-small) !important; + max-width:var(--chord-fretboard-small) !important; + margin:0 auto 7px !important; + padding:0 !important; + display:flex !important; + justify-content:center !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + width:100% !important; + max-width:100% !important; + min-width:0 !important; + box-sizing:border-box !important; + font-size:15px !important; + line-height:1 !important; + padding:5px 8px !important; + border-radius:11px !important; + font-weight:650 !important; + letter-spacing:-.015em !important; +} +.chord-card .diagram{ + width:var(--chord-fretboard-small) !important; + max-width:var(--chord-fretboard-small) !important; + margin:0 auto !important; +} + +/* Fret numbers slightly closer to fretboard, but still readable */ +.diagram .fret-number, +.modal-diagram .fret-number{ + text-anchor:end !important; + font-size:15px !important; + font-weight:780 !important; +} + +/* Modal spacing and legend aligned with fret-number axis */ +.chord-modal-card{padding:44px 18px 18px !important;} +#chord-modal-content{ + display:flex !important; + flex-direction:column !important; + align-items:center !important; +} +.modal-chord-title-box.chord-title-box{ + width:var(--chord-fretboard-large) !important; + max-width:var(--chord-fretboard-large) !important; + margin:0 auto 12px !important; +} +.modal-diagram{ + width:var(--chord-fretboard-large) !important; + max-width:var(--chord-fretboard-large) !important; +} +.chord-legend{ + width:var(--chord-fretboard-large) !important; + max-width:var(--chord-fretboard-large) !important; + box-sizing:border-box !important; + margin:10px auto 0 !important; + padding-left:0 !important; + justify-content:flex-start !important; + text-align:left !important; +} + +@media (max-width:430px){ + :root{--chord-fretboard-small:140px;--chord-fretboard-large:226px;} + .letter-filter-row,.type-filter-row{gap:6px !important;} + .letter-chip,.filter-chip{font-size:11.5px !important;min-height:29px !important;padding:6px 9px !important;} + .letter-chip{width:29px !important;min-width:29px !important;max-width:29px !important;} + .chord-card .chord-name,#chordGrid .chord-name{font-size:14.5px !important;} + .chord-modal-card{padding:42px 14px 16px !important;} +} + + +/* === EasyTune v21: restored chord typography, aligned legend, OR filter UI cleanup === */ +:root{ + --chord-diagram-small:144px; + --chord-diagram-modal:232px; + --chord-fretboard-title-small:94px; + --chord-fretboard-title-modal:149px; +} + +/* chord subview surface: no extra surrounding frame */ +.view-card.chords-panel, +.chords-panel, +.view-screen > .chords-panel{ + border:0 !important; + outline:0 !important; + background:transparent !important; + box-shadow:none !important; + padding:0 !important; +} + +/* filters: upper row letters only; lower row traits; multi-select */ +.letter-filter-row,.type-filter-row{ + display:flex !important; + flex-wrap:wrap !important; + justify-content:center !important; + align-items:center !important; + gap:7px !important; + width:100% !important; + margin:0 auto 10px !important; + padding:0 !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; +} +.type-filter-row{margin-bottom:14px !important;} +.letter-chip[data-letter="all"],.filter-chip[data-filter="all"]{display:none !important;} +.letter-chip,.filter-chip{ + appearance:none !important; + border:1px solid rgba(255,255,255,.10) !important; + background:rgba(255,255,255,.035) !important; + color:rgba(248,250,252,.78) !important; + border-radius:999px !important; + min-height:30px !important; + padding:6px 10px !important; + font-size:12px !important; + line-height:1 !important; + font-weight:560 !important; + letter-spacing:.01em !important; + box-shadow:none !important; +} +.letter-chip{ + width:30px !important; + min-width:30px !important; + max-width:30px !important; + padding-left:0 !important; + padding-right:0 !important; +} +.letter-chip.active,.filter-chip.active{ + border-color:rgba(234,149,22,.50) !important; + background:rgba(234,149,22,.22) !important; + color:#fff7ed !important; +} + +/* card layout: one figure holds title, notes and diagram */ +.chord-grid{gap:20px 12px !important;} +.chord-card{ + display:flex !important; + align-items:center !important; + justify-content:center !important; + padding:12px !important; + overflow:visible !important; +} +.chord-figure, +.chord-card-figure, +.modal-chord-figure{ + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:flex-start !important; + gap:7px !important; + width:100% !important; + margin:0 auto !important; + padding:0 !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; +} +.chord-card-figure{max-width:var(--chord-diagram-small) !important;} +.modal-chord-figure{max-width:var(--chord-diagram-modal) !important;gap:10px !important;} + +/* name + notes box: exact visual fretboard width */ +.chord-card .chord-title-box, +.chord-card-head.chord-title-box{ + width:var(--chord-fretboard-title-small) !important; + min-width:var(--chord-fretboard-title-small) !important; + max-width:var(--chord-fretboard-title-small) !important; + box-sizing:border-box !important; + margin:0 auto !important; + padding:0 !important; + overflow:hidden !important; + border-radius:12px !important; + border:1px solid rgba(255,218,160,.24) !important; + background:linear-gradient(180deg,#FFB83D,#EA9516) !important; + box-shadow:0 4px 12px rgba(234,149,22,.16), inset 0 1px 0 rgba(255,255,255,.23) !important; +} +.modal-chord-title-box.chord-title-box, +.modal-chord-title-box{ + width:var(--chord-fretboard-title-modal) !important; + min-width:var(--chord-fretboard-title-modal) !important; + max-width:var(--chord-fretboard-title-modal) !important; + box-sizing:border-box !important; + margin:0 auto !important; + padding:0 !important; + overflow:hidden !important; + border-radius:14px !important; + border:1px solid rgba(255,218,160,.24) !important; + background:linear-gradient(180deg,#FFB83D,#EA9516) !important; + box-shadow:0 4px 12px rgba(234,149,22,.16), inset 0 1px 0 rgba(255,255,255,.23) !important; +} +.chord-card .chord-name,#chordGrid .chord-name,.modal-chord-title{ + display:block !important; + width:100% !important; + max-width:100% !important; + min-width:0 !important; + box-sizing:border-box !important; + margin:0 !important; + border:0 !important; + border-radius:0 !important; + background:transparent !important; + box-shadow:none !important; + color:#111827 !important; + text-align:center !important; + line-height:1 !important; + letter-spacing:0 !important; + font-weight:650 !important; +} +.chord-card .chord-name,#chordGrid .chord-name{font-size:15px !important;padding:5px 7px 4px !important;} +.modal-chord-title{font-size:26px !important;padding:7px 8px 6px !important;} +.chord-title-divider{ + display:block !important; + width:100% !important; + height:1px !important; + flex:0 0 1px !important; + margin:0 !important; + background:rgba(17,24,39,.26) !important; + box-shadow:0 1px 0 rgba(255,255,255,.17) !important; +} +.chord-card .chord-notes,#chordGrid .chord-notes,.modal-chord-sub{ + display:block !important; + width:100% !important; + box-sizing:border-box !important; + margin:0 !important; + border:0 !important; + background:transparent !important; + color:rgba(17,24,39,.82) !important; + font-weight:620 !important; + text-align:center !important; + line-height:1.05 !important; + letter-spacing:0 !important; + white-space:normal !important; +} +.chord-card .chord-notes,#chordGrid .chord-notes{font-size:8px !important;padding:4px 5px 5px !important;} +.modal-chord-sub{font-size:13px !important;padding:6px 7px 7px !important;} +.modal-chord-sub::before{content:"" !important;} + +/* diagram width and no separate frame */ +.chord-card .diagram{ + display:block !important; + width:var(--chord-diagram-small) !important; + max-width:var(--chord-diagram-small) !important; + height:auto !important; + margin:0 auto !important; + padding:0 !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; + overflow:visible !important; +} +.modal-diagram{ + display:block !important; + width:var(--chord-diagram-modal) !important; + max-width:var(--chord-diagram-modal) !important; + height:auto !important; + margin:0 auto !important; + padding:0 !important; + border:0 !important; + background:transparent !important; + box-shadow:none !important; + overflow:visible !important; +} +.diagram .fret-number,.modal-diagram .fret-number{ + text-anchor:end !important; + font-size:15px !important; + font-weight:780 !important; + fill:rgba(255,247,237,.78) !important; +} +.diagram .state-open,.modal-diagram .state-open{ + fill:transparent !important; + stroke:#38d66b !important; + stroke-width:1.15 !important; + filter:none !important; +} +.diagram .state-muted line,.modal-diagram .state-muted line{ + stroke:#ff4d4d !important; + stroke-width:1.25 !important; + stroke-linecap:round !important; + filter:none !important; +} + +/* modal legend: full diagram width, no early wrapping, starts at fret-number axis */ +.chord-legend{ + width:var(--chord-diagram-modal) !important; + max-width:var(--chord-diagram-modal) !important; + box-sizing:border-box !important; + margin:0 auto !important; + padding:0 0 0 30px !important; + display:flex !important; + flex-direction:column !important; + align-items:flex-start !important; + gap:5px !important; + text-align:left !important; + overflow:visible !important; +} +.chord-legend span{ + display:flex !important; + align-items:center !important; + justify-content:flex-start !important; + gap:7px !important; + width:auto !important; + max-width:none !important; + margin:0 !important; + padding:0 !important; + white-space:nowrap !important; + text-align:left !important; + font-size:12px !important; + line-height:1.15 !important; +} +.chord-legend b,.chord-legend .legend-fret{ + flex:0 0 30px !important; + width:30px !important; + min-width:30px !important; + max-width:30px !important; + height:auto !important; + margin:0 !important; + padding:0 !important; + display:inline-flex !important; + align-items:center !important; + justify-content:flex-start !important; + text-align:left !important; +} +.legend-o{color:#38d66b !important;} +.legend-x{color:#ff4d4d !important;} + +@media (max-width:430px){ + :root{--chord-diagram-small:140px;--chord-diagram-modal:226px;--chord-fretboard-title-small:91px;--chord-fretboard-title-modal:145px;} + .chord-card{padding:11px 9px !important;} + .letter-filter-row,.type-filter-row{gap:6px !important;} + .letter-chip,.filter-chip{font-size:11.5px !important;min-height:29px !important;padding:6px 9px !important;} + .letter-chip{width:29px !important;min-width:29px !important;max-width:29px !important;} + .chord-card .chord-name,#chordGrid .chord-name{font-size:14.5px !important;} + .modal-chord-title{font-size:25px !important;} + .chord-legend{padding-left:29px !important;} + .chord-legend span{font-size:11.5px !important;} +} + + +/* === EasyTune v22: exact 7 filter + 20% larger chord modal content === */ +:root{ + --chord-diagram-modal:278px; + --chord-fretboard-title-modal:179px; +} +.chord-modal-card{ + padding:32px 10px 12px !important; +} +.modal-chord-figure{ + max-width:var(--chord-diagram-modal) !important; + gap:12px !important; +} +.modal-chord-title-box.chord-title-box, +.modal-chord-title-box{ + width:var(--chord-fretboard-title-modal) !important; + min-width:var(--chord-fretboard-title-modal) !important; + max-width:var(--chord-fretboard-title-modal) !important; +} +.modal-diagram{ + width:var(--chord-diagram-modal) !important; + max-width:var(--chord-diagram-modal) !important; +} +.modal-chord-title{ + font-size:31px !important; + padding:8px 9px 7px !important; +} +.modal-chord-sub{ + font-size:15.5px !important; + padding:7px 8px 8px !important; +} +.chord-legend{ + width:var(--chord-diagram-modal) !important; + max-width:var(--chord-diagram-modal) !important; + padding-left:36px !important; +} +.chord-legend span{ + font-size:13px !important; +} +.chord-legend b,.chord-legend .legend-fret{ + flex-basis:34px !important; + width:34px !important; + min-width:34px !important; + max-width:34px !important; +} +@media (max-width:430px){ + :root{--chord-diagram-modal:270px;--chord-fretboard-title-modal:174px;} + .chord-modal-card{padding:30px 8px 10px !important;} + .modal-chord-title{font-size:30px !important;} + .modal-chord-sub{font-size:15px !important;} + .chord-legend{padding-left:35px !important;} + .chord-legend span{font-size:12.5px !important;} +} + + +/* === EasyTune v23: filter spacing, centered chord cards, larger modal diagrams === */ +:root{ + --chord-diagram-modal:318px; + --chord-fretboard-title-modal:205px; +} +.letter-filter-row{ + margin:0 auto 18px !important; + gap:8px !important; +} +.type-filter-row{ + margin:0 auto 18px !important; + gap:8px !important; +} +.letter-chip, +.filter-chip{ + min-height:32px !important; + font-size:13px !important; + line-height:1 !important; +} +.letter-chip{ + width:32px !important; + min-width:32px !important; + max-width:32px !important; +} +.filter-chip[data-filter="sharp"], +.filter-chip[data-filter="7"]{ + width:32px !important; + min-width:32px !important; + max-width:32px !important; + height:32px !important; + min-height:32px !important; + padding:0 !important; + display:inline-flex !important; + align-items:center !important; + justify-content:center !important; + border-radius:999px !important; +} +.chord-grid{ + align-items:stretch !important; +} +.chord-card{ + display:flex !important; + align-items:center !important; + justify-content:center !important; + text-align:center !important; + padding:12px !important; +} +.chord-card-figure{ + min-height:100% !important; + justify-content:center !important; + align-items:center !important; +} +.chord-card .chord-title-divider, +.chord-card .chord-notes, +#chordGrid .chord-notes{ + display:none !important; +} +.chord-card .diagram .fret-number{ + font-size:15px !important; +} +.modal-diagram .fret-number{ + font-size:15.5px !important; +} +.modal-chord-figure{ + max-width:var(--chord-diagram-modal) !important; + gap:12px !important; +} +.modal-diagram{ + width:var(--chord-diagram-modal) !important; + max-width:var(--chord-diagram-modal) !important; +} +.modal-chord-title-box.chord-title-box, +.modal-chord-title-box{ + width:var(--chord-fretboard-title-modal) !important; + min-width:var(--chord-fretboard-title-modal) !important; + max-width:var(--chord-fretboard-title-modal) !important; +} +.chord-legend{ + width:var(--chord-diagram-modal) !important; + max-width:var(--chord-diagram-modal) !important; + padding-left:40px !important; +} +@media (max-width:430px){ + :root{--chord-diagram-modal:306px;--chord-fretboard-title-modal:198px;} + .letter-filter-row{margin-bottom:16px !important;gap:7px !important;} + .type-filter-row{margin-bottom:17px !important;gap:7px !important;} + .letter-chip,.filter-chip{font-size:12.5px !important;min-height:31px !important;} + .letter-chip,.filter-chip[data-filter="sharp"],.filter-chip[data-filter="7"]{width:31px !important;min-width:31px !important;max-width:31px !important;height:31px !important;} + .chord-legend{padding-left:38px !important;} +} + +/* === EasyTune v24: chord figure unified, filter reset companion styling === */ +:root{ + --chord-diagram-small:150px; + --chord-fretboard-title-small:96px; +} +/* widok akordów: nazwa i diagram jako jeden spójny pionowy blok */ +.chord-card{ + padding:13px 12px !important; + align-items:center !important; + justify-content:center !important; +} +.chord-card-figure{ + width:var(--chord-diagram-small) !important; + max-width:var(--chord-diagram-small) !important; + margin:0 auto !important; + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:5px !important; + min-height:0 !important; +} +.chord-card-head.chord-title-box, +.chord-card .chord-title-box{ + width:var(--chord-fretboard-title-small) !important; + min-width:var(--chord-fretboard-title-small) !important; + max-width:var(--chord-fretboard-title-small) !important; + margin:0 auto !important; + padding:0 !important; + display:flex !important; + align-items:center !important; + justify-content:center !important; + box-sizing:border-box !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + width:100% !important; + padding:6px 7px !important; + border:1px solid rgba(234,149,22,.38) !important; + border-radius:14px !important; + background:rgba(234,149,22,.16) !important; + text-align:center !important; + box-sizing:border-box !important; + font-size:15px !important; + font-weight:620 !important; + line-height:1 !important; + letter-spacing:0 !important; +} +.chord-card .diagram{ + width:var(--chord-diagram-small) !important; + max-width:var(--chord-diagram-small) !important; + margin:0 auto !important; +} +.chord-card .chord-title-divider, +.chord-card .chord-notes, +#chordGrid .chord-notes{ + display:none !important; +} + +/* modal: nazwa, dźwięki i diagram w tej samej osi oraz bez osobnego "pływania" */ +.modal-chord-figure{ + width:var(--chord-diagram-modal) !important; + max-width:var(--chord-diagram-modal) !important; + margin:0 auto !important; + align-items:center !important; + justify-content:center !important; + gap:10px !important; +} +.modal-chord-title-box.chord-title-box, +.modal-chord-title-box{ + width:var(--chord-fretboard-title-modal) !important; + min-width:var(--chord-fretboard-title-modal) !important; + max-width:var(--chord-fretboard-title-modal) !important; + margin:0 auto !important; + box-sizing:border-box !important; +} +.modal-chord-sub::before{ + content:"Dźwięki: " !important; + color:rgba(248,250,252,.66) !important; + font-weight:650 !important; +} + +/* mniej pustego światła między nazwą a diagramem w kafelkach */ +.chord-grid{align-items:stretch !important;} +.chord-card:focus, +.chord-card:focus-visible{ + outline:none !important; + box-shadow:0 16px 34px rgba(0,0,0,.24) !important; +} + +@media (max-width:430px){ + :root{--chord-diagram-small:146px;--chord-fretboard-title-small:93px;} + .chord-card{padding:12px 10px !important;} + .chord-card-figure{gap:4px !important;} + .chord-card .chord-name,#chordGrid .chord-name{font-size:14.5px !important;padding:6px 7px !important;} +} + +/* === EasyTune v25: chord filters spacing, reset, and card vertical balance === */ +.chords-panel{ + padding-top:18px !important; +} +.letter-filter-row{ + margin:0 auto 22px !important; + row-gap:10px !important; + column-gap:8px !important; +} +.type-filter-row{ + margin:0 auto 18px !important; + row-gap:10px !important; + column-gap:9px !important; +} +.chord-filter-actions{ + display:flex !important; + justify-content:center !important; + align-items:center !important; + margin:0 auto 18px !important; +} +.chord-reset-btn{ + min-height:34px !important; + padding:8px 18px !important; + border-radius:999px !important; + font-size:12px !important; + font-weight:700 !important; + letter-spacing:.03em !important; + text-transform:uppercase !important; +} +.chord-card{ + padding:14px 12px !important; + display:flex !important; + align-items:center !important; + justify-content:center !important; +} +.chord-card-figure{ + gap:2px !important; + justify-content:center !important; + align-items:center !important; +} +.chord-card .diagram{ + margin-top:0 !important; + margin-bottom:0 !important; +} +.chord-card-head.chord-title-box, +.chord-card .chord-title-box{ + margin:0 auto !important; +} +@media (max-width:430px){ + .letter-filter-row{margin-bottom:20px !important;row-gap:9px !important;column-gap:7px !important;} + .type-filter-row{margin-bottom:16px !important;row-gap:9px !important;column-gap:8px !important;} + .chord-filter-actions{margin-bottom:16px !important;} + .chord-card{padding:13px 10px !important;} + .chord-card-figure{gap:1px !important;} +} + + +/* === EasyTune v26: chord header reset, full names, balanced chord cards and modal notes === */ +.chords-view-head{ + display:grid !important; + grid-template-columns:auto 1fr auto !important; + align-items:center !important; + gap:12px !important; +} +.chords-view-head .view-title{ + text-align:center !important; + justify-self:center !important; + margin:0 !important; +} +.chords-view-head .chord-reset-btn{ + justify-self:end !important; + min-width:0 !important; + white-space:nowrap !important; +} +.chords-panel .chord-filter-actions{display:none !important;} + +/* Kafelki: równe światło góra/dół i nazwa razem z diagramem */ +.chord-card{ + display:flex !important; + align-items:center !important; + justify-content:center !important; + padding:16px 10px 16px !important; + min-height:0 !important; +} +.chord-card-figure{ + width:100% !important; + min-height:100% !important; + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:5px !important; + margin:0 auto !important; +} +.chord-card-head.chord-title-box, +.chord-card .chord-title-box{ + width:118px !important; + min-width:118px !important; + max-width:118px !important; + margin:0 auto 2px !important; +} +.chord-card .chord-name, +#chordGrid .chord-name{ + font-size:13.5px !important; + line-height:1.08 !important; + padding:6px 6px !important; + white-space:normal !important; +} +.chord-card .chord-notes, +#chordGrid .chord-notes{ + display:none !important; +} +.chord-card .diagram{ + margin:0 auto !important; +} + +/* Modal: pełniejsza zawartość, białe dźwięki i większy diagram */ +.chord-modal-card{ + padding:18px 14px 18px !important; +} +.modal-chord-figure{ + width:min(96vw,360px) !important; + max-width:360px !important; + gap:8px !important; + margin:0 auto !important; +} +.modal-diagram{ + width:min(345px,92vw) !important; + max-width:345px !important; + height:auto !important; + margin:0 auto !important; +} +.modal-chord-title-box.chord-title-box, +.modal-chord-title-box{ + width:min(345px,92vw) !important; + min-width:0 !important; + max-width:345px !important; + margin:0 auto 6px !important; +} +.modal-chord-title{ + font-size:26px !important; + line-height:1.1 !important; + padding:8px 10px !important; + white-space:normal !important; +} +.modal-chord-sub{ + color:#fff !important; + font-size:15px !important; + line-height:1.18 !important; + padding:7px 9px 8px !important; +} +.modal-chord-sub::before{content:"" !important;} +.modal-notes-label{color:#fff !important;font-weight:700 !important;} + +@media (max-width:430px){ + .chord-card{padding:15px 9px 15px !important;} + .chord-card-head.chord-title-box, + .chord-card .chord-title-box{width:112px !important;min-width:112px !important;max-width:112px !important;} + .chord-card .chord-name,#chordGrid .chord-name{font-size:12.5px !important;padding:6px 5px !important;} + .modal-diagram{width:min(330px,93vw) !important;} + .modal-chord-title-box.chord-title-box,.modal-chord-title-box{width:min(330px,93vw) !important;max-width:330px !important;} + .modal-chord-title{font-size:24px !important;} + .modal-chord-sub{font-size:14px !important;} +} + +/* === EasyTune v27: minimal SVG whitespace and modal title width === */ +:root{ + --chord-diagram-small:150px; +} + +/* Kafelki akordów: cała grupa dokładnie wyśrodkowana, bez nierównego światła z SVG */ +.chord-card{ + padding:16px 10px 16px !important; + display:flex !important; + align-items:center !important; + justify-content:center !important; +} +.chord-card-figure{ + width:var(--chord-diagram-small) !important; + max-width:var(--chord-diagram-small) !important; + min-height:0 !important; + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:2px !important; + margin:0 auto !important; + padding:0 !important; +} +.chord-card-head.chord-title-box, +.chord-card .chord-title-box{ + margin:0 auto !important; +} +.chord-card .diagram{ + width:var(--chord-diagram-small) !important; + max-width:var(--chord-diagram-small) !important; + margin:0 auto !important; + padding:0 !important; + display:block !important; + overflow:visible !important; +} + +/* Modal akordu: nazwa nie wychodzi poza modal, diagram bez pustego dołu */ +.modal-chord-figure{ + width:min(96vw,360px) !important; + max-width:360px !important; + gap:8px !important; + align-items:center !important; +} +.modal-chord-title-box.chord-title-box, +.modal-chord-title-box{ + width:80% !important; + min-width:0 !important; + max-width:80% !important; + box-sizing:border-box !important; + margin:0 auto 4px !important; +} +.modal-chord-title, +.modal-chord-sub{ + box-sizing:border-box !important; + overflow-wrap:anywhere !important; + word-break:normal !important; +} +.modal-diagram{ + width:min(350px,94vw) !important; + max-width:350px !important; + margin:0 auto !important; + padding:0 !important; + display:block !important; + overflow:visible !important; +} + +@media (max-width:430px){ + :root{--chord-diagram-small:146px;} + .chord-card{padding:15px 9px 15px !important;} + .chord-card-figure{gap:2px !important;} + .modal-chord-title-box.chord-title-box, + .modal-chord-title-box{width:80% !important;max-width:80% !important;} + .modal-diagram{width:min(336px,94vw) !important;max-width:336px !important;} +} + + +/* === EasyTune v28: modal centering, chord tile balance, transpose layout polish === */ +/* Modal akordu: usuń optyczny lewy margines, wyśrodkuj całą figurę i powiększ użyteczną przestrzeń */ +.chord-modal-card{ + padding:14px 10px 16px !important; + align-items:center !important; + justify-content:center !important; + text-align:center !important; +} +#chord-modal-content{ + width:100% !important; + display:flex !important; + align-items:center !important; + justify-content:center !important; + text-align:center !important; +} +.modal-chord-figure{ + width:min(96vw,380px) !important; + max-width:380px !important; + margin:0 auto !important; + padding:0 !important; + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:8px !important; + text-align:center !important; +} +.modal-chord-title-box.chord-title-box, +.modal-chord-title-box{ + width:80% !important; + max-width:304px !important; + min-width:0 !important; + margin:0 auto 3px !important; + align-self:center !important; +} +.modal-diagram{ + width:min(366px,94vw) !important; + max-width:366px !important; + margin:0 auto !important; + align-self:center !important; + transform:translateX(0) !important; +} +.chord-legend{ + width:min(304px,80%) !important; + max-width:304px !important; + margin:4px auto 0 !important; + align-self:center !important; +} + +/* Kafelki akordów: więcej górnego światła i mniejsza przerwa nazwa–diagram */ +.chord-card{ + padding:20px 10px 16px !important; + display:flex !important; + align-items:center !important; + justify-content:center !important; +} +.chord-card-figure{ + gap:0 !important; + align-items:center !important; + justify-content:center !important; + margin:0 auto !important; +} +.chord-card-head.chord-title-box, +.chord-card .chord-title-box{ + margin:0 auto -1px !important; +} +.chord-card .diagram{ + margin:-1px auto 0 !important; +} + +/* Transpozycja: przyciski i podpisy zgodne z resztą kart */ +.view-head .view-title{ + text-align:center !important; + justify-self:center !important; +} +.form-label-row{ + display:flex !important; + align-items:center !important; + justify-content:space-between !important; + gap:12px !important; + margin:0 0 8px !important; +} +.form-label-row .form-label{ + margin:0 !important; +} +.icon-action{ + display:inline-flex !important; + align-items:center !important; + justify-content:center !important; + gap:7px !important; + min-height:34px !important; + padding:7px 12px !important; + border-radius:999px !important; + white-space:nowrap !important; +} +.icon-action span[aria-hidden="true"]{ + font-size:14px !important; + line-height:1 !important; +} +.transpose-section-label{ + display:block !important; + margin:14px 0 8px !important; + text-align:left !important; +} +.transpose-controls{ + margin-top:0 !important; +} +.transpose-value span{display:none !important;} +.transpose-reset-row{ + display:flex !important; + justify-content:center !important; + align-items:center !important; + margin-top:12px !important; +} +.transpose-reset-row .ghost-btn{ + min-width:116px !important; +} +.output-actions{ + display:flex !important; + justify-content:center !important; + margin-top:12px !important; +} +.output-actions .primary-btn{ + min-width:160px !important; +} + +@media (max-width:430px){ + .chord-card{padding:19px 9px 15px !important;} + .modal-diagram{width:min(350px,94vw) !important;max-width:350px !important;} + .modal-chord-title-box.chord-title-box,.modal-chord-title-box{max-width:294px !important;} + .chord-legend{width:min(294px,80%) !important;max-width:294px !important;} + .form-label-row{gap:8px !important;} + .icon-action{padding:7px 10px !important;font-size:12px !important;} +} + +/* === EasyTune v29: chord modal centering fix === + Przyczyną optycznej pustki z lewej strony była kombinacja szerokiego viewBoxu SVG + z pozycją gryfu i dodatkowymi szerokościami kontenerów. Ten blok wymusza jeden, + wyśrodkowany tor: tytuł → diagram → legenda. */ +.chord-modal-card{ + padding:22px 10px 14px !important; + display:flex !important; + align-items:center !important; + justify-content:center !important; + text-align:center !important; + overflow:hidden !important; +} +#chord-modal-content{ + width:100% !important; + max-width:100% !important; + margin:0 auto !important; + padding:0 !important; + display:flex !important; + justify-content:center !important; + align-items:center !important; + text-align:center !important; +} +.modal-chord-figure{ + width:min(92vw,340px) !important; + max-width:340px !important; + margin:0 auto !important; + padding:0 !important; + display:flex !important; + flex-direction:column !important; + align-items:center !important; + justify-content:center !important; + gap:9px !important; + transform:none !important; + left:auto !important; + right:auto !important; +} +.modal-chord-title-box.chord-title-box, +.modal-chord-title-box{ + width:80% !important; + max-width:272px !important; + min-width:0 !important; + margin:0 auto !important; + align-self:center !important; + box-sizing:border-box !important; +} +.modal-diagram{ + width:min(340px,92vw) !important; + max-width:340px !important; + margin:0 auto !important; + padding:0 !important; + display:block !important; + align-self:center !important; + transform:none !important; + overflow:visible !important; +} +.chord-legend{ + width:min(340px,92vw) !important; + max-width:340px !important; + margin:2px auto 0 !important; + padding-left:24px !important; + box-sizing:border-box !important; + align-self:center !important; +} +.chord-legend span{ + white-space:nowrap !important; +} +@media (max-width:430px){ + .chord-modal-card{padding:22px 8px 14px !important;} + .modal-chord-figure{width:min(94vw,330px) !important;max-width:330px !important;gap:8px !important;} + .modal-diagram{width:min(330px,94vw) !important;max-width:330px !important;} + .modal-chord-title-box.chord-title-box, + .modal-chord-title-box{width:80% !important;max-width:264px !important;} + .chord-legend{width:min(330px,94vw) !important;max-width:330px !important;padding-left:24px !important;} +} + +/* === EasyTune v30: drobne korekty tekstów i transpozycji === */ +.tool-card .tool-copy{ + margin-left:8px !important; +} +@media (max-width:430px){ + .tool-card .tool-copy{margin-left:6px !important;} +} +.result-label-row{ + justify-content:flex-start !important; + align-items:center !important; + gap:8px !important; + margin-bottom:8px !important; +} +.result-label-row .form-label{ + margin:0 !important; +} +.info-dot{ + width:20px !important; + height:20px !important; + border-radius:50% !important; + border:1px solid rgba(234,149,22,.72) !important; + background:rgba(234,149,22,.12) !important; + color:#f5b35a !important; + display:inline-flex !important; + align-items:center !important; + justify-content:center !important; + padding:0 !important; + font-size:12px !important; + line-height:1 !important; + font-weight:700 !important; + font-family:inherit !important; + cursor:help !important; +} + +/* === EasyTune v31: transpose result info and clear button polish === */ +.result-label-row{ + position:relative !important; + display:flex !important; + align-items:center !important; + justify-content:center !important; + padding-right:30px !important; +} +.result-label-row .info-dot{ + position:absolute !important; + right:0 !important; + top:50% !important; + transform:translateY(-50%) !important; +} +#clearSong.small-action{ + gap:0 !important; +} + + +/* === EasyTune v33: transposition subtitle alignment and no-wrap song scaling === */ +#songInput, +#songOutput{ + font-size:14px; + transition:font-size .12s ease; +} +.song-input{ + white-space:pre; + overflow:auto; + word-break:normal; +} +.output-box{ + white-space:pre; + overflow:auto; + word-break:normal; +} +.output-line{ + white-space:pre; + min-width:max-content; +} +.transpose-section-label, +.result-label-row, +.form-label-row{ + text-align:left !important; +} +.result-label-row{ + justify-content:flex-start !important; + position:relative; +} +.result-label-row .info-dot{ + margin-left:auto !important; +} + +/* EasyTune v35 — metronom: jeden system synchronizacji, bez podwójnego ruchu */ +.metro-clean-main{ + display:grid !important; + gap:14px !important; +} +.metro-clean-visual{order:1 !important;} +.metro-clean-beats{order:2 !important;} +.metro-clean-meta{order:3 !important;} +.metro-clean-actions{order:4 !important;} + +/* Wyłączamy ciągłe animacje, które przesuwały fazę względem kliknięcia. */ +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual::before{ + animation:none !important; +} +.metro-clean-pendulum{ + transform:translateX(-50%) rotate(0deg) !important; +} +.metro-clean-visual.beat-hit, +.metro-clean-visual.beat-hit::before{ + animation:none !important; + box-shadow:inherit !important; +} +/* Zostaje tylko krótki rozbłysk na akcencie. */ +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .18s ease-out 1 !important; +} +.metro-clean-visual.accent-hit{ + border-color:rgba(234,149,22,.82) !important; + box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 0 0 3px rgba(234,149,22,.16),0 0 60px rgba(234,149,22,.22),0 24px 60px rgba(0,0,0,.40) !important; +} + + +/* EasyTune v36 — metronom: układ i jedna synchronizacja wahadła */ +.metro-clean-main{ + display:grid !important; + gap:14px !important; +} +.metro-clean-meta{order:1 !important;} +.metro-clean-visual{order:2 !important;} +.metro-clean-beats{order:3 !important;} +.metro-clean-actions{order:4 !important;} + +/* Przywrócone wahadło: jedyny ciągły ruch. Bez pulsowania koła. */ +.metro-clean-visual::before, +.metro-clean-visual.beat-hit, +.metro-clean-visual.beat-hit::before{ + animation:none !important; +} +.metro-clean-pendulum{ + animation:metroCleanSwing var(--metro-duration, 600ms) ease-in-out infinite alternate paused !important; + transform:translateX(-50%) rotate(-38deg); +} +.metro-clean-visual.running .metro-clean-pendulum{ + animation-play-state:running !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .18s ease-out 1 !important; +} + +/* EasyTune v37 — metronom: przywrócone wahadło + równy pionowy rytm */ +.metro-clean-main{ + display:grid !important; + gap:20px !important; + align-items:center !important; + justify-items:center !important; +} +.metro-clean-meta{ + order:1 !important; + margin:0 auto !important; +} +.metro-clean-visual{ + order:2 !important; + margin:0 auto !important; +} +.metro-clean-beats{ + order:3 !important; + margin:0 auto !important; +} +.metro-clean-actions{ + margin-top:20px !important; + display:flex !important; + justify-content:center !important; +} +/* Nadpisanie wcześniejszego animation:none z v35: wahadło ma się ruszać prawo-lewo. */ +.metro-clean-visual .metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum{ + animation-name:metroCleanSwing !important; + animation-duration:var(--metro-duration, 600ms) !important; + animation-timing-function:ease-in-out !important; + animation-iteration-count:infinite !important; + animation-direction:alternate !important; + animation-fill-mode:both !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual .metro-clean-pendulum{ + animation-play-state:paused !important; +} +.metro-clean-visual.running .metro-clean-pendulum{ + animation-play-state:running !important; +} +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + transform:translateX(-50%) rotate(0deg) !important; +} +/* Dalej bez pulsowania tarczy — zostaje tylko krótki rozbłysk akcentu. */ +.metro-clean-visual.beat-hit, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .18s ease-out 1 !important; +} + +/* EasyTune v38 — metronom: ruch wahadła sterowany tylko JS, bez zdublowanych animacji CSS */ +.metro-clean-visual .metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transition:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-main{ + gap:24px !important; +} +.metro-clean-meta{ + order:1 !important; +} +.metro-clean-visual{ + order:2 !important; +} +.metro-clean-beats{ + order:3 !important; + margin-top:2px !important; + margin-bottom:6px !important; +} +.metro-clean-actions{ + order:4 !important; + margin-top:18px !important; +} + + +/* EasyTune v39 — metronom: czysty układ i ruch wskazówki sterowany tylko JS */ +.metro-clean-main{ + display:grid !important; + grid-template-areas: + "meta" + "visual" + "beats" !important; + gap:24px !important; + align-items:center !important; + justify-items:center !important; +} +.metro-clean-meta{grid-area:meta !important; order:1 !important; margin:0 auto !important; width:min(100%, 520px) !important;} +.metro-clean-visual{grid-area:visual !important; order:2 !important; margin:0 auto !important;} +.metro-clean-beats{grid-area:beats !important; order:3 !important; margin:0 auto 0 !important;} +.metro-clean-actions{margin-top:24px !important; display:flex !important; justify-content:center !important;} + +.metro-clean-visual, +.metro-clean-visual::before, +.metro-clean-visual.beat-hit, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .18s ease-out 1 !important; +} +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transition:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + transform:translateX(-50%) rotate(0deg) !important; +} + +/* EasyTune v40 — metronome: only JS moves the pendulum; no circle pulse, no CSS swing */ +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum{ + animation:none !important; + transition:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual::before, +.metro-clean-visual.beat-hit, +.metro-clean-visual.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .18s ease-out 1 !important; +} +.metro-clean-main{ + display:grid !important; + gap:18px !important; +} +.metro-clean-meta{order:1 !important;} +.metro-clean-visual{order:2 !important;} +.metro-clean-beats{order:3 !important; margin-top:2px !important; margin-bottom:2px !important;} +.metro-clean-actions{order:4 !important; margin-top:4px !important;} + +/* EasyTune v41 — metronome final sync overrides */ +.metro-clean-visual::before, +.metro-clean-visual.beat-hit, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .18s ease-out 1 !important; +} +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transform-origin:50% 100% !important; +} + +/* EasyTune v42 — metronome endpoint sync: no CSS swing or circle pulse */ +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual::before, +.metro-clean-visual.beat-hit, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .17s ease-out 1 !important; +} +.metro-clean-main{ + gap:20px !important; +} +.metro-clean-beats{ + margin-top:6px !important; + margin-bottom:8px !important; +} + + +/* EasyTune v43 — final metronome sync CSS: JS controls needle, no circle pulse */ +.metro-clean-visual, +.metro-clean-visual::before, +.metro-clean-visual.beat-hit, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .18s ease-out 1 !important; +} +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + transition:none !important; +} + +/* EasyTune v45 — metronome sync fix: no frame flash, no circle pulse, JS-only needle */ +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transition:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual, +.metro-clean-visual.beat-hit, +.metro-clean-visual.running.beat-hit{ + animation:none !important; +} +.metro-clean-visual.beat-hit, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.accent-hit{ + border-color:rgba(234,149,22,.24) !important; + box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; +} +.metro-clean-visual::before, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .14s ease-out 1 !important; + border-color:rgba(234,149,22,.86) !important; +} + + +/* EasyTune v46 — hard metronome safety: no frame flash, no CSS swing, JS-only needle */ +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transition:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual.beat-hit, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.accent-hit{ + border-color:rgba(234,149,22,.24) !important; + box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; + animation:none !important; +} +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .14s ease-out 1 !important; +} + +/* EasyTune v54 — mobile metronome fit */ +@media (max-width: 430px){ + .metro-clean-screen{ + padding:12px 10px calc(12px + env(safe-area-inset-bottom, 0px)) !important; + } + .metro-clean-main{ + gap:10px !important; + } + .metro-clean-visual{ + min-height:min(42vh,300px) !important; + border-radius:18px !important; + } + .metro-clean-pendulum{ + top:54px !important; + height:165px !important; + } + .metro-clean-bpm strong{ + font-size:clamp(56px,17vw,78px) !important; + } + .metro-clean-beats{ + min-height:52px !important; + padding:10px 8px !important; + gap:8px !important; + } + .metro-clean-meta{ + gap:8px !important; + } + .metro-clean-meta button{ + min-height:54px !important; + } + .metro-clean-actions .primary-btn{ + min-height:50px !important; + font-size:17px !important; + } +} +@media (max-width: 430px) and (max-height: 760px){ + .metro-clean-visual{ + min-height:min(36vh,250px) !important; + } + .metro-clean-pendulum{ + top:44px !important; + height:140px !important; + } + .metro-clean-meta button{ + min-height:50px !important; + padding:7px 4px !important; + } + .metro-clean-meta strong{ + font-size:15px !important; + } +} + +/* EasyTune v47 — no frame flash; JS-only needle */ +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transition:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual.beat-hit, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.accent-hit{ + border-color:rgba(234,149,22,.24) !important; + box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; + animation:none !important; +} +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} + +/* EasyTune v48 — metronome: endpoint-only light, no frame/circle pulse */ +.metro-clean-visual, +.metro-clean-visual.beat-hit, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.accent-hit{ + animation:none !important; + border-color:rgba(234,149,22,.24) !important; + box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; +} +.metro-clean-visual::before, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .14s ease-out 1 !important; + border-color:rgba(234,149,22,.86) !important; +} +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transform-origin:50% 100% !important; +} + +/* EasyTune v50 — twardy stan początkowy wskazówki: maksymalny lewy wychył. + JS steruje ruchem; CSS nie może przywracać pionu ani pulsowania ramki. */ +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + transform:translateX(-50%) rotate(-38deg) !important; +} +.metro-clean-visual, +.metro-clean-visual.beat-hit, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.accent-hit{ + animation:none !important; + border-color:rgba(234,149,22,.24) !important; + box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; +} +.metro-clean-visual::before, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .14s ease-out 1 !important; + border-color:rgba(234,149,22,.86) !important; +} + +/* EasyTune v51 — final metronome CSS guard: no CSS swing/pulse, idle needle left */ +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transition:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + transform:translateX(-50%) rotate(-38deg) !important; +} +.metro-clean-visual, +.metro-clean-visual.beat-hit, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.accent-hit{ + animation:none !important; + border-color:rgba(234,149,22,.24) !important; + box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; +} +.metro-clean-visual::before, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .14s ease-out 1 !important; + border-color:rgba(234,149,22,.86) !important; +} + + +/* EasyTune v52 — metronome sync guard */ +.metro-clean-pendulum, +.metro-clean-visual.running .metro-clean-pendulum, +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + animation:none !important; + transition:none !important; + transform-origin:50% 100% !important; +} +.metro-clean-visual:not(.running) .metro-clean-pendulum{ + transform:translateX(-50%) rotate(-38deg) !important; +} +.metro-clean-visual, +.metro-clean-visual.beat-hit, +.metro-clean-visual.running.beat-hit, +.metro-clean-visual.accent-hit{ + animation:none !important; + border-color:rgba(234,149,22,.24) !important; + box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 24px 60px rgba(0,0,0,.35) !important; +} +.metro-clean-visual::before, +.metro-clean-visual.beat-hit::before, +.metro-clean-visual.running.beat-hit::before{ + animation:none !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .14s ease-out 1 !important; + border-color:rgba(234,149,22,.86) !important; +} + +/* EasyTune v53 — explicit visual durations used by metronome sync compensation */ +.metro-clean-beats .beat, +.metro-clean-beats .beat-number{ + transition:transform .08s ease, background-color .08s ease, color .08s ease, box-shadow .08s ease !important; +} +.metro-clean-visual.accent-hit::before{ + animation:metroAccentFlash .14s ease-out 1 !important; +}