/* =============================================================================
   CGF Worship v2 — worship.cgfvernon.ca
   Three full screens that slide over each other: services (a year of dates
   under the month tray of cgfvernon.ca) → one service's set list → one song.
   System fonts only. Warm ivory paper, burgundy for actions and chords,
   bronze for structure; the same paper under lamplight in dark mode.
============================================================================= */

:root {
  color-scheme: light;
  --paper:          #fbf7ef;
  --surface:        #fdfaf3;
  --card:           #fffdf8;
  --card-line:      #dfd6c6;
  --tint-bronze:    #f3eadb;
  --tint-accent:    #f7e8e6;
  --tray:           #f1e9da;
  --ink:            #2a231d;
  --ink-soft:       #675a4e;
  --ink-faint:      #93857a;
  --rule:           #e2d7c5;
  --rule-soft:      #ece4d5;
  --ghost-line:     #ddd2c0;
  --accent:         #7c2230;
  --accent-hover:   #661a27;
  --accent-line:    #d9aeb0;
  --accent-soft:    rgba(124, 34, 48, .34);
  --on-accent:      #fff8f3;
  --bronze:         #8a5e33;
  --chord:          #8a2533;
  --focus:          #8a2533;
  --live:           #2f9e57;
  --danger:         #b42f27;
  --mark:           #ffe27a;
  --btn-bg:         #fffcf6;
  --btn-bg-hover:   #f6eee0;
  --btn-bg-active:  #efe4d2;
  --btn-border:     #e2d7c5;
  --btn-border-hover: #d2c2a8;
  --shadow-soft:    0 1px 2px rgba(58, 42, 28, .05), 0 8px 24px rgba(58, 42, 28, .06);
  --shadow-sunday:  0 1px 2px rgba(58, 42, 28, .06), 0 10px 26px rgba(124, 34, 48, .11);
  --shadow-lift:    0 10px 30px rgba(58, 42, 28, .18), 0 2px 6px rgba(58, 42, 28, .08);
  --shadow-sheet:   0 -10px 34px rgba(40, 28, 16, .22);
  --shadow-view:    -16px 0 40px rgba(40, 28, 16, .16);
  --backdrop:       rgba(36, 27, 19, .5);

  --font-ui: system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --font-display: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", Cambria, Georgia, "Noto Serif", "Times New Roman", serif;
  --font-lyric: var(--font-display);
  --font-chord: var(--font-ui);

  --lyric-size: 20px;
  --chord-ratio: .72;
  --lyric-lh: 1.3;
  --chord-lh: 1.2;
  --plain-lh: 1.5;
  --chord-gap: max(7px, .5em);
  --row-gap: 3px;
  --label-size: 12px;

  --gutter: clamp(14px, 4.2vw, 24px);
  --col: 760px;
  --bar-h: 56px;
  --transport-h: 62px;
  --radius: 10px;
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --pad-l: max(calc(var(--gutter) + var(--safe-l)), calc((100% - var(--col)) / 2));
  --pad-r: max(calc(var(--gutter) + var(--safe-r)), calc((100% - var(--col)) / 2));
  --ease: cubic-bezier(.2, .7, .3, 1);
  --spring: cubic-bezier(.34, 1.3, .5, 1);
}

/* Dark: the same paper under lamplight (the first site's palette). ⋯ → Appearance
   sets <html data-theme>, remembered per phone; the head of the page sets it before
   anything shows, so there is no flash of the light paper. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --paper:          #15120f;
  --surface:        #1a1613;
  --card:           #1f1a16;
  --card-line:      #342b23;
  --tint-bronze:    #2a221a;
  --tint-accent:    #33211f;
  --tray:           #221c17;
  --ink:            #f0e7d8;
  --ink-soft:       #ab9d8b;
  --ink-faint:      #8a7d6d;
  --rule:           #352d25;
  --rule-soft:      #29211a;
  --ghost-line:     #3a3128;
  --accent:         #f0a79e;
  --accent-hover:   #f7bcb3;
  --accent-line:    #6d4038;
  --accent-soft:    rgba(240, 167, 158, .34);
  --on-accent:      #24100e;
  --bronze:         #d3a268;
  --chord:          #f4aca2;
  --focus:          #f0a79e;
  --live:           #4cc27a;
  --danger:         #f08a80;
  --mark:           #6e5519;
  --btn-bg:         #221d18;
  --btn-bg-hover:   #2c251e;
  --btn-bg-active:  #362d24;
  --btn-border:     #3a3128;
  --btn-border-hover: #4c4034;
  --shadow-soft:    0 1px 2px rgba(0, 0, 0, .3), 0 8px 24px rgba(0, 0, 0, .22);
  --shadow-sunday:  0 1px 2px rgba(0, 0, 0, .35), 0 10px 26px rgba(0, 0, 0, .34);
  --shadow-lift:    0 10px 30px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .35);
  --shadow-sheet:   0 -12px 40px rgba(0, 0, 0, .62);
  --shadow-view:    -16px 0 40px rgba(0, 0, 0, .5);
  --backdrop:       rgba(8, 6, 4, .68);
}

/* ---------------------------------------------------------------- base */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  overflow: hidden;                    /* each screen scrolls on its own */
  background: var(--paper);
  color: var(--ink);
  font: 400 16px/1.45 var(--font-ui);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  overflow-wrap: break-word;
}
h1, h2, h3, p, ol, ul { margin: 0; }
ol, ul { padding: 0; list-style: none; }
svg { display: block; }
a { color: inherit; }
[hidden] { display: none !important; }
::selection { background: var(--tint-accent); color: var(--ink); }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }
.sr-only {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.eyebrow {
  display: block;
  font: 700 11px/1.3 var(--font-ui);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--bronze);
}

/* ---------------------------------------------------------------- controls */
button {
  font: 600 15px/1.2 var(--font-ui);
  color: var(--ink);
  background: var(--btn-bg);
  border: 1px solid var(--btn-border);
  border-radius: var(--radius);
  min-height: 44px;
  min-width: 44px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  cursor: pointer;
  touch-action: manipulation;
  transition: background-color .15s ease, border-color .15s ease, color .15s ease, transform .08s ease;
}
button > svg, a > svg {
  width: 20px; height: 20px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
@media (hover: hover) { button:hover { background: var(--btn-bg-hover); border-color: var(--btn-border-hover); } }
button:active { background: var(--btn-bg-active); transform: translateY(1px); }
button[disabled] { opacity: .38; cursor: default; transform: none; background: var(--btn-bg); border-color: var(--btn-border); }
button.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); padding: 0 20px; }
@media (hover: hover) { button.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); } }
button.quiet { background: transparent; border-color: transparent; color: var(--ink-soft); }
.icon-btn { width: 44px; padding: 0; background: transparent; border-color: transparent; }
.icon-btn .aa { font: 700 16px/1 var(--font-display); letter-spacing: -.02em; }

