:root { --bg: #f4f3fb; --surface: #ffffff; --surface-alt: #f7f6fd; --text: #201f2b; --muted: #6b6878; --border: #e4e1f0; --accent: #6c4cf0; --accent-2: #ff5f8f; --accent-contrast: #ffffff; --danger: #d1453d; --danger-bg: #fdecea; --success: #1e8e5a; --success-bg: #e8f7ef; --radius: 14px; --radius-sm: 8px; --shadow: 0 1px 2px rgba(32, 31, 43, 0.04), 0 4px 16px rgba(32, 31, 43, 0.06); font-family: "Segoe UI", system-ui, -apple-system, Roboto, sans-serif; } @media (prefers-color-scheme: dark) { :root { --bg: #15131f; --surface: #1e1c2b; --surface-alt: #262436; --text: #ece9f7; --muted: #a29fb5; --border: #322f42; --accent: #9884f5; --accent-2: #ff85ac; --accent-contrast: #15131f; --danger: #ef6b64; --danger-bg: #3a201f; --success: #4fd190; --success-bg: #163828; --shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 8px 24px rgba(0, 0, 0, 0.35); } } :root[data-theme="dark"] { --bg: #15131f; --surface: #1e1c2b; --surface-alt: #262436; --text: #ece9f7; --muted: #a29fb5; --border: #322f42; --accent: #9884f5; --accent-2: #ff85ac; --accent-contrast: #15131f; --danger: #ef6b64; --danger-bg: #3a201f; --success: #4fd190; --success-bg: #163828; } :root[data-theme="light"] { --bg: #f4f3fb; --surface: #ffffff; --surface-alt: #f7f6fd; --text: #201f2b; --muted: #6b6878; --border: #e4e1f0; --accent: #6c4cf0; --accent-2: #ff5f8f; --accent-contrast: #ffffff; --danger: #d1453d; --danger-bg: #fdecea; --success: #1e8e5a; --success-bg: #e8f7ef; } * { box-sizing: border-box; } body { margin: 0; background: var(--bg); color: var(--text); -webkit-font-smoothing: antialiased; } /* ---------- Header / nav ---------- */ header.app-header { position: sticky; top: 0; z-index: 20; background: var(--surface); border-bottom: 1px solid var(--border); padding: 0 1.25rem; } nav#main-nav { max-width: 1100px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 60px; flex-wrap: wrap; } .brand { font-weight: 700; font-size: 1.15rem; letter-spacing: 0.01em; background: linear-gradient(135deg, var(--accent), var(--accent-2)); -webkit-background-clip: text; background-clip: text; color: transparent; display: flex; align-items: center; gap: 0.4rem; margin-right: auto; text-decoration: none; } .brand .brand-dot { -webkit-text-fill-color: initial; color: var(--accent); } .nav-controls { display: flex; align-items: center; gap: 0.5rem; } .nav-toggle { display: none; background: transparent; border: 1px solid var(--border); color: var(--text); border-radius: var(--radius-sm); padding: 0.4rem 0.6rem; font-size: 1.1rem; line-height: 1; } .nav-menu { display: flex; align-items: center; justify-content: space-between; flex: 1 1 auto; gap: 1rem; flex-wrap: wrap; } .nav-links { display: flex; align-items: center; gap: 1.4rem; flex-wrap: wrap; } .nav-links a { color: var(--muted); text-decoration: none; font-weight: 500; font-size: 0.95rem; padding: 0.3rem 0; border-bottom: 2px solid transparent; } .nav-links a.active { color: var(--accent); border-bottom-color: var(--accent); } .nav-links a:hover { color: var(--accent); } .nav-user { display: flex; align-items: center; gap: 0.9rem; color: var(--muted); font-size: 0.88rem; margin-left: auto; } .nav-profile { position: relative; } .nav-profile-trigger { display: flex; align-items: center; gap: 0.5rem; background: transparent; border: none; padding: 0.3rem 0.4rem; border-radius: var(--radius-sm); color: var(--text); font-weight: 500; font-size: 0.88rem; cursor: pointer; } .nav-profile-trigger:hover { background: var(--surface-alt); } .nav-profile-trigger span { color: var(--text); } .nav-profile-dropdown { display: none; position: absolute; top: calc(100% + 0.4rem); right: 0; min-width: 180px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow); padding: 0.35rem; flex-direction: column; z-index: 30; } .nav-profile-dropdown.open { display: flex; } .nav-profile-dropdown a { color: var(--text); text-decoration: none; font-weight: 500; font-size: 0.9rem; padding: 0.5rem 0.6rem; border-radius: var(--radius-sm); } .nav-profile-dropdown a:hover { background: var(--surface-alt); } #theme-toggle { border-radius: 999px; width: 2rem; height: 2rem; padding: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 1rem; line-height: 1; } /* ---------- Avatars ---------- */ .avatar { border-radius: 999px; object-fit: cover; flex: 0 0 auto; } .avatar-sm { width: 1.7rem; height: 1.7rem; } .avatar-lg { width: 4.5rem; height: 4.5rem; font-size: 1.4rem; } .avatar-initials { display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: #fff; font-weight: 700; font-size: 0.75rem; } /* ---------- Profile page ---------- */ .profile-header { display: flex; align-items: center; gap: 1.25rem; margin-bottom: 1rem; } .stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 0.75rem; } .stat-tile { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); padding: 1rem; text-align: center; } .stat-value { font-size: 1.8rem; font-weight: 700; background: linear-gradient(135deg, var(--accent), var(--accent-2)); -webkit-background-clip: text; background-clip: text; color: transparent; } .stat-label { color: var(--muted); font-size: 0.85rem; margin-top: 0.2rem; } .badge { background: linear-gradient(135deg, var(--accent), var(--accent-2)); color: #fff; border-radius: 999px; padding: 0.1rem 0.55rem; font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.03em; } /* ---------- Layout ---------- */ main { max-width: 1100px; margin: 0 auto; padding: 1.75rem 1.25rem 4rem; } h1 { font-size: 1.65rem; margin: 0 0 0.25rem; letter-spacing: -0.01em; } h2 { font-size: 1.15rem; margin: 2.25rem 0 0.75rem; } h3 { font-size: 1rem; margin: 0 0 0.5rem; } .page-subtitle { color: var(--muted); margin: 0 0 1.5rem; } .section-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; margin: 2.25rem 0 0.75rem; } .section-header h2 { margin: 0; } .search-bar { position: relative; max-width: 360px; margin: 0 0 1rem; } .search-bar input { padding-left: 2.2rem; } .search-icon { position: absolute; left: 0.65rem; top: 50%; transform: translateY(-50%); color: var(--muted); display: flex; pointer-events: none; } /* ---------- Cards / grids ---------- */ .card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.9rem; } .card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.15rem; margin-bottom: 0.75rem; box-shadow: var(--shadow); } .card-grid .card { margin-bottom: 0; } .card-header { display: flex; justify-content: space-between; align-items: flex-start; gap: 0.75rem; } .card-title { font-weight: 600; font-size: 1.02rem; } .card-subtitle { color: var(--muted); font-size: 0.88rem; margin-top: 0.1rem; } /* ---------- Song card (repertoire) ---------- */ .song-card { display: flex; gap: 0.9rem; align-items: flex-start; } .song-thumb { flex: 0 0 auto; width: 96px; height: 72px; border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-alt); display: flex; align-items: center; justify-content: center; position: relative; } .song-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; } .song-thumb.placeholder { color: var(--muted); font-size: 1.5rem; } .song-thumb a.play-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.15); color: #fff; font-size: 1.4rem; text-decoration: none; opacity: 0; transition: opacity 0.15s ease; } .song-thumb:hover a.play-overlay { opacity: 1; } /* ---------- Tutorial cards (embedded links per instrument) ---------- */ .tutorial-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.7rem; margin-top: 0.6rem; } .tutorial-card { display: flex; flex-direction: column; gap: 0.35rem; } .tutorial-thumb { width: 100%; height: 84px; } .tutorial-meta { font-size: 0.8rem; } .tutorial-label { margin-top: 0.2rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tutorial-label a { color: var(--accent); text-decoration: none; } .tutorial-text-wrap { display: flex; flex-direction: column; gap: 0.25rem; } .tutorial-text { margin: 0; max-height: 4.5em; overflow: hidden; white-space: pre-wrap; word-break: break-word; font-family: ui-monospace, Consolas, monospace; font-size: 0.8rem; background: var(--surface-alt, rgba(127, 127, 127, 0.08)); border-radius: 6px; padding: 0.4rem 0.5rem; } .tutorial-text.expanded { max-height: none; } .tutorial-text-toggle { align-self: flex-start; font-size: 0.75rem; padding: 0.15rem 0.5rem; } .song-body { flex: 1 1 auto; min-width: 0; } .song-links { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; } .pill-link { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.78rem; font-weight: 600; text-decoration: none; padding: 0.25rem 0.65rem; border-radius: 999px; border: 1px solid var(--border); color: var(--text); background: var(--surface-alt); } .pill-link.youtube { color: #d1272b; border-color: #f3c8c9; } .pill-link.spotify { color: #1db954; border-color: #bdeccb; } @media (prefers-color-scheme: dark) { .pill-link.youtube { border-color: #5a2b2b; } .pill-link.spotify { border-color: #205934; } } .calendar-menu { position: relative; display: inline-block; } .calendar-menu > summary { list-style: none; cursor: pointer; } .calendar-menu > summary::-webkit-details-marker { display: none; } .calendar-menu-options { position: absolute; top: calc(100% + 0.3rem); left: 0; z-index: 20; display: flex; flex-direction: column; min-width: 9rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); overflow: hidden; } .calendar-menu-options a { padding: 0.45rem 0.75rem; font-size: 0.85rem; color: var(--text); text-decoration: none; } .calendar-menu-options a:hover { background: var(--surface-alt); } /* ---------- Tags (tutorials / instruments) ---------- */ .tag-list { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.6rem; } .tag { background: var(--surface-alt); border: 1px solid var(--border); border-radius: 999px; padding: 0.2rem 0.65rem; font-size: 0.78rem; } .tag a { color: var(--accent); text-decoration: none; font-weight: 500; } .empty { color: var(--muted); font-style: italic; font-size: 0.92rem; } /* ---------- Forms ---------- */ form.inline-form { display: flex; flex-wrap: wrap; gap: 0.7rem; margin-top: 0.85rem; align-items: flex-end; } form.inline-form label { display: flex; flex-direction: column; font-size: 0.78rem; color: var(--muted); gap: 0.3rem; flex: 1 1 160px; } form.stacked-form { display: flex; flex-direction: column; gap: 0.7rem; max-width: 480px; } form.stacked-form label { display: flex; flex-direction: column; font-size: 0.8rem; color: var(--muted); gap: 0.3rem; } /* ---------- Title autocomplete (add song) ---------- */ .autocomplete-wrapper { position: relative; } .autocomplete-dropdown { position: absolute; top: 100%; left: 0; right: 0; margin-top: 0.25rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow); max-height: 260px; overflow-y: auto; z-index: 30; } .autocomplete-item { display: flex; align-items: center; gap: 0.6rem; padding: 0.45rem 0.6rem; cursor: pointer; font-size: 0.85rem; } .autocomplete-item:hover, .autocomplete-item.active { background: var(--surface-alt); } .autocomplete-item img, .autocomplete-thumb-placeholder { width: 32px; height: 32px; border-radius: 6px; object-fit: cover; flex: 0 0 auto; } .autocomplete-thumb-placeholder { display: flex; align-items: center; justify-content: center; background: var(--surface-alt); color: var(--muted); } input, select, textarea { font: inherit; padding: 0.5rem 0.65rem; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); width: 100%; } textarea { resize: vertical; min-height: 4.5em; } input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: 1px; } button { font: inherit; font-weight: 600; padding: 0.5rem 1rem; border: none; border-radius: 999px; background: var(--accent); color: var(--accent-contrast); cursor: pointer; white-space: nowrap; } button:hover { filter: brightness(1.07); } button.secondary { background: transparent; border: 1px solid var(--border); color: var(--text); } button.icon-btn { display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.35rem 0.55rem; font-size: 0.85rem; } button.icon-btn svg { flex: 0 0 auto; } button.danger { background: var(--danger); color: #fff; } button:disabled { opacity: 0.5; cursor: not-allowed; } .panel { background: var(--surface-alt); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.15rem; margin-top: 0.75rem; } /* ---------- Suggestions / voting ---------- */ .vote-tally { display: flex; gap: 1rem; font-size: 0.88rem; margin-top: 0.5rem; font-weight: 600; } .vote-tally .approve { color: var(--success); } .vote-tally .reject { color: var(--danger); } .vote-list { margin-top: 0.75rem; border-top: 1px solid var(--border); padding-top: 0.6rem; display: flex; flex-direction: column; gap: 0.5rem; } .vote-item { font-size: 0.85rem; background: var(--surface-alt); border-radius: var(--radius-sm); padding: 0.45rem 0.65rem; } .vote-item .voter { font-weight: 600; } .vote-item.approve { border-left: 3px solid var(--success); } .vote-item.reject { border-left: 3px solid var(--danger); } .suggestion-note { margin-top: 0.5rem; font-size: 0.9rem; background: var(--surface-alt); border-radius: var(--radius-sm); padding: 0.5rem 0.7rem; } .youtube-embed { margin-top: 0.75rem; aspect-ratio: 16 / 9; width: 100%; max-width: 480px; border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-alt); } .youtube-embed iframe { width: 100%; height: 100%; border: 0; } /* ---------- History timeline ---------- */ .timeline-concert { margin-bottom: 1.5rem; } .timeline-songs { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 0.5rem; } .timeline-song-row { display: flex; align-items: flex-start; gap: 0.9rem; background: var(--surface-alt); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.7rem 0.9rem; } .timeline-song-row .row-index { margin-top: 0.15rem; } .timeline-song-main { flex: 1 1 auto; min-width: 0; } .timeline-song-title { font-weight: 600; } .timeline-embed { width: 200px; max-width: 200px; flex: 0 0 auto; margin-top: 0; } .timeline-no-embed { flex: 0 0 auto; width: 200px; text-align: center; margin: 0; } /* ---------- Setlist ---------- */ .setlist-columns { display: grid; grid-template-columns: 1fr 1.4fr; gap: 1.25rem; align-items: start; } .setlist-section { margin-top: 1.5rem; } .setlist-section h3 { margin-bottom: 0.5rem; } .setlist-rows { display: flex; flex-direction: column; gap: 0.5rem; } .setlist-row { display: flex; align-items: center; gap: 0.6rem; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.55rem 0.75rem; } .setlist-row .row-index { font-weight: 700; color: var(--muted); width: 1.5rem; text-align: center; flex: 0 0 auto; } .setlist-row .row-main { flex: 1 1 auto; min-width: 0; } .setlist-row .row-title { font-weight: 600; } .setlist-row .row-artist { color: var(--muted); font-size: 0.85rem; } .setlist-row .row-note-input { flex: 1 1 160px; } .setlist-row .row-actions { display: flex; gap: 0.25rem; flex: 0 0 auto; } ol.setlist { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.5rem; } ol.setlist li { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.6rem 0.8rem; } .note { color: var(--muted); font-size: 0.85rem; display: block; margin-top: 0.15rem; } /* ---------- Misc ---------- */ .error-banner { background: var(--danger-bg); color: var(--danger); border: 1px solid var(--danger); border-radius: var(--radius-sm); padding: 0.6rem 0.9rem; margin-bottom: 1.25rem; font-size: 0.9rem; } a.back-link { color: var(--muted); text-decoration: none; font-size: 0.9rem; display: inline-block; margin-bottom: 1rem; } a.back-link:hover { color: var(--accent); } /* ---------- Calendar (availability) ---------- */ /* button. prefix needed so this outweighs button.icon-btn's own `display: inline-flex` (same 720px-and-below rule further down). */ button.calendar-filters-toggle, button.calendar-filters-close { display: none; } .calendar-header-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; } .calendar-layout { display: grid; grid-template-columns: 220px 1fr; gap: 1.25rem; align-items: start; } .calendar-filters { position: sticky; top: 76px; } .calendar-people-list { display: flex; flex-direction: column; gap: 0.4rem; } .person-toggle { display: flex; align-items: center; gap: 0.5rem; font-size: 0.88rem; cursor: pointer; padding: 0.2rem 0; } .person-toggle.excluded { opacity: 0.4; } .person-dot { width: 10px; height: 10px; border-radius: 999px; flex: 0 0 auto; } .calendar-filters-backdrop { display: none; } .calendar-main { min-width: 0; } .calendar-month-nav { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-bottom: 0.75rem; } .calendar-month-label { font-weight: 600; font-size: 1.05rem; min-width: 10ch; text-align: center; text-transform: capitalize; } .calendar-month-nav button:disabled { opacity: 0.35; cursor: default; } .calendar-header-row { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 0.5rem; color: var(--muted); font-size: 0.8rem; font-weight: 600; text-align: center; margin-bottom: 0.4rem; } .calendar-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 0.5rem; } .cal-cell { position: relative; min-height: 92px; min-width: 0; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface); padding: 0.4rem 0.5rem; font-size: 0.78rem; display: flex; flex-direction: column; gap: 0.25rem; overflow: hidden; } .cal-cell.today { border-color: var(--accent); border-width: 2px; } .cal-cell.empty { background: transparent; border-style: dashed; color: var(--muted); } .cal-cell.has-slot { cursor: pointer; } .cal-cell.has-slot:hover { border-color: var(--accent); } .cal-cell.outside-month { border-style: none; opacity: 0.35; } .cell-date { font-weight: 600; color: var(--muted); } .cell-date .day-num { color: var(--text); font-size: 0.95rem; margin-right: 0.25rem; } .no-slot-label { color: var(--muted); font-style: italic; margin-top: auto; } .cell-time { color: var(--muted); font-size: 0.72rem; } .cell-dots { display: flex; flex-wrap: wrap; gap: 0.2rem; margin-top: auto; } .cell-dot { width: 8px; height: 8px; border-radius: 999px; } .cell-dot.busy { opacity: 0.3; } .cell-count { font-size: 0.72rem; color: var(--muted); align-self: flex-end; } .cal-cell.all-available { background: var(--success-bg); border-color: var(--success); } .cal-cell.heat-1 { background: color-mix(in srgb, var(--success-bg) 80%, var(--danger-bg)); } .cal-cell.heat-2 { background: color-mix(in srgb, var(--success-bg) 55%, var(--danger-bg)); } .cal-cell.heat-3 { background: color-mix(in srgb, var(--danger-bg) 55%, var(--success-bg)); } .cal-cell.heat-4 { background: color-mix(in srgb, var(--danger-bg) 80%, var(--success-bg)); } .cal-cell.heat-5 { background: var(--danger-bg); border-color: var(--danger); } .calendar-legend { display: flex; flex-wrap: wrap; gap: 0.9rem; margin-top: 1rem; font-size: 0.8rem; color: var(--muted); } .legend-item { display: flex; align-items: center; gap: 0.4rem; } .legend-dot { width: 10px; height: 10px; border-radius: 999px; display: inline-block; } .legend-dot-all { background: var(--success-bg); border: 1px solid var(--success); } /* ---------- Modal & toast (calendar) ---------- */ .modal-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.45); display: flex; align-items: center; justify-content: center; z-index: 100; padding: 1rem; } .modal-overlay.hidden { display: none; } .modal { position: relative; max-width: 360px; width: 100%; } .modal-close { position: absolute; top: 0.6rem; right: 0.6rem; } .modal-time { margin-top: 0.1rem; } .modal-section { margin-top: 1rem; } .modal-section-title { font-size: 0.8rem; font-weight: 600; margin-bottom: 0.4rem; } .modal-section-title.available { color: var(--success); } .modal-section-title.busy { color: var(--danger); } .modal-people { display: flex; flex-direction: column; gap: 0.35rem; } .modal-person { display: flex; align-items: center; gap: 0.5rem; font-size: 0.88rem; } .toast { position: fixed; bottom: 1.25rem; left: 50%; transform: translateX(-50%); background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow); border-radius: var(--radius-sm); padding: 0.6rem 1rem; font-size: 0.88rem; z-index: 200; max-width: min(90vw, 420px); } .toast.hidden { display: none; } .toast.error { border-color: var(--danger); color: var(--danger); } /* ---------- Responsive / mobile ---------- */ @media (max-width: 720px) { .setlist-columns { grid-template-columns: 1fr; } } @media (max-width: 640px) { nav#main-nav { min-height: 56px; } .nav-toggle { display: inline-flex; } /* Only the brand + theme toggle + hamburger stay in the top row; the rest (page links, account/profile/logout) collapses into one dropdown so the bar doesn't get crowded on a phone-width screen. */ .nav-menu { order: 3; flex-basis: 100%; flex-direction: column; align-items: stretch; gap: 0; max-height: 0; overflow: hidden; transition: max-height 0.25s ease; } .nav-menu.open { max-height: 420px; padding-bottom: 0.6rem; } .nav-links { flex-direction: column; align-items: flex-start; gap: 0.1rem; padding-top: 0.4rem; } .nav-links a { width: 100%; padding: 0.5rem 0; border-bottom: 1px solid var(--border); } .nav-user { flex-direction: column; align-items: stretch; gap: 0; margin-left: 0; } .nav-profile-trigger { width: 100%; padding: 0.5rem 0; border-bottom: 1px solid var(--border); border-radius: 0; } .nav-profile-dropdown { position: static; box-shadow: none; border: none; padding: 0; min-width: 0; } .nav-profile-dropdown a { width: 100%; padding: 0.5rem 0; border-bottom: 1px solid var(--border); border-radius: 0; } main { padding: 1.25rem 0.9rem 3rem; } .card-grid { grid-template-columns: 1fr; } .song-card { flex-wrap: wrap; } .song-thumb { width: 100%; height: 160px; } form.inline-form { flex-direction: column; align-items: stretch; } form.inline-form label { flex: 1 1 auto; } .setlist-row { flex-wrap: wrap; } .setlist-row .row-note-input { flex-basis: 100%; order: 4; } .setlist-row .row-actions { flex-basis: 100%; order: 5; justify-content: flex-end; } .profile-header { flex-direction: column; text-align: center; } button.calendar-filters-toggle, button.calendar-filters-close { display: inline-flex; } .calendar-header-actions { width: 100%; } .calendar-header-actions button { flex: 1 1 auto; white-space: normal; line-height: 1.2; font-size: 0.82rem; } .calendar-layout { grid-template-columns: 1fr; } .calendar-filters { position: fixed; top: 0; bottom: 0; left: 0; width: 260px; max-width: 80vw; z-index: 110; border-radius: 0; transform: translateX(-100%); transition: transform 0.2s ease; overflow-y: auto; } .calendar-filters.open { transform: translateX(0); } .calendar-filters-backdrop { display: none; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.4); z-index: 105; } .calendar-filters-backdrop.open { display: block; } .calendar-header-row { gap: 0.25rem; } .calendar-header-row span:nth-child(n) { font-size: 0.62rem; } .calendar-grid { gap: 0.25rem; } .cal-cell { min-height: 56px; font-size: 0.62rem; padding: 0.3rem 0.25rem; gap: 0.15rem; } /* Per-person names/times don't fit on a phone-width column — the heat color + the "avail/total" count already convey availability at a glance; full detail is one tap away via the day modal. */ .cell-time, .cell-dots { display: none; } .cell-date { display: flex; flex-direction: column; align-items: center; line-height: 1.15; } .cell-date .day-num { margin-right: 0; font-size: 0.85rem; } .cell-badges { position: static; align-self: center; } .cell-count { align-self: center; margin-top: auto; } .timeline-song-row { flex-wrap: wrap; } .timeline-embed, .timeline-no-embed { width: 100%; max-width: none; } } /* ---------- View toggle (suggestions) ---------- */ .view-toggle { display: flex; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; } .view-toggle-btn { background: var(--surface); color: var(--text); border: none; border-radius: 0; padding: 0.45rem 0.9rem; font-size: 0.88rem; cursor: pointer; } .view-toggle-btn + .view-toggle-btn { border-left: 1px solid var(--border); } .view-toggle-btn.active { background: var(--accent); color: var(--accent-contrast); } /* ---------- Swipe / "Vote rapide" view ---------- */ .swipe-header { display: flex; align-items: center; justify-content: space-between; margin: 0 0 1rem; color: var(--muted); font-size: 0.9rem; } .swipe-stack { position: relative; max-width: 380px; height: 420px; margin: 0 auto; } .swipe-card { position: absolute; inset: 0; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); display: flex; flex-direction: column; overflow: hidden; touch-action: none; transform: scale(calc(1 - var(--depth, 0) * 0.04)) translateY(calc(var(--depth, 0) * 10px)); transition: transform 0.2s ease; } .swipe-card-media { position: relative; flex: 1 1 auto; background: var(--surface-alt); min-height: 0; } .swipe-card-media img { width: 100%; height: 100%; object-fit: cover; display: block; } .swipe-card-media .song-thumb.placeholder { width: 100%; height: 100%; font-size: 3rem; } .swipe-card-media .play-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.15); color: #fff; font-size: 2rem; text-decoration: none; opacity: 0; transition: opacity 0.15s ease; } .swipe-card-media:hover .play-overlay { opacity: 1; } .swipe-stamp { position: absolute; top: 1.2rem; padding: 0.3rem 0.7rem; border: 3px solid; border-radius: var(--radius-sm); font-weight: 700; font-size: 1.1rem; letter-spacing: 0.04em; opacity: 0; pointer-events: none; transform: rotate(-12deg); } .swipe-stamp.approve { left: 1.2rem; color: var(--success); border-color: var(--success); } .swipe-stamp.reject { right: 1.2rem; color: var(--danger); border-color: var(--danger); transform: rotate(12deg); } .swipe-card-body { flex: 0 0 auto; padding: 0.9rem 1.1rem; } .swipe-controls { display: flex; justify-content: center; gap: 1.5rem; margin: 1.25rem 0; } .swipe-btn { width: 56px; height: 56px; border-radius: 50%; border: 1px solid var(--border); background: var(--surface); font-size: 1.4rem; cursor: pointer; box-shadow: var(--shadow); } .swipe-btn.approve { color: var(--success); } .swipe-btn.reject { color: var(--danger); } /* ---------- "Mes votes" review modal ---------- */ .modal-wide { max-width: 520px; max-height: 80vh; overflow-y: auto; } .vote-review-row { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.75rem 0.9rem; margin-bottom: 0.6rem; } .vote-review-header { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; } .vote-review-detail { margin-top: 0.75rem; } /* ---------- Admin dashboard ---------- */ .admin-user-list { display: flex; flex-direction: column; gap: 0.6rem; } .admin-user-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 0.6rem 0.85rem; flex-wrap: wrap; } .admin-user-identity { display: flex; align-items: center; gap: 0.75rem; } .admin-user-counts { display: flex; gap: 0.9rem; color: var(--muted); font-size: 0.88rem; white-space: nowrap; } .calendar-person-row { flex-direction: column; align-items: stretch; gap: 0.6rem; } .calendar-feeds { display: flex; flex-direction: column; gap: 0.4rem; } .feed-row { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; background: var(--surface-alt); border-radius: var(--radius-sm); padding: 0.4rem 0.6rem; font-size: 0.88rem; } .add-feed-form input { font-size: 0.85rem; } /* ---------- Répétitions proposées ---------- */ .rehearsal-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; border-bottom: 1px solid var(--border); padding: 0.6rem 0; } .rehearsal-row:last-child { border-bottom: none; } .rehearsal-row.highlight { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; transition: outline-color 3s ease; } .rehearsal-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; } .rehearsal-accepted-by { display: flex; align-items: center; flex-wrap: wrap; gap: 0.3rem 0.5rem; margin: 0.35rem 0 0.6rem; font-size: 0.8rem; } .modal-section .rehearsal-actions { margin-top: 0.5rem; } .rehearsal-accepted-by .avatar-sm { width: 1.3rem; height: 1.3rem; font-size: 0.65rem; } .vote-badge { font-size: 0.85rem; border-radius: var(--radius-sm); padding: 0.35rem 0.6rem; background: var(--surface-alt); } .vote-badge.accept { border-left: 3px solid var(--success); } .vote-badge.reject { border-left: 3px solid var(--danger); } .rehearsal-voted-section { margin-top: 0.75rem; } .rehearsal-voted-section > summary { color: var(--muted); font-size: 0.85rem; cursor: pointer; list-style: none; padding: 0.3rem 0; } .rehearsal-voted-section > summary::-webkit-details-marker { display: none; } .rehearsal-voted-section > summary::before { content: '▸ '; } .rehearsal-voted-section[open] > summary::before { content: '▾ '; } .rehearsal-voted-section .panel { margin-top: 0.4rem; opacity: 0.85; } .cell-badges { position: absolute; top: 0.3rem; right: 0.4rem; display: flex; gap: 0.2rem; font-size: 0.85rem; line-height: 1; } /* Concert/rehearsal markers take priority over the availability heat colors above (same specificity, later in the cascade) — a scheduled date matters more than who's free that day. */ .cal-cell.has-rehearsal { background: color-mix(in srgb, var(--accent) 20%, var(--surface)); border-color: var(--accent); } .cal-cell.has-concert { background: color-mix(in srgb, var(--accent-2) 20%, var(--surface)); border-color: var(--accent-2); } .cal-cell.has-rehearsal.has-concert { background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 20%, var(--surface)), color-mix(in srgb, var(--accent-2) 20%, var(--surface))); } /* ---------- Concerts: upcoming list + detail actions ---------- */ .concert-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; } .concert-row-info { cursor: pointer; flex: 1 1 auto; } .concert-row-actions { display: flex; align-items: center; gap: 0.5rem; flex: 0 0 auto; } .concert-detail-card { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.75rem; flex-wrap: wrap; } /* Icon-only on narrow screens — the emoji glyph alone is enough to convey "modifier"/"supprimer" once space is tight, matching how the nav collapses the same way at this breakpoint. */ @media (max-width: 640px) { .btn-label { display: none; } }