/*
 * This is a manifest file that'll be compiled into application.css.
 *
 * With Propshaft, assets are served efficiently without preprocessing steps. You can still include
 * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard
 * cascading order, meaning styles declared later in the document or manifest will override earlier ones,
 * depending on specificity.
 *
 * Consider organizing styles into separate files for maintainability.
 */

/* ── Live follower surfaces (projector / musician) ──────────────────────────
   Projector = "Classic" look: true black, bold sans-serif, maximum contrast for
   any projector in any lighting. The fit Stimulus controller sizes .projector-lyrics
   to fill the stage; CSS only sets face, weight, colour and layout. */
.follower-body { margin: 0; background: #000; }

.projector-root {
  position: fixed; inset: 0;
  background: var(--proj-bg, #000); color: var(--proj-text, #fff);
  display: flex; flex-direction: column;
  font-family: var(--proj-font, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
}
.musician-root { min-height: 100vh; padding: 2rem; box-sizing: border-box; }

/* The live frame is the flex stage: lyrics vertically placed per church setting, copyright
   pinned to the foot. The frame itself carries --proj-* vars so the operator-preview (which
   renders the same frame) inherits the look too. */
:is(#live-frame, .live-frame) {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: var(--proj-valign, center);
  padding: 6vh 6vw; text-align: center; position: relative;
  background: var(--proj-bg, #000); color: var(--proj-text, #fff);
  font-family: var(--proj-font, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
}
.projector-section { display: flex; flex-direction: column; align-items: center; width: 100%; }

.projector-lyrics { width: 100%; }
.projector-line {
  font-weight: var(--proj-weight, 700); line-height: var(--proj-line-height, 1.15);
  letter-spacing: -0.01em; text-wrap: balance;
  text-transform: var(--proj-lyric-case, none);
}
.projector-line + .projector-line { margin-top: 0.35em; }
/* Invisible copies of every slide of the current song. The fit controller sizes each one to find
   the single text size that fits the whole song; never seen, never takes space. */
.projector-measure {
  position: absolute; left: 0; top: 0; height: 0; overflow: hidden;
  visibility: hidden; pointer-events: none;
}
/* Small "×2" after a line the band repeats. em-based so it scales with the fitted lyric size;
   kept out of the casing transform so it never reads "X2". */
.projector-repeat {
  margin-left: 0.5em; font-size: 0.45em; font-weight: 600; opacity: 0.7;
  vertical-align: middle; text-transform: none; white-space: nowrap;
}

/* Operator preview: a bounded mini-stage showing the live projector frame in place, so the
   operator sees exactly what's on the screen — including the church's projector colours, which
   the inner #live-frame carries as --proj-* vars. */
.projector-preview {
  background: var(--proj-bg, #000); color: var(--proj-text, #fff); aspect-ratio: 16 / 9; position: relative; container-type: size;
  font-family: var(--proj-font, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif);
}
/* The real projector stage is also a size container, so a slide's fixed font size (in cqh) is a
   percentage of the screen height. Scoped to .projector-root: the musician page reuses
   #live-frame as a content-sized band, which size containment would collapse. */
.projector-root :is(#live-frame, .live-frame) { container-type: size; }
.projector-preview :is(#live-frame, .live-frame) { position: static; inset: auto; height: 100%; padding: 4% 5%; }
/* Slide-show previews render a .projector-slide DIRECTLY in the preview box (no #live-frame);
   center and pad it so the slide body sits in the middle and the background image fills the box. */
.projector-preview > .projector-slide {
  position: absolute; inset: 0; padding: 4% 5%; box-sizing: border-box;
}
/* The operator preview uses the SAME fit controller as the real projector, sized to this smaller
   stage — so the text proportions match what the congregation sees (just scaled down). */
/* The blank overlay is position:fixed for the real full-screen projector; inside the operator
   preview it must stay WITHIN the preview box, not cover the whole page. */
.projector-preview .projector-blank { position: absolute; }

.projector-copyright {
  margin-top: 4vh; font-size: clamp(0.8rem, 1.4vw, 1.1rem);
  color: #9aa0a6; letter-spacing: 0.02em; text-align: center; font-weight: 400;
}

/* Title slide TEMPLATE: fixed proportions of the screen (cqh/cqw against the projector stage, a
   size container), not auto-fit, so every title looks consistent. Always vertically centered
   (margin-block:auto) whatever the lyric position setting. Colours follow the church text colour. */
.projector-title { margin-block: auto; justify-content: center; }
.projector-title-content { width: 100%; text-align: center; display: flex; flex-direction: column; align-items: center; }
.projector-title-name {
  max-width: 85%; font-weight: 800; line-height: 1.05; letter-spacing: -0.02em; text-wrap: balance;
  font-size: min(10cqh, 7cqw);
  text-transform: var(--proj-title-case, none);
}
.projector-title-rule {
  width: 8cqw; height: max(2px, 0.5cqh); margin: 4cqh auto 3cqh;
  background: currentColor; opacity: 0.45; border-radius: 9999px;
}
.projector-title-credits { opacity: 0.7; font-weight: 400; }
.projector-title-credit-line { font-size: min(3cqh, 2.2cqw); letter-spacing: 0.02em; }
.projector-title-credit-line + .projector-title-credit-line { margin-top: 0.4em; }

/* Blank: a true-black fill that hides everything (operator pressed Blank). */
.projector-root.is-blanked, .projector-blank { background: #000; }
.projector-blank { position: fixed; inset: 0; }

/* A text slide fills the stage as a column; its body is placed with auto margins per the slide's
   alignment (top/center/bottom × left/center/right). Auto margins (not justify-content) collapse
   to 0 when the text overflows, so the fit controller still measures overflow correctly. */
.projector-slide { width: 100%; flex: 1 1 auto; display: flex; flex-direction: column; }
/* Regular body weight, so the editor's Bold (**text** → <strong>) is visibly heavier on the
   projector. A 600 base rendered as bold in most projector fonts and hid the difference. */
.projector-slide-body { font-weight: 400; text-align: center; margin-block: auto; }
.projector-slide-body :is(strong, b) { font-weight: 700; }
.projector-slide.slide-valign-top .projector-slide-body { margin-block: 0 auto; }
.projector-slide.slide-valign-bottom .projector-slide-body { margin-block: auto 0; }
.projector-slide.slide-align-left .projector-slide-body { text-align: left; }
.projector-slide.slide-align-right .projector-slide-body { text-align: right; }
/* Lists read naturally only left-aligned; centered/right slides keep bullets beside the text. */
.projector-slide:not(.slide-align-left) .projector-slide-body :is(ul, ol) { list-style-position: inside; }

/* Text-slide background image: a cover photo filling the stage, with a dark scrim behind the
   text for legibility. The bg sits BEHIND the stage padding (inset:0 over the whole #live-frame),
   while the body stays within the normal centered flow, lifted above the scrim. */
.projector-slide-bg {
  position: absolute; inset: 0; z-index: 0;
  background-size: cover; background-position: center; background-repeat: no-repeat;
}
.projector-slide-scrim { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.45); }

/* Imported deck page (PDF export): the page image fills the stage edge to edge, letterboxed on
   black when the screen and deck aspect ratios differ. Ignores the stage padding. */
.projector-deck-page { position: absolute; inset: 0; background: #000; display: flex; align-items: center; justify-content: center; }
.projector-deck-page img { width: 100%; height: 100%; object-fit: contain; display: block; }
.musician-deck-page img { max-width: 28rem; width: 100%; border-radius: 0.375rem; border: 1px solid #e5e7eb; }
.projector-slide.has-bg { position: relative; z-index: 1; }
.projector-slide.has-bg .projector-slide-body { text-shadow: 0 2px 10px rgba(0,0,0,0.6); }

/* Countdown field in a slide: fixed-width digits so the line doesn't jiggle every second. */
.slide-countdown { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Auto-advancing slide: every page stacked in ONE grid cell inside the stage's padding, so each
   keeps full layout (its own fit controller can measure it) and only the current one is visible.
   Fade cross-fades the pages; Cut switches instantly; reduced motion always cuts. */
.projector-auto-pages { flex: 1 1 auto; width: 100%; min-height: 0; display: grid; }
.projector-auto-page { grid-area: 1 / 1; display: flex; flex-direction: column; min-height: 0; opacity: 0; }
.projector-auto-page.is-on { opacity: 1; }
.projector-auto-pages.is-fade .projector-auto-page { transition: opacity 0.6s ease; }
@media (prefers-reduced-motion: reduce) {
  .projector-auto-pages.is-fade .projector-auto-page { transition: none; }
}

/* Song-wide background image (Song projection settings). The .projector-slide-bg/scrim fill the
   whole #live-frame; lift the title/lyric content above them and add a soft shadow so the text
   stays legible over any photo. The copyright footer rides along too. */
:is(#live-frame, .live-frame).has-song-bg > .projector-section,
:is(#live-frame, .live-frame).has-song-bg > .projector-title,
:is(#live-frame, .live-frame).has-song-bg .projector-copyright { position: relative; z-index: 1; }
:is(#live-frame, .live-frame).has-song-bg .projector-line,
:is(#live-frame, .live-frame).has-song-bg .projector-title-name,
:is(#live-frame, .live-frame).has-song-bg .projector-title-credit-line { text-shadow: 0 2px 12px rgba(0,0,0,0.65); }

.live-ended { text-align: center; font-size: 1.5rem; color: #9aa0a6; }

/* ── Musician view — a LIGHT, high-readability lead sheet (not the dark stage) ──
   The projector/congregation surfaces stay true-black; the musician reads from a
   bright paper-like chart. The whole set is shown in order; a sticky header tracks
   the live "Now" and peeks at "Next". */

/* Override the shared black follower background for the musician page only. */
.follower-body:has(.musician-root) { background: #f6f7f9; }

.musician-root {
  min-height: 100vh;
  padding: 0 0 4rem;
  box-sizing: border-box;
  background: #f6f7f9;
  color: #16181d;
  font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* Chord/lyric layout: chord floats above its syllable so a wide chord never injects a space.
   Shared by the live "Now" frame and the full chart. Monospace keeps columns honest.
   Only chord + first word is an unbreakable anchor (see SongsHelper#musician_segment); the
   rest of the lyric wraps normally, and each chorded anchor reserves its own chord row via
   padding-top, so a wrapped line on a phone never has chords overlapping the lyric above. */
.musician-line,
.musician-chart-line {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  white-space: pre-wrap; overflow-wrap: anywhere;
  font-size: 1.15rem; line-height: 1.5;
}
.musician-seg { position: relative; display: inline-block; white-space: pre; vertical-align: baseline; }
.musician-seg.has-chord { padding-top: 1.35em; }
.musician-chord {
  position: absolute; top: 0; left: 0; font-weight: 700; line-height: 1.35;
  white-space: pre; padding-right: 0.5rem; color: #1a56db; /* chords in a strong blue */
}

/* Top bar: set name + key/capo chooser, sticky so controls are always reachable. */
.musician-topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.75rem 1.25rem;
  background: #ffffff; border-bottom: 1px solid #e3e6ea;
}
.musician-setname { font-weight: 700; font-size: 1.05rem; }
.musician-key-chooser { display: flex; align-items: center; gap: 1rem; font-size: 0.85rem; color: #4a5059; }
.musician-key-chooser label { display: inline-flex; align-items: center; gap: 0.4rem; }
.musician-field {
  border: 1px solid #c9ced6; border-radius: 0.5rem; padding: 0.3rem 0.5rem; width: 4rem;
  background: #fff; color: #16181d; font-size: 0.95rem;
}
.musician-field-sm { width: 3.25rem; }

/* Above the fold: the sticky Now/Next header that follows the projector. */
.musician-nowbar {
  position: sticky; top: 3.25rem; z-index: 20;
  margin: 0 0 1.25rem; padding: 1rem 1.25rem 1.1rem;
  background: #fffdf4; border-bottom: 2px solid #e8d98f; /* a warm "live" band */
  box-shadow: 0 2px 6px rgba(0,0,0,0.04);
}
.musician-cue {
  display: inline-block; font-size: 0.7rem; font-weight: 800; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 0.1rem 0.5rem; border-radius: 0.4rem; margin-bottom: 0.4rem;
}
.musician-cue-now { background: #b45309; color: #fff; }
.musician-cue-next { background: #e5e7eb; color: #4a5059; }
.musician-now #live-frame {
  display: block; padding: 0; text-align: left; align-items: stretch; /* undo stage centering */
  background: transparent; color: #16181d; /* light lead sheet, not the dark projector stage */
}
.musician-now .musician-chart-section,
.musician-now .musician-section { margin: 0; }
/* The Now frame's chords stay blue and bold; its key badge is a light pill. */
.musician-now [data-role=key-badge] {
  display: inline-block; background: #eef2ff; color: #1a56db; border: 1px solid #c7d2fe;
  font-size: 0.75rem; font-weight: 700; padding: 0.1rem 0.5rem; border-radius: 0.4rem; margin-bottom: 0.5rem;
}
.musician-next { margin-top: 0.9rem; padding-top: 0.75rem; border-top: 1px dashed #e8d98f; }
.musician-next-body { color: #4a5059; font-size: 0.95rem; }
.musician-peek-label { font-weight: 700; color: #16181d; margin-right: 0.4rem; }
.musician-peek-title { font-weight: 700; }
.musician-peek-lyric { color: #6b7280; }

/* The whole-set chart. */
.musician-setlist { padding: 0 1.25rem; max-width: 56rem; margin: 0 auto; }
.musician-row {
  padding: 0.9rem 1.1rem; margin-bottom: 0.85rem;
  background: #ffffff; border: 1px solid #e3e6ea; border-radius: 0.75rem;
  scroll-margin-top: 8rem; /* clear the sticky Now/Next header when scrolled to */
}
.musician-row.is-current { border-color: #b45309; box-shadow: 0 0 0 2px rgba(180,83,9,0.25); }

.musician-chart-title h2 { font-size: 1.5rem; font-weight: 800; margin: 0; }
.musician-chart-key {
  display: inline-block; background: #eef2ff; color: #1a56db; border: 1px solid #c7d2fe;
  font-size: 0.8rem; font-weight: 700; padding: 0.1rem 0.5rem; border-radius: 0.4rem; margin-top: 0.4rem;
}
.musician-chart-credits { margin-top: 0.5rem; color: #6b7280; font-size: 0.9rem; }

.musician-chart-label,
.musician-section-label {
  font-size: 0.8rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase;
  color: #b45309; margin-bottom: 0.1rem;
}
.musician-chart-tag {
  margin-left: 0.5rem; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.03em;
  color: #6b7280; background: #f1f3f5; border: 1px solid #e3e6ea;
  padding: 0.05rem 0.4rem; border-radius: 0.4rem; text-transform: lowercase;
}
.musician-chart-section { margin: 0.5rem 0 0.75rem; }
.musician-chart-section.is-replay { opacity: 0.92; }
.musician-chart-annotation,
.musician-annotation { font-style: italic; color: #6b7280; }
.musician-empty { color: #6b7280; padding: 2rem 1.25rem; text-align: center; }
/* Permanent per-service link while the service isn't live: a calm note instead of the live band. */
.musician-not-live {
  margin: 0 0 1.25rem; padding: 0.75rem 1.25rem;
  background: #f4f5f7; border-bottom: 1px solid #e5e7eb; color: #4a5059; font-size: 0.95rem;
}

/* The live frame still carries dark-stage classes on the projector; keep the shared chord
   float technique working there. The musician's live frame is recolored above. */
.musician-section-label { color: #b45309; }

@media (prefers-reduced-motion: reduce) {
  .musician-row { scroll-behavior: auto; }
}

/* ── Song sheet auto-scroll dock ─────────────────────────────────────────────
   A floating teleprompter control on the song view (a light admin page, so it uses
   semantic theme tokens). Fixed bottom-center, above the sheet; never printed. */
.autoscroll-dock {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: 1.25rem; z-index: 40;
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.5rem 0.9rem 0.5rem 0.5rem;
  background: var(--color-base-100, #fff);
  border: 1px solid var(--color-base-300, #d4d8de);
  border-radius: 9999px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}
.autoscroll-speed { display: flex; align-items: center; gap: 0.5rem; }
.autoscroll-speed .range { width: 7rem; }
.autoscroll-speed-label {
  font-size: 0.8rem; font-weight: 700; min-width: 2rem; text-align: right;
  color: var(--color-base-content, #16181d);
}
@media print { .autoscroll-dock { display: none !important; } }
@media (prefers-reduced-motion: reduce) {
  /* The control still works on demand; we simply don't imply motion is free. */
  .autoscroll-dock { opacity: 0.95; }
}

/* ── Set preview page (one-page read-through inside the admin shell) ──────────
   Reuses the musician chart styling on a light surface. The preview's own top bar
   should not be sticky (the shell already has a sticky navbar), and the header +
   app chrome drop away when printing so the sheet prints clean. */
.musician-preview-page .musician-topbar { position: static; border-radius: 0.75rem; margin-bottom: 1rem; }
.musician-preview-page .musician-setlist { padding: 0; }
@media print {
  .no-print { display: none !important; }

  /* Drop the admin shell chrome so only the page content prints: no navbar, no
     sidebar, no drawer offset, no body tint. (The shell's navbar/sidebar carry no
     no-print class of their own, so they are hidden here by structure.) */
  body { background: #fff !important; }
  .drawer > .drawer-content > header.navbar,
  .drawer > .drawer-side { display: none !important; }
  .drawer, .drawer > .drawer-content { display: block !important; min-height: 0 !important; overflow: visible !important; }
  .drawer > .drawer-content > main > div { padding: 0 !important; }

  /* Print just the set: strip the app shell chrome around the preview. */
  [data-role=set-preview] { margin: 0 !important; max-width: none !important; }
  .musician-preview-page .musician-row { break-inside: avoid; box-shadow: none; border-color: #ccc; }
}

/* ── Sidebar navigation active style ─────────────────────────────────────────
   DaisyUI's menu draws `menu-active` (and the pressed :active state) from
   --menu-active-bg / --menu-active-fg, defaulting to the near-black neutral with a depth
   shadow. The sidebar sets them to a soft primary tint with primary text and icon instead.
   `.menu.sidebar-menu` outranks DaisyUI's `.menu`, which loads after this file. */
.menu.sidebar-menu {
  --menu-active-bg: color-mix(in oklab, var(--color-primary) 12%, var(--color-base-100));
  --menu-active-fg: var(--color-primary);
}
.menu.sidebar-menu .menu-active {
  box-shadow: none;
  font-weight: 600;
}

/* Nested submenu: indent and slightly mute the sub-item labels. */
.sidebar-submenu { padding-left: 0.5rem; }
.sidebar-submenu > li > a {
  font-size: 0.875rem;
  color: color-mix(in oklab, var(--color-base-content) 70%, transparent);
}
.sidebar-submenu > li > a.menu-active { color: var(--menu-active-fg); }