input, output, textarea { font: inherit; color: inherit; }
input[type="range"] { width: 100%; height: 44px; margin: 0; accent-color: var(--accent); background: transparent; }

/* ---------------------------------------------------------------- screens */
.view {
  position: fixed;
  inset: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  -webkit-overflow-scrolling: touch;
  background: var(--paper);
}
#home { z-index: 1; }
#svc  { z-index: 2; }
#song { z-index: 3; }
/* a screen that is not showing keeps its place and its scroll position */
.view[aria-hidden="true"] { visibility: hidden; }
.view.moving { visibility: visible; will-change: transform; }
.view.covering { box-shadow: var(--shadow-view); }

.bar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: calc(var(--bar-h) + var(--safe-t));
  padding: var(--safe-t) var(--pad-r) 0 var(--pad-l);
  background: var(--paper);
}
.bar.sticky {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease;
}
.bar.sticky.scrolled { border-bottom-color: var(--rule); }
.bar-tools { display: flex; align-items: center; gap: 4px; margin-left: auto; margin-right: -8px; }

.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  min-height: 44px;
  padding: 10px 8px 0;
  margin-left: -8px;
  border-radius: 8px;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.brand-cgf { font: 700 11px/1 var(--font-ui); letter-spacing: .2em; color: var(--bronze); }
.brand-word { font: 600 21px/1 var(--font-display); letter-spacing: -.01em; }
.admin-tag {
  flex: none;
  padding: 4px 8px 3px;
  border-radius: 999px;
  background: var(--tint-bronze);
  color: var(--bronze);
  font: 800 10px/1.2 var(--font-ui);
  letter-spacing: .14em;
  text-transform: uppercase;
}

.back {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
  min-height: 44px;
  margin-left: -10px;
  padding: 0 10px 0 4px;
  border-radius: 10px;
  color: var(--accent);
  font: 600 15.5px/1.2 var(--font-ui);
  text-decoration: none;
}
.back span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.back svg { width: 24px; height: 24px; stroke-width: 2; }
@media (hover: hover) { .back:hover, .brand:hover { background: var(--btn-bg-hover); } }

/* live count: a pill with a dot; tap for the card */
.live {
  height: 34px;
  min-height: 34px;
  min-width: 0;
  gap: 7px;
  padding: 0 12px 0 11px;
  border-radius: 999px;
  font: 700 13.5px/1 var(--font-ui);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: #e0a24a; box-shadow: 0 0 0 3px rgba(224, 162, 74, .22); }
.live[data-state="live"] .live-dot { background: var(--live); box-shadow: 0 0 0 3px color-mix(in srgb, var(--live) 24%, transparent); animation: live-pulse 2.4s ease-in-out infinite; }
.live[data-state="offline"] .live-dot { background: var(--ink-faint); box-shadow: none; }
.live[data-state="connecting"] .live-dot { animation: blink 1.2s ease-in-out infinite; }
.live-n { min-width: 1ch; text-align: center; }
.live-n.bump { animation: bump .5s var(--spring); }
@keyframes live-pulse { 0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--live) 24%, transparent); } 50% { box-shadow: 0 0 0 6px transparent; } }
@keyframes blink { 50% { opacity: .35; } }
@keyframes bump { 0% { transform: translateY(40%); opacity: 0; } 100% { transform: none; opacity: 1; } }

/* a small card that drops out of its button: the count's, and Aa's text size */
.pop {
  position: fixed;
  z-index: 80;
  width: min(280px, calc(100vw - 24px));
  padding: 16px 18px 14px;
  border: 1px solid var(--rule);
  border-radius: 18px;
  background: var(--card);
  box-shadow: var(--shadow-lift);
  transform-origin: calc(100% - 30px) -8px;
  animation: card-drop .42s var(--spring) both;
}
.pop-caret {
  position: absolute;
  top: -7px;
  right: var(--caret-r, 26px);
  width: 14px; height: 14px;
  border-left: 1px solid var(--rule);
  border-top: 1px solid var(--rule);
  background: var(--card);
  transform: rotate(45deg);
}
.lc-count { display: flex; align-items: center; gap: 12px; }
.lc-count b { font: 800 40px/1 var(--font-ui); font-variant-numeric: tabular-nums; color: var(--accent); }
.lc-count span { font-size: 14.5px; line-height: 1.3; color: var(--ink-soft); }
.lc-state { margin-top: 10px; padding-top: 9px; border-top: 1px solid var(--rule-soft); font-size: 12.5px; color: var(--ink-faint); }
.lc-state:empty { display: none; }
@keyframes card-drop { from { opacity: 0; transform: translateY(-10px) scale(.92); } to { opacity: 1; transform: none; } }
.menu-card { width: min(300px, calc(100vw - 24px)); padding: 12px 12px 14px; }
.menu-row + .menu-row { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--rule-soft); }
.menu-label { display: block; margin: 0 2px 6px; font: 700 10.5px/1.2 var(--font-ui); letter-spacing: .12em; text-transform: uppercase; color: var(--bronze); }
.menu-card .seg { display: flex; width: 100%; }
.menu-card .seg button { display: inline-flex; flex: 1; align-items: center; justify-content: center; gap: 6px; padding: 0 8px; }
.mode-icon { width: 15px; height: 15px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.menu-btn svg { width: 20px; height: 20px; fill: currentColor; stroke: none; }
.font-row { display: flex; align-items: center; gap: 6px; }
.font-row input[type="range"] { flex: 1; min-width: 0; }
.font-step { flex: none; width: 44px; padding: 0; border-color: transparent; background: transparent; color: var(--accent); }
.font-step span { font: 600 15px/1 var(--font-display); }
.font-step.big span { font-size: 24px; }

/* ---------------------------------------------------------------- 1. services */
.filterbar {
  position: sticky;
  top: 0;
  z-index: 15;
  padding: 6px var(--pad-r) 10px var(--pad-l);
  background: color-mix(in srgb, var(--paper) 94%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.month-tray {
  position: relative;
  display: grid;
  grid-template-columns: auto repeat(6, 1fr);
  grid-template-rows: repeat(2, 40px); /* the same height with a year or two as with twelve months */
  gap: 3px;
  padding: 5px;
  border: 1px solid var(--rule);
  border-radius: 16px;
  background: var(--tray);
}
.tray-pill {
  position: absolute;
  top: 0; left: 0;
  width: 0; height: 0;
  border-radius: 11px;
  background: var(--accent);
  opacity: 0;
  pointer-events: none;
  transition: transform .44s var(--spring), width .44s var(--spring), height .44s var(--spring), opacity .12s ease;
}
.month-tray.ready .tray-pill { opacity: 1; }
.month-tray.no-anim .tray-pill { transition: none; }
.month-tray button {
  position: relative;
  z-index: 1;
  min-width: 0;
  min-height: 40px;
  padding: 0;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: var(--ink-soft);
  font: 650 12.5px/1 var(--font-ui);
  transition: color .2s ease;
}
/* twelve 44px cells would need a much taller bar: the pill stays compact, the
   hit area alone reaches the minimum (the bleed is under the 3px gap) */
.month-tray button::after { content: ""; position: absolute; inset: -2px -1px; }
@media (hover: hover) { .month-tray button:not(:disabled):not(.on):hover { background: color-mix(in srgb, var(--card) 70%, transparent); } }
.month-tray button:active { transform: none; }
.month-tray button.on { color: var(--on-accent); }
.month-tray button.is-now:not(.on) { box-shadow: inset 0 0 0 1.5px var(--accent-soft); }
.month-tray button:disabled { opacity: .32; cursor: default; }
.year-chip {
  grid-row: span 2;
  padding: 0 13px !important;
  box-shadow: inset 0 0 0 1px var(--rule);
  color: var(--ink) !important;
  font-size: 13.5px !important;
  font-weight: 750 !important;
}
.year-chip[aria-expanded="true"] { background: var(--card) !important; }
.month-tray.years button:not(.year-chip) { font-size: 13px; }

.months { padding: 4px var(--pad-r) calc(40px + var(--safe-b)) var(--pad-l); }
.month + .month { margin-top: 22px; }
.month-title {
  margin: 10px 2px 8px;
  font: 600 15px/1.2 var(--font-display);
  color: var(--ink-soft);
}
.cards { display: flex; flex-direction: column; gap: 8px; }

.card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 72px;
  padding: 12px 12px 12px 15px;
  overflow: hidden;
  border: 1px solid var(--card-line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: var(--shadow-soft);
  color: var(--ink);
  text-decoration: none;
  transition: opacity .2s ease, transform .12s ease;
}
.card.sunday { border-color: var(--accent-soft); box-shadow: var(--shadow-sunday); }
.card.sunday::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px; background: var(--accent); pointer-events: none; }
.card:active { transform: scale(.985); }
/* past dates step back: still there to open, just quieter */
.card.past { background: transparent; border-color: var(--ghost-line); box-shadow: none; opacity: .58; }
.card.past::before { opacity: .45; }
.card.singing { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), var(--shadow-sunday); }
.card-main small.card-now { color: var(--accent); font-weight: 600; }
@media (hover: hover) { .card:hover { opacity: 1; } .card:not(.past):hover { border-color: var(--accent-line); } }
.card-date { display: flex; flex: 0 0 42px; flex-direction: column; align-items: center; padding: 3px 0 4px; border-radius: 12px; }
.card-date small { font: 750 9.5px/1.2 var(--font-ui); letter-spacing: .09em; color: var(--bronze); }
.card-date strong { font: 600 24px/1.05 var(--font-display); }
.card.today .card-date { background: var(--accent); }
.card.today .card-date small { color: color-mix(in srgb, var(--on-accent) 78%, transparent); }
.card.today .card-date strong { color: var(--on-accent); }
.card-main { flex: 1; min-width: 0; }
.card-main strong { display: block; overflow: hidden; font: 600 17px/1.3 var(--font-display); text-overflow: ellipsis; white-space: nowrap; }
.card-main small { display: block; overflow: hidden; color: var(--ink-soft); font-size: 12.5px; line-height: 1.5; text-overflow: ellipsis; white-space: nowrap; }
.card-side { display: flex; flex: none; align-items: center; gap: 6px; color: var(--ink-faint); }
.card-side svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.card-flag { font: 750 11px/1 var(--font-ui); letter-spacing: .04em; color: var(--accent); }
.card-flag.live-flag { display: inline-flex; align-items: center; gap: 5px; padding: 4px 8px 4px 7px; border-radius: 999px; background: var(--accent); color: var(--on-accent); }
.card-flag.live-flag::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: blink 1.6s ease-in-out infinite; }
.home-empty { padding: 40px var(--pad-r) 0 var(--pad-l); color: var(--ink-soft); text-align: center; }

/* A service dressed for its occasion (user, 2026-10-03, after cgfvernon.ca's design of
   2026-10-01: OccasionArt.tsx and .has-occasion in the CGF Website's globals.css). The
   artwork sits in the top-right corner over a wash of its colour; the element isolates, so
   the art's z-index of -1 puts it above the background but under the words. */
.has-occasion { isolation: isolate; }
.occasion-thanksgiving { --occasion-wash: rgba(214, 128, 52, .16); }
:root[data-theme="dark"] .occasion-thanksgiving { --occasion-wash: rgba(214, 128, 52, .2); }
.occasion-art { position: absolute; top: 0; right: 0; z-index: -1; height: auto; pointer-events: none; }
/* On the date card: a strip of it, fading out toward the title, with the flag and the
   chevron on pale pills so they stay readable over the leaves. */
.card.has-occasion { background-image: radial-gradient(120% 140% at 100% 0%, var(--occasion-wash), transparent 60%); }
.card .occasion-art { width: 150px; -webkit-mask-image: linear-gradient(90deg, transparent, #000 50%); mask-image: linear-gradient(90deg, transparent, #000 50%); }
.card.has-occasion .card-flag:not(.live-flag),
.card.has-occasion .card-side svg { border-radius: 999px; background: color-mix(in srgb, var(--card) 86%, transparent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--card) 86%, transparent); }
/* At the top of the set list: the whole piece; the empty float is the size of its dense part
   (the right 37.5% and top 102 of its 128 units), so the date and title wrap before it. */
.svc-head { position: relative; }
.svc-head.has-occasion { display: flow-root; background-image: radial-gradient(130% 100% at 100% 0%, var(--occasion-wash), transparent 62%); }
.svc-head .occasion-art { width: var(--oa-w); }
.svc-head { --oa-w: min(64vw, 240px); }
.occasion-room { float: right; width: calc(var(--oa-w) * .375); aspect-ratio: .88; margin: -10px calc(-1 * var(--pad-r)) 4px 12px; }

/* It moves each time it comes on screen (app.js swaps oa-wait for oa-play, and back once it
   has gone right off, which restarts the keyframes). Each moving part is an .oa group with its
   start in --d; one with .oa-at turns about a point in the art's own units. */
.oa { --d: 0s; transform-box: fill-box; transform-origin: center; }
.oa-at { transform-box: view-box; }
@media (prefers-reduced-motion: no-preference) {
  .oa-wait .oa { opacity: 0; }
  .oa-play .oa-fall { animation: oa-fall 1s cubic-bezier(.2, .75, .3, 1) var(--d) both; }
  .oa-play .oa-drift { animation: oa-drift 1.8s ease-out var(--d) both; }
  .oa-play .oa-pop { animation: oa-pop .65s ease-out var(--d) both; }
  .oa-play .oa-sway { animation: oa-sway 1.2s ease-out var(--d) both; }
  .oa-play .oa-swing { animation: oa-swing 2.4s ease-in-out var(--d) both; }
}
@keyframes oa-fall { from { opacity: 0; transform: translate(-6px, -22px) rotate(-24deg); } to { opacity: 1; transform: none; } }
@keyframes oa-drift {
  0% { opacity: 0; transform: translate(14px, -26px) rotate(-60deg); }
  60% { opacity: 1; transform: translate(-3px, -4px) rotate(10deg); }
  100% { opacity: 1; transform: none; }
}
@keyframes oa-pop { 0% { opacity: 0; transform: scale(.3); } 65% { opacity: 1; transform: scale(1.08); } 100% { opacity: 1; transform: none; } }
@keyframes oa-sway { 0% { opacity: 0; transform: rotate(-9deg); } 60% { opacity: 1; transform: rotate(1.5deg); } 100% { opacity: 1; transform: none; } }
@keyframes oa-swing {
  0% { opacity: 0; transform: rotate(22deg); }
  12% { opacity: 1; }
  35% { transform: rotate(-12deg); }
  58% { transform: rotate(6deg); }
  80% { transform: rotate(-2.5deg); }
  100% { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- 2. one service */
.svc-head { padding: 10px var(--pad-r) 16px var(--pad-l); }
.svc-head h1 { margin: 6px 0 4px; font: 600 clamp(28px, 7.4vw, 36px)/1.1 var(--font-display); letter-spacing: -.01em; text-wrap: balance; }
.svc-meta { color: var(--ink-soft); font-size: 14px; }
.svc-recordings { margin-top: 12px; }
.telegram-link { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 10px 14px; border: 1px solid var(--accent-line); border-radius: 12px; background: var(--tint-accent); color: var(--accent); font: 700 13px/1.35 var(--font-ui); text-decoration: none; }
.telegram-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.recording-links { display: flex; flex-wrap: wrap; gap: 8px; }
/* in the point's sheet (admin): each video's length after a hairline */
.telegram-link .recording-time { margin-left: 10px; padding-left: 10px; border-left: 1px solid var(--accent-line); font-weight: 600; font-variant-numeric: tabular-nums; }
.svc-team { margin-top: 8px; color: var(--ink-soft); font-size: 13.5px; line-height: 1.55; }
.svc-team b { color: var(--bronze); font-weight: 700; }

.cue {
  position: relative;
  margin: 0 var(--pad-r) 0 var(--pad-l);
  border: 1px solid var(--rule);
  border-radius: 18px;
  background: var(--card);
  box-shadow: var(--shadow-soft);
}
.cue-row {
  position: relative;
  display: flex;
  align-items: stretch;
  background: var(--card);
  border-radius: 0;
}
.cue-row:first-child { border-radius: 18px 18px 0 0; }
.cue-row:last-child { border-radius: 0 0 18px 18px; }
.cue-row:only-child { border-radius: 18px; }
.cue-row + .cue-row::before { content: ""; position: absolute; top: 0; left: 52px; right: 0; border-top: 1px solid var(--rule-soft); }
.cue-open {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 12px;
  min-width: 0;
  min-height: 64px;
  padding: 11px 8px 11px 12px;
  border-radius: inherit;
  color: var(--ink);
  text-decoration: none;
}
@media (hover: hover) { .cue-open:hover { background: color-mix(in srgb, var(--tint-bronze) 45%, transparent); } }
.cue-open:active { background: var(--tint-bronze); }
.cue-n {
  display: flex;
  flex: 0 0 28px;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  font: 600 18px/1 var(--font-display);
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--bronze);
  text-align: center;
}
.cue-n-now { font: 800 8px/1 var(--font-ui); letter-spacing: .08em; text-transform: uppercase; color: var(--accent); animation: blink 1.6s ease-in-out infinite; }
/* measuring (app.js fitTitles): every title at its one-line width, never painted */
.cue.measuring .cue-title { width: max-content; max-height: none; white-space: nowrap; overflow: visible; }
.cue-main { flex: 1; min-width: 0; }
/* one line where it fits (app.js fitTitles), else two even lines, never more */
.cue-title {
  display: block;
  max-height: calc(2em * 1.28);
  overflow: hidden;
  font: 600 17px/1.28 var(--font-display);
  text-wrap: balance;
}
.cue-sub { display: block; margin-top: 3px; overflow: hidden; color: var(--ink-soft); font-size: 12.5px; line-height: 20px; text-overflow: ellipsis; white-space: nowrap; }
.cue-sub i { color: var(--ink-faint); }
.cue-tag {
  display: inline-block;
  margin-right: 6px;
  padding: 2px 6px 1px;
  border-radius: 999px;
  background: var(--tint-bronze);
  color: var(--bronze);
  font: 800 9.5px/1.3 var(--font-ui);
  font-style: normal;
  letter-spacing: .1em;
  text-transform: uppercase;
  vertical-align: 1px;
}
/* the key sits first under the title, where every row puts it */
.cue-key {
  display: inline-block;
  min-width: 26px;
  margin-right: 7px;
  padding: 0 6px;
  border: 1px solid var(--accent-line);
  border-radius: 6px;
  background: var(--tint-accent);
  color: var(--accent);
  font: 700 12.5px/18px var(--font-ui);
  font-variant-numeric: tabular-nums;
  text-align: center;
  vertical-align: 0;
}
.cue-key.mine { border-style: dashed; background: transparent; }
.cue-row.backup .cue-title { font-style: italic; color: var(--ink-soft); }
.cue-row:not(:has(.grip)) .cue-open { padding-right: 14px; }

/* now singing: the row carries a band and "Now" under its number (nothing else in the row moves) */
.cue-row.now { background: color-mix(in srgb, var(--tint-accent) 70%, var(--card)); }
.cue-row.now::after { content: ""; position: absolute; inset: 10px auto 10px 0; width: 3px; border-radius: 0 3px 3px 0; background: var(--accent); pointer-events: none; }
.cue-row.now .cue-n { color: var(--accent); }
.now-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-right: 7px;
  padding: 0 7px 0 6px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font: 800 9.5px/18px var(--font-ui);
  letter-spacing: .1em;
  text-transform: uppercase;
  vertical-align: 1px;
}
.now-tag i, .now-dot {
  content: "";
  display: block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: blink 1.6s ease-in-out infinite;
}
/* a point of the program: its kind's colour, its icon where a song has its number */
.k-sermon { --k: #b3151b; }
.k-intro { --k: #9a4a1f; }
.k-song { --k: #c27a0e; }
.k-poem { --k: #2f7d6b; }
.k-testimony { --k: #3a6ea5; }
.k-announcements { --k: #6b6258; }
.k-prayer { --k: #6b5190; }
.k-other { --k: #7d6e67; }
/* lighter under the lamp, so the kind's name still reads on the dark paper */
:root[data-theme="dark"] .k-sermon { --k: #de5b55; }
:root[data-theme="dark"] .k-intro { --k: #d27d4a; }
:root[data-theme="dark"] .k-song { --k: #d99a2b; }
:root[data-theme="dark"] .k-poem { --k: #3fa58c; }
:root[data-theme="dark"] .k-testimony { --k: #5b8fd0; }
:root[data-theme="dark"] .k-announcements { --k: #9a8f84; }
:root[data-theme="dark"] .k-prayer { --k: #9477c2; }
:root[data-theme="dark"] .k-other { --k: #a39289; }
.point-node { display: grid; width: 28px; height: 28px; place-items: center; border-radius: 50%; background: var(--k); color: #fff; box-shadow: 0 3px 8px -2px color-mix(in srgb, var(--k) 60%, transparent); }
.point-node svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round; }
.point-kind { font: 800 9.5px/1 var(--font-ui); letter-spacing: .1em; text-transform: uppercase; color: var(--k); }
/* a point is one line (who, its kind beside the name), a second only for a title or note;
   a little lighter than the songs, which are what people open. A name is never cut: a long
   one on a narrow phone takes a third line rather than lose its end or its kind. */
.cue-row.point .cue-open { min-height: 48px; padding-block: 8px; }
.cue-row.point .cue-title { max-height: none; font-size: 16px; }
.cue-title .point-kind { margin-left: 8px; vertical-align: .18em; white-space: nowrap; }
.cue-row.point .cue-open { cursor: default; }
@media (hover: hover) { html:not(.admin) .cue-row.point .cue-open:hover { background: transparent; } }
html:not(.admin) .cue-row.point .cue-open:active { background: transparent; }
html.admin .cue-row.point .cue-open { cursor: pointer; }

/* A point's recording (user, 2026-10-04: one tap opens it in Telegram, and it shows how
   long it is). The row is the link. Its length sits at the right edge in a play chip, so
   it reads as a video's length, not the time of day the point began; the chips are all
   one width with the figures to the right, so the lengths line up down the list as in a
   track list (a bare ▶ where the length is not known). Nothing goes under the name, so
   no row grows for it. In parts: part 1 is the row, each further part a slim line of its
   own under it, its chip under part 1's, every chip named by its part (on a narrow phone
   part 1's chip too takes a line under the name: see below). */
.point a.cue-open { color: inherit; text-decoration: none; }
html:not(.admin) .cue-row.point a.cue-open { cursor: pointer; }
@media (hover: hover) { html:not(.admin) .cue-row.point a.cue-open:hover, .recording-part-link:hover { background: color-mix(in srgb, var(--tint-bronze) 45%, transparent); } }
html:not(.admin) .cue-row.point a.cue-open:active, .recording-part-link:active { background: var(--tint-bronze); }
.recording-meta { display: flex; flex: none; align-items: center; gap: 7px; }
.recording-indicator {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: space-between;
  gap: 5px;
  min-width: calc(4.6ch + 27px);       /* "00:00" and the ▶ */
  height: 24px;
  padding: 0 8px 0 7px;
  border-radius: 999px;
  background: var(--tint-accent);
  color: var(--accent);
  font: 700 12.5px/1 var(--font-ui);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.recording-indicator::before { content: ""; flex: none; width: 7px; height: 8px; background: currentColor; clip-path: polygon(0 0, 100% 50%, 0 100%); }
.recording-indicator:empty { justify-content: center; width: 24px; min-width: 0; padding: 0 0 0 2px; }
.recording-part { font: 800 9.5px/1 var(--font-ui); font-variant-numeric: tabular-nums; letter-spacing: .1em; text-transform: uppercase; color: var(--bronze); white-space: nowrap; }
.point.has-recording-parts { flex-wrap: wrap; }
/* Part 1 never squeezes the name: where it would leave the name under 150px (a phone
   narrower than about 370px; at 320px the name had 107px and lost its kind), part 1's
   label and chip drop to a line of their own under the name, a line like part 2's, the
   chip in the same right-edge column. Wider, nothing moves. */
.point.has-recording-parts > .cue-open { flex-basis: 100%; flex-wrap: wrap; row-gap: 0; }
.point.has-recording-parts .cue-main { flex-basis: 150px; }
.point.has-recording-parts .cue-open > .recording-meta { min-height: 32px; margin-left: auto; }
.cue-row.point.has-recording-parts > .cue-open { min-height: 40px; padding-bottom: 0; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.recording-parts { width: 100%; }
.recording-part-link { display: flex; align-items: center; justify-content: flex-end; min-height: 40px; padding: 0 14px 8px 52px; color: inherit; text-decoration: none; }
.cue-row:last-child .recording-part-link:last-child { border-radius: 0 0 18px 18px; }

/* admin: the + at the bottom right adds a point */
.fab {
  position: fixed;
  right: calc(18px + var(--safe-r));
  bottom: calc(20px + var(--safe-b));
  z-index: 16;
  width: 58px;
  height: 58px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 10px 24px rgba(124, 34, 48, .35), 0 2px 6px rgba(58, 42, 28, .15);
}
.fab svg { width: 26px; height: 26px; stroke-width: 2.4; }
@media (hover: hover) { .fab:hover { background: var(--accent-hover); } }
html.admin #svc { padding-bottom: calc(100px + var(--safe-b)); }

/* the kinds in the point's sheet (as on sam26) */
.kinds { display: flex; flex-wrap: wrap; gap: 6px; }
.kind {
  display: inline-flex; /* its colour comes from its k-* class */
  flex: none;
  align-items: center;
  gap: 5px;
  height: 32px;
  min-height: 32px;
  min-width: 0;
  padding: 0 11px 0 4px;
  border: 1.5px solid var(--btn-border);
  border-radius: 999px;
  background: var(--card);
  color: var(--ink-soft);
  font: 600 13px/1 var(--font-ui);
}
.kind i { display: grid; width: 23px; height: 23px; place-items: center; border-radius: 50%; background: color-mix(in srgb, var(--k) 14%, transparent); color: var(--k); }
.kind svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.kind[aria-checked="true"] { background: var(--k); border-color: var(--k); color: #fff; }
.kind[aria-checked="true"] i { background: rgba(255, 255, 255, .22); color: #fff; }
.dialog-foot .grow { flex: 1; }
button.danger { color: var(--danger); }

.grip {
  flex: none;
  align-self: stretch;
  width: 46px;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: color-mix(in srgb, var(--ink-faint) 80%, transparent);
  cursor: grab;
  touch-action: none;
}
.cue-row:first-child .grip { border-top-right-radius: 17px; }
.cue-row:last-child .grip { border-bottom-right-radius: 17px; }
.grip svg { width: 20px; height: 20px; fill: currentColor; stroke: none; }
@media (hover: hover) { .grip:hover { background: var(--tint-bronze); color: var(--ink-soft); } }
.grip:active { transform: none; }
.cue.is-dragging .cue-row:not(.dragging) { transition: transform .22s var(--ease); }
.cue.is-dragging { user-select: none; -webkit-user-select: none; }
.cue-row.dragging { z-index: 6; border-radius: 16px; background: var(--card); box-shadow: var(--shadow-lift); }
.cue-row.dragging::before, .cue-row.dragging + .cue-row::before { opacity: 0; }
.cue-row.dragging .grip { color: var(--accent); cursor: grabbing; }
.cue-row.flash { animation: row-flash 1.4s var(--ease); }
@keyframes row-flash { from { box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--accent) 12%, transparent); } to { box-shadow: inset 0 0 0 999px transparent; } }
body.dragging-any, body.dragging-any * { cursor: grabbing !important; }
.svc-foot { padding: 18px var(--pad-r) calc(40px + var(--safe-b)) var(--pad-l); color: var(--ink-faint); font-size: 13px; }
.svc-foot a { color: var(--accent); font-weight: 600; text-decoration: none; }

/* ---------------------------------------------------------------- 3. one song */
.reader { padding: 0 var(--pad-r) calc(var(--transport-h) + var(--safe-b) + 28px) var(--pad-l); }
.song-header { position: relative; padding: 4px 0 4px; }
.song-meta {
  display: flex; flex-wrap: wrap; gap: 2px 10px;
  font: 700 11.5px/1.3 var(--font-ui);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bronze);
}
.song-meta:empty { display: none; }
#song-title { margin: 6px 0 2px; font: 600 clamp(25px, 6.8vw, 32px)/1.14 var(--font-display); text-wrap: balance; }
.edit-song { min-height: 36px; margin-top: 10px; padding: 0 12px 0 10px; border-radius: 999px; color: var(--accent); font-size: 13.5px; }
.edit-song svg { width: 16px; height: 16px; }
.song-header .now-tag { position: absolute; top: 4px; right: 0; margin: 0; }

/* another song is being sung: one tap goes there */
.now-pill {
  position: fixed;
  left: 50%;
  bottom: calc(var(--transport-h) + var(--safe-b) + 10px);
  z-index: 11;
  display: flex;
  align-items: center;
  gap: 6px;
  width: max-content; /* centred by its own width, not squeezed into half the screen */
  max-width: min(calc(100vw - 48px), 420px);
  height: 30px;
  padding: 0 8px 0 10px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  box-shadow: 0 4px 14px rgba(58, 42, 28, .2);
  text-decoration: none;
  transform: translateX(-50%);
  animation: pill-in .38s var(--spring) both;
}
.now-pill::after { content: ""; position: absolute; inset: -7px -4px; } /* a finger-sized target for a slim pill */
.now-dot { width: 5px; height: 5px; }
.now-label { flex: none; font: 800 9px/1 var(--font-ui); letter-spacing: .12em; text-transform: uppercase; opacity: .85; }
.now-title { min-width: 0; overflow: hidden; font: 600 13.5px/1.2 var(--font-display); text-overflow: ellipsis; white-space: nowrap; }
.now-pill svg { width: 13px; height: 13px; stroke-width: 2.4; }
@keyframes pill-in { from { opacity: 0; transform: translate(-50%, 8px) scale(.96); } to { opacity: 1; transform: translateX(-50%); } }
body.now-pill-up .reader { padding-bottom: calc(var(--transport-h) + var(--safe-b) + 60px); }
body.now-pill-up #toast { bottom: calc(var(--transport-h) + var(--safe-b) + 50px); }

/* Lyrics | Chords, Original | Latin and 文A share one line under the title */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 12px 0 8px;
}
/* 文A: the translation under each line (Russian songs); a tap goes to the next language */
.toolbar .seg button { padding: 0 10px; }
.tr-btn {
  flex: none;
  gap: 4px;
  height: 36px;
  min-height: 36px;
  min-width: 0;
  padding: 0 10px;
  border-radius: 999px;
  color: var(--ink-soft);
  font: 600 13px/1 var(--font-ui);
}
.tr-icon { font: 600 13.5px/1 var(--font-ui); letter-spacing: -.02em; }
.tr-state:empty { display: none; }
.tr-btn.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
@media (hover: hover) { .tr-btn.on:hover { background: var(--accent-hover); border-color: var(--accent-hover); } }
.tr-line {
  margin: -1px 0 7px;
  font-family: var(--font-lyric);
  font-size: calc(var(--ls) * .8);
  font-style: italic;
  font-weight: 400;
  line-height: 1.3;
  color: color-mix(in srgb, var(--accent) 62%, var(--ink-soft));
  text-wrap: pretty;
}
/* in the top bar: − key + beside Aa */
.bar-tools .key-control { margin-right: 2px; }
.key-control {
  display: flex;
  flex: none;
  align-items: stretch;
  height: 36px;
  overflow: hidden;
  border: 1px solid var(--btn-border);
  border-radius: 10px;
  background: var(--btn-bg);
}
.key-control button {
  min-width: 36px;
  min-height: 34px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--accent);
  font-size: 19px;
  font-weight: 500;
  line-height: 1;
}
.key-control button:active { transform: none; background: var(--btn-bg-active); }
.key-control button.key-label {
  flex-direction: column;
  gap: 0;
  min-width: 44px;
  padding: 0 6px;
  border-inline: 1px solid var(--rule);
  color: var(--ink);
  overflow: hidden;
  user-select: none;
  -webkit-user-select: none;
}
.key-label small {
  margin-bottom: 2px;
  font: 750 7.5px/1 var(--font-ui);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bronze);
  white-space: nowrap;
}
.key-label.shifted { background: var(--tint-accent); }
.key-label.shifted small { color: var(--accent); }
/* the caption only speaks up when the key has been changed ("Your key", "orig C") */
.key-label:not(.shifted) small { display: none; }
.key-label strong { display: block; font: 700 15px/1 var(--font-ui); font-variant-numeric: tabular-nums; white-space: nowrap; }

.seg {
  position: relative;
  display: inline-flex;
  flex: none;
  align-items: stretch;
  height: 36px;
  padding: 2px;
  border: 1px solid var(--btn-border);
  border-radius: 999px;
  background: var(--btn-bg);
}
.seg-thumb {
  position: absolute;
  top: 2px; bottom: 2px; left: 0;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
  transition: transform .28s var(--ease), width .28s var(--ease);
}
.seg-thumb.no-anim { transition: none; }
.seg button {
  position: relative;
  z-index: 1;
  min-height: 30px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  font-size: 13px;
  white-space: nowrap;
  transition: color .2s ease;
}
.seg button[aria-pressed="true"] { color: var(--on-accent); background: transparent; }
.seg button:active { transform: none; background: transparent; }
@media (hover: hover) {
  .seg button:hover { background: transparent; }
  .seg button:not([aria-pressed="true"]):hover { color: var(--accent); }
}

.notice {
  margin: 8px 0 4px;
  padding: 9px 12px;
  border-left: 3px solid var(--bronze);
  border-radius: 0 8px 8px 0;
  background: var(--tint-bronze);
  color: var(--ink-soft);
  font: 400 14px/1.45 var(--font-ui);
}

/* --fit (app.js fitLines) shrinks a song a little so its lines stay whole */
#song-content { --ls: calc(var(--lyric-size) * var(--fit, 1)); padding-top: 6px; font-family: var(--font-lyric); font-size: var(--ls); line-height: var(--lyric-lh); overflow-wrap: normal; }
.lyric-section { scroll-margin-top: calc(var(--bar-h) + var(--safe-t) + 10px); }
.lyric-section + .lyric-section { margin-top: 18px; }
.section-title { margin: 0 0 4px; font: 700 var(--label-size)/1.25 var(--font-ui); letter-spacing: .13em; text-transform: uppercase; color: var(--bronze); }
.section-title:empty { display: none; }
.chorus .section-title { color: var(--accent); }
.chorus .lyric-line, .chorus .syllable, .chorus .tr-line { font-weight: 700; } /* choruses always bold, translations included */
.lyric-line { font-size: var(--ls); } /* a line app.js had to fit on its own carries its own --ls */
.lyric-line.plain { display: block; padding-block: 1px; line-height: var(--plain-lh); text-wrap: balance; }
/* measuring: every line at its one-line width (never painted) */
#song-content.measuring .lyric-line { width: max-content; max-width: none; }
#song-content.measuring .lyric-line.plain { white-space: nowrap; }
#song-content.measuring .lyric-line.charted { flex-wrap: nowrap; }
#song-content.measuring .word { max-width: none; }
.lyric-line.plain:empty { min-height: .6em; }
.lyric-line.charted { display: flex; flex-wrap: wrap; align-items: flex-end; row-gap: var(--row-gap); padding-block: 2px 1px; }
.lyric-line.charted > .word { display: flex; flex: 0 0 auto; flex-wrap: nowrap; align-items: flex-end; max-width: 100%; }
.segment { display: flex; flex: 0 0 auto; flex-direction: column; align-items: flex-start; }
.chord {
  display: block;
  height: calc(1em * var(--chord-lh));
  margin-right: var(--chord-gap);
  overflow: hidden;
  font-family: var(--font-chord);
  font-size: calc(var(--ls) * var(--chord-ratio));
  font-weight: 700;
  line-height: var(--chord-lh);
  font-variant-numeric: tabular-nums;
  color: var(--chord);
  white-space: nowrap;
  user-select: none;
  -webkit-user-select: none;
}
.chord:empty { margin-right: 0; }
.chord:empty::before { content: "\200B"; }
.syllable { display: block; min-height: calc(1em * var(--lyric-lh)); font-size: var(--ls); line-height: var(--lyric-lh); white-space: pre; }
.syllable:empty::before { content: "\200B"; }
.chords-off .chord { height: 0 !important; width: 0 !important; margin-right: 0 !important; opacity: 0 !important; }
.chords-off .syllable { line-height: var(--plain-lh); min-height: calc(1em * var(--plain-lh)); }
.chords-exit .chord { opacity: 0; transition: opacity .12s ease; }
.chords-enter .chord { animation: chord-in .3s .06s ease both; }
@keyframes chord-in { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
.roll-up   { animation: roll-up .3s var(--ease) both; }
.roll-down { animation: roll-down .3s var(--ease) both; }
@keyframes roll-up   { from { transform: translateY(70%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes roll-down { from { transform: translateY(-70%); opacity: 0; } to { transform: none; opacity: 1; } }
.src-swap   { animation: src-in .42s var(--ease) both; }
.src-swap-r { animation: src-in-r .42s var(--ease) both; }
@keyframes src-in   { from { transform: translateY(-8px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes src-in-r { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
.song-enter { animation: song-in .28s var(--ease) both; }
@keyframes song-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.source-details { margin: 28px 0 4px; border-top: 1px solid var(--rule); color: var(--ink-soft); font: 400 14px/1.55 var(--font-ui); }
.source-details > summary {
  display: flex; align-items: center; gap: 10px;
  min-height: 48px;
  list-style: none;
  cursor: pointer;
  font: 700 var(--label-size)/1.2 var(--font-ui);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--bronze);
}
.source-details > summary::-webkit-details-marker { display: none; }
.source-details > summary::before {
  content: ""; flex: none; width: .42em; height: .42em; margin-top: -.15em;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(-45deg); transition: transform .18s ease;
}
.source-details[open] > summary::before { transform: rotate(45deg); }
#source-note { margin: 2px 0 12px; }
#source-note:empty { display: none; }
#source-links { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 14px; }
#source-links:empty { display: none; }
.source-link {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px;
  border: 1px solid var(--rule); border-radius: 999px;
  color: var(--accent); font: 600 13.5px/1.2 var(--font-ui); text-decoration: none;
}
#source-photo { display: block; width: 100%; height: auto; margin-bottom: 14px; border: 1px solid var(--rule); border-radius: 10px; background: var(--tint-bronze); }

.transport {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 12;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: calc(var(--transport-h) + var(--safe-b));
  padding: 8px var(--pad-r) calc(8px + var(--safe-b)) var(--pad-l);
  background: var(--surface);
  border-top: 1px solid var(--rule);
}
.transport .step { flex: none; height: 46px; padding: 0 10px; font-size: 14.5px; }
#previous { width: 48px; padding: 0; }
#next { padding: 0 8px 0 14px; }
/* the middle: the set list (tap), where we are, and the song that comes next */
.transport .position {
  flex: 1 1 auto;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 0;
  height: 46px;
  padding: 0 6px;
  background: transparent;
  border-color: transparent;
}
#pos-caption {
  font: 700 9.5px/1 var(--font-ui);
  font-variant-numeric: tabular-nums;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--bronze);
  white-space: nowrap;
}
#pos-next {
  max-width: 100%;
  overflow: hidden;
  font: 600 14.5px/1.2 var(--font-display);
  color: var(--ink);
  text-overflow: ellipsis;
  white-space: nowrap;
}
#pos-next.last { color: var(--ink-faint); font-style: italic; font-weight: 400; }

/* ---------------------------------------------------------------- sheets */
dialog {
  width: 100%;
  max-width: 100%;
  max-height: calc(100dvh - 40px);
  margin: auto 0 0;
  padding: 0;
  border: 0;
  border-radius: 20px 20px 0 0;
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-sheet);
  overflow: auto;
}
dialog:not([open]) { display: none !important; }
dialog[open] { display: block; animation: sheet-up .32s var(--ease) both; }
dialog::backdrop { background: var(--backdrop); animation: fade .2s ease both; }
@keyframes sheet-up { from { transform: translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes fade { from { opacity: 0; } }
@media (min-width: 640px) {
  dialog { width: min(460px, calc(100vw - 32px)); margin: auto; border-radius: 20px; }
}
.dialog-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 10px 6px 20px; }
.dialog-head h2 { font: 600 22px/1.2 var(--font-display); }
.dialog-titles .eyebrow { margin-bottom: 3px; }
.dialog-body { display: flex; flex-direction: column; gap: 12px; padding: 8px 20px 18px; }
.dialog-foot {
  position: sticky;
  bottom: 0;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 20px calc(14px + var(--safe-b));
  background: var(--card);
  border-top: 1px solid var(--rule-soft);
}

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field-label { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px; font: 700 11px/1.2 var(--font-ui); letter-spacing: .12em; text-transform: uppercase; color: var(--bronze); }
.field-reset { min-height: 22px; min-width: 0; padding: 0 8px; border-radius: 999px; background: var(--tint-accent); border-color: transparent; color: var(--accent); font-size: 11.5px; letter-spacing: 0; text-transform: none; }
.field input, .field textarea {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--btn-border);
  border-radius: 10px;
  background: var(--paper);
  font-size: 16px;                    /* 16px keeps iPhones from zooming in */
  line-height: 1.35;
  resize: none;
}
.field input:focus, .field textarea:focus { border-color: var(--accent); outline: 2px solid var(--accent-soft); outline-offset: 0; }
.field-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: end; }
.key-control.small .f-key { display: grid; place-items: center; min-width: 52px; border-inline: 1px solid var(--rule); font: 700 16px/1 var(--font-ui); }
.switch-row { display: flex; align-items: center; justify-content: space-between; min-height: 44px; font-weight: 600; font-size: 15px; }
.switch-row input { width: 46px; height: 28px; margin: 0; accent-color: var(--accent); }

/* two fields side by side (a guest's title | city; the point's title | note) */
.field-pair { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px; }
.field-pair[hidden] { display: none; }
/* Guest: a small switch at the right of "Who" */
.guest-switch { display: inline-flex; align-items: center; gap: 7px; cursor: pointer; }
.field .guest-switch input {
  position: relative;
  flex: none;
  width: 30px;
  height: 18px;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  outline: none;
  background: var(--btn-border-hover);
  appearance: none;
  cursor: pointer;
  transition: background-color .2s ease;
}
.field .guest-switch input::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--card);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .25);
  transition: transform .2s var(--ease);
}
.field .guest-switch input:checked { background: var(--accent); }
.field .guest-switch input:checked::after { transform: translateX(12px); }
.field .guest-switch input:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* suggestions while typing (as on sam26's team page) */
#point-edit .dialog-body { position: relative; }
.suggest {
  position: absolute;
  z-index: 6;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 4px;
  border: 1px solid var(--btn-border);
  border-radius: 12px;
  background: var(--card);
  box-shadow: var(--shadow-lift);
  transform-origin: top center;
  animation: suggest-in .16s var(--ease);
}
.suggest.up { transform-origin: bottom center; }
.suggest[hidden] { display: none; }
@keyframes suggest-in { from { opacity: 0; transform: translateY(-4px) scale(.98); } }
.suggest .sg-opt {
  display: block;
  width: 100%;
  min-height: 0;
  padding: 10px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--ink);
  font: 500 15px/20px var(--font-ui);
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.suggest .sg-opt:active { transform: none; }
.suggest .sg-opt.active { background: var(--btn-bg-hover); }
@media (hover: hover) { .suggest .sg-opt:hover { background: var(--btn-bg-hover); } }
/* the letters that matched what was typed */
.sg-opt mark { background: var(--mark); color: inherit; border-radius: 3px; box-shadow: 0 0 0 1px var(--mark); }
/* a guest's title and city after the name */
.sg-sub { margin-left: 8px; color: var(--ink-faint); font-size: 12.5px; font-weight: 400; }
/* the groups: Recent, or CGF Vernon and Guests */
.sg-head { padding: 8px 10px 4px; font: 700 10.5px/1.2 var(--font-ui); letter-spacing: .12em; text-transform: uppercase; color: var(--bronze); }
.sg-head:not(:first-child) { margin-top: 4px; padding-top: 10px; border-top: 1px solid var(--rule-soft); }
/* under Google's cities (their terms ask for it) */
.sg-powered { padding: 4px 10px 3px; text-align: right; font-size: 11px; color: var(--ink-faint); }
.sg-powered b { font-weight: 600; color: var(--ink-soft); }

/* ---------------------------------------------------------------- toast, print */
#toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--transport-h) + var(--safe-b) + 14px);
  z-index: 90;
  width: max-content;
  max-width: min(calc(100vw - 32px), 420px);
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font: 600 13.5px/1.35 var(--font-ui);
  text-align: center;
  box-shadow: var(--shadow-lift);
  pointer-events: none;
  transform: translateX(-50%);
  transition: opacity .18s ease, transform .18s ease;
}
#toast:not(.visible) { opacity: 0; transform: translate(-50%, 8px); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* A small breath between worship, spoken points and performances. */
.cue.grouped { border: 0; background: transparent; box-shadow: none; }
.cue.grouped .cue-row { border-inline: 1px solid var(--rule); }
.cue.grouped .group-start { margin-top: 10px; border-top: 1px solid var(--rule); border-start-start-radius: 14px; border-start-end-radius: 14px; }
.cue.grouped .group-start:first-child { margin-top: 0; }
.cue.grouped .group-start::before { display: none; }
.cue.grouped .group-end { border-bottom: 1px solid var(--rule); border-end-start-radius: 14px; border-end-end-radius: 14px; }

/* Completed programme entries remain available to open, edit and reorder. */
.cue-row.completed { opacity: .5; }
.dialog-foot { flex-wrap: wrap; }
.completion-toggle { display: flex; align-items: center; gap: 10px; flex: 0 0 100%; min-height: 44px; cursor: pointer; color: var(--ink-soft); font-size: 14px; }
.completion-toggle input { appearance: auto; width: 22px; height: 22px; margin: 0; accent-color: var(--accent); cursor: pointer; }
.completion-toggle[hidden] { display: none; }

.lyric-line strong { font-weight: 700; } /* repeated phrases */
