/* The Singing Bible — public site styles, v38 (second client-redesign pass).
   Layout philosophy: the page is a flex column sized to the visible viewport
   (100dvh) — brand, player, picks, actions, then a full-width white-on-black
   verse band pinned to the bottom. Vertical space flexes via clamp()/auto
   margins so the app fills the screen exactly at any height; if a viewport is
   shorter than the content minimum, the page scrolls normally.
   Background matched to the logo's white (#FEFEFE) so the logo appears
   transparent against the page.
   NOTE: the admin page (rendered by _worker.js) and admin/login.html also link
   this stylesheet for its :root tokens and base rules — keep token names and
   generic element rules stable. */

:root {
  /* Background tuned to match the logo image's near-white background. */
  --bg: #FEFEFE;
  --bg-elevated: #FFFFFF;

  /* Ink scale — keep generous contrast against the off-white background. */
  --ink: #1A1A1A;
  --ink-soft: #404040;
  --ink-muted: #707070;
  --ink-faint: #A0A0A0;

  /* Lines and surfaces. */
  --line: #E5E5E5;
  --line-strong: #C8C8C8;
  --disabled-bg: #F4F4F4;

  /* Gold accent borrowed from the logo's wordmark. Used sparingly. */
  --gold: #B8860B;
  --gold-soft: #D4A82E;

  /* Brand teal (v37). RGB 0,135,125 per Ron's spec — used for the Play button,
     the featured verse, the active loop toggle, and form accents. (The logo SVG
     carries its own near-identical teal, #01847d — normalized to #00877D in
     logo-tm.svg + icon.svg per Ron 2026-08-18: the teal is RGB 0,135,125,
     ALWAYS. Original designer logo.svg left untouched as archival source.) */
  --teal: #00877D;
  --teal-dark: #006F66;
  --teal-soft: rgba(0, 135, 125, 0.12);

  --dark: #0F0F0F;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.08);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.12);

  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-pill: 999px;

  --dur-fast: 140ms;
  --dur-med: 240ms;
  --ease: cubic-bezier(.2, .8, .2, 1);

  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
}

* { box-sizing: border-box; }
/* Defensive rule: ensure the `hidden` HTML attribute always wins, even when
   an element has an explicit `display:` rule. Without this, `.gate { display:
   flex }` and `.pick__menu--grid { display: grid }` override the browser's
   default `[hidden] { display: none }` (equal specificity, CSS later in the
   cascade wins), so setting element.hidden = true has no visual effect.
   Bug shipped in v35; fixed in v35.1. Pattern borrowed from common resets. */
[hidden] { display: none !important; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
button { font-family: inherit; }

/* Boot loader — soft pulse until the manifest loads. */
.boot {
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 400ms var(--ease);
}
.boot.is-hidden { opacity: 0; pointer-events: none; }
.boot__pulse {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--gold);
  opacity: 0.4;
  animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { transform: scale(0.8); opacity: 0.3; } 50% { transform: scale(1.0); opacity: 0.7; } }

/* ----- Password gate ----------------------------------------------------- */
/* Full-screen overlay shown until the user enters the correct password.
   The unlock state lives in localStorage (sb.gate.unlocked) with a 7-day TTL. */
.gate {
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: fadeIn 300ms var(--ease) both;
}
.gate__card {
  width: 100%;
  max-width: 380px;
  text-align: center;
}
.gate__logo {
  width: 100%;
  max-width: 320px;
  height: auto;
  margin: 0 auto 24px;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}
.gate__form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.gate__input {
  width: 100%;
  padding: 12px 16px;
  font-size: 16px;
  font-family: inherit;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  color: var(--ink);
  outline: none;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.gate__input:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(184, 134, 11, 0.15); }
.gate__submit {
  padding: 12px 20px;
  font-size: 15px;
  font-weight: 600;
  font-family: inherit;
  border: 1px solid var(--ink);
  border-radius: var(--radius-md);
  background: var(--ink);
  color: #fff;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.gate__submit:hover { background: var(--dark); border-color: var(--dark); }
.gate__error {
  margin-top: 12px;
  min-height: 20px;
  font-size: 13px;
  color: #b34242;
}

/* ----- Page layout ------------------------------------------------------- */
/* v38: full-viewport flex column. Sections constrain their own width; the page
   itself is full-bleed so the verse band can span edge to edge. `min-height`
   (not `height`) keeps short viewports scrollable instead of crushed. */
.page {
  width: 100%;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  animation: fadeIn 400ms var(--ease) both;
}

/* Brand: logo at top. v38: a tad smaller than v37 (360px -> 300px mobile,
   480px -> 400px desktop) so it doesn't dominate the top area. */
.brand {
  display: flex;
  justify-content: center;
  padding: clamp(8px, 1.8vh, 18px) 18px clamp(2px, 0.8vh, 8px);
}
.brand__logo {
  width: 100%;
  max-width: min(300px, 72vw);
  height: auto;
  user-select: none;
  -webkit-user-drag: none;
}
@media (min-width: 720px) {
  .brand { padding-top: clamp(12px, 2.2vh, 24px); }
  .brand__logo { max-width: 400px; }
}

/* ----- Inline player ----------------------------------------------------- */
/* v38: the player moved ABOVE the dropdown stack (mockup order: title,
   controls, scrubber right under the logo). */
.player {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(6px, 1.2vh, 12px);
  width: 100%;
  margin-top: clamp(2px, 1vh, 12px);
  padding: 4px 18px 0;
}
/* Now-playing track info, displayed above the controls. Single line: book +
   chapter. v36: subtitle line removed; title moved from Cormorant Garamond
   to Inter (body sans) at bold weight. */
.player__track {
  text-align: center;
  width: 100%;
  max-width: 520px;
  padding: 0 8px;
}
.player__track-title {
  font-family: var(--font-body);
  font-size: 20px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: 0.005em;
  line-height: 1.25;
}
@media (min-width: 720px) {
  .player__track-title { font-size: 22px; }
}
.player__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.player__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 8px;
  border-radius: 50%;
  color: var(--ink);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.player__btn:hover:not(:disabled) { background: rgba(0, 0, 0, 0.05); }
.player__btn:disabled { color: var(--ink-faint); cursor: default; }
.player__btn--primary {
  background: var(--teal);
  color: #fff;
  width: 48px;
  height: 48px;
  padding: 0;
  margin: 0 4px;
}
.player__btn--primary:hover:not(:disabled) { background: var(--teal-dark); transform: scale(1.04); }
.player__btn--primary:disabled { background: var(--disabled-bg); color: var(--ink-faint); }
.player__btn--secondary { width: 38px; height: 38px; padding: 0; }
.player__btn--secondary svg { display: block; }

/* Play/pause icon swap, v35.2: class-based instead of hidden-attribute-based.
   Default state (not playing): play icon visible, pause icon hidden.
   Playing state (button has .is-playing): play hidden, pause visible.
   Reason for the change: the v35 `el.iconPlay.hidden = true` approach relied
   on `[hidden] { display: none }` winning the cascade — which it does now,
   thanks to the v35.1 !important rule, but the click handler had a separate
   reliability issue (the swap happened on the 'play' audio event, which only
   fires if the audio successfully starts; if the audio request failed, the
   user saw a stuck play icon even though they clicked). Class-based makes
   the visual state independent of the audio element's events. */
.player__icon-pause { display: none; }
.player__btn--primary.is-playing .player__icon-play { display: none; }
.player__btn--primary.is-playing .player__icon-pause { display: block; }

/* Progress bar with elapsed/total. Inline below the buttons. */
.player__progress {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  max-width: 520px;
  padding: 0 4px;
}
.player__time {
  font-size: 12px;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  min-width: 36px;
  text-align: center;
}
.player__seek {
  position: relative;
  flex: 1;
  height: 20px;
  cursor: pointer;
  display: flex;
  align-items: center;
  /* v38: stop touch scrubs from being reinterpreted as page scrolls (which
     fired pointercancel and stranded the drag listeners — see app.js). */
  touch-action: none;
}
.player__seek::before {
  content: '';
  position: absolute;
  inset: 9px 0;
  background: var(--line);
  border-radius: 999px;
}
.player__seek-fill {
  position: absolute;
  left: 0;
  top: 9px;
  height: 2px;
  background: var(--ink);
  border-radius: 999px;
  width: 0%;
  pointer-events: none;
}
.player__seek-thumb {
  position: absolute;
  top: 50%;
  width: 12px;
  height: 12px;
  background: var(--ink);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  left: 0%;
  pointer-events: none;
  transition: transform var(--dur-fast) var(--ease);
}
.player__seek:hover .player__seek-thumb { transform: translate(-50%, -50%) scale(1.2); }

/* ----- Dropdown stack ("picks") ----------------------------------------- */
/* v36: single column on all viewports. Container constrained to ~480px and
   centered so the dropdowns line up visually with the logo (max-width 480px
   on desktop). The page wrapper stays wider so brand and player are
   unaffected. The v35 two-column desktop layout is gone. */
.picks {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(8px, 1.4vh, 12px);
  width: 100%;
  max-width: 516px; /* 480px column + its own 18px side padding */
  padding: clamp(10px, 2.4vh, 26px) 18px 0;
  /* v38: `auto` shares the viewport's leftover height with the auto margin on
     .actions — the picks cluster floats between player and action row, which
     is the mockup's rhythm. On short screens both autos collapse to 0 and the
     clamp() paddings keep the minimum breathing room. */
  margin: auto auto 0;
}

/* Individual dropdown. */
.pick { position: relative; }
.pick__trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  cursor: pointer;
  color: var(--ink);
  font-size: 16px;
  text-align: left;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.pick__trigger:hover { border-color: var(--line-strong); }
.pick__trigger:focus-visible { outline: none; border-color: var(--gold); box-shadow: 0 0 0 3px rgba(184, 134, 11, 0.15); }
.pick__trigger[aria-expanded="true"] {
  border-color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.pick__label {
  font-weight: 700;
  font-size: 16px;
  color: var(--ink-soft);
  letter-spacing: 0.01em;
}
.pick__label::after { content: ':'; }
.pick__value {
  flex: 1;
  color: var(--ink);
  font-weight: 700;
  font-size: 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pick__caret {
  flex-shrink: 0;
  color: var(--ink-muted);
  transition: transform var(--dur-fast) var(--ease);
}
.pick__trigger[aria-expanded="true"] .pick__caret { transform: rotate(180deg); }

/* Popup menu shared base. Floats below the trigger, has a soft shadow. */
.pick__menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  z-index: 30;
  padding: 6px;
  animation: menuOpen 160ms var(--ease) both;
}
.pick__menu--scroll { max-height: 320px; overflow-y: auto; }

/* Standard list option (translation, voice, style, book). */
.pick__option {
  display: block;
  width: 100%;
  padding: 9px 12px;
  border: none;
  background: transparent;
  text-align: left;
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.pick__option:hover:not(:disabled) { background: rgba(0, 0, 0, 0.04); }
.pick__option--selected { background: rgba(184, 134, 11, 0.08); }
.pick__option--selected::after {
  content: '✓';
  float: right;
  color: var(--gold);
  font-weight: 700;
}
.pick__option:disabled { color: var(--ink-faint); cursor: default; font-style: italic; }
.pick__option:disabled::after { content: ' · coming soon'; color: var(--ink-faint); font-style: italic; font-size: 12px; font-weight: 400; }

/* Chapter grid. 5 columns wide; scrolls vertically if needed. */
.pick__menu--grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
  padding: 10px;
  max-height: 280px;
  overflow-y: auto;
}
.chapter {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 600;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.chapter:hover:not(:disabled) { border-color: var(--ink); transform: scale(1.04); }
.chapter--playing { background: var(--ink); color: #fff; border-color: var(--ink); font-weight: 700; }
.chapter:disabled {
  color: var(--ink-faint);
  background: var(--disabled-bg);
  cursor: default;
  font-style: italic;
}

@keyframes menuOpen { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ===== v37 redesign additions ============================================ */

/* Loop / shuffle share the secondary button sizing. The loop toggle gets a
   teal "active" treatment when continuous-loop is ON. */
.player__btn.is-active { color: var(--teal); background: var(--teal-soft); }
.player__btn.is-active:hover:not(:disabled) { background: rgba(0, 135, 125, 0.2); }

/* ----- Featured verse band ----------------------------------------------- */
/* v38: full-width white-on-black band pinned to the bottom of the viewport
   (mockup). The quote must stay on ONE line at every width: fluid vw-based
   font size, floor tuned so 49 characters of Inter italic fit a 320px screen.
   The reference sits right-justified beneath it. */
.verse-band {
  flex-shrink: 0;
  width: 100%;
  background: var(--dark);
  color: #fff;
  padding: 10px clamp(12px, 4vw, 28px) calc(10px + env(safe-area-inset-bottom, 0px));
}
.verse-band__inner {
  /* Shrink the inner box to the quote line's own width (it is nowrap), capped
     to the viewport. This makes the box's right edge coincide with the closing
     quotation mark, so the right-justified reference below lands directly under
     the mark rather than at a wider 560px column edge. (v39, per Ron.) */
  width: max-content;
  max-width: 100%;
  margin: 0 auto;
  /* v39.17 (Ron): the band must be the SAME height everywhere. The fluid font
     sizes above shrink on narrow screens, which used to shrink the band with
     them; reserve the max-size content height (17px + 14px lines + 2px gap at
     1.45 line-height ≈ 47px) and center the text in it. */
  min-height: 47px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.verse-band__text {
  display: block;
  white-space: nowrap;
  text-align: center;
  font-style: italic;
  font-size: clamp(10px, 3.1vw, 17px);
  line-height: 1.45;
  letter-spacing: 0.005em;
}
.verse-band__ref {
  display: block;
  text-align: right;
  font-style: italic;
  font-size: clamp(9px, 2.7vw, 14px);
  color: rgba(255, 255, 255, 0.85);
  margin-top: 2px;
}

/* ----- Bottom action row ------------------------------------------------- */
.actions {
  /* v39.17 (Ron's mockups 2026-08-18): two stacked rows — links row
     (Feedback left, View/Hide Bible Text right) above the icon bar. */
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  max-width: 556px; /* 520px row + its own 18px side padding */
  /* v38: margin-top auto pins the action row (and the verse band after it) to
     the bottom of the viewport column; leftover height collects above it. */
  margin: auto auto 0;
  padding: 10px 18px clamp(8px, 1.6vh, 16px);
}
.actions__links {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  /* v39.17b (Ron): the links row spans exactly the dropdown column (.picks is
     516px incl. 18px side padding → 480px content), so with the offsets below
     "Feedback" left-aligns with the pick labels and the toggle's caret joins
     the dropdown carets' column — at every viewport width. Hamburger + share
     stay on the WIDER bar row, which keeps them prominent (Ron liked this). */
  max-width: 480px;
  margin: 0 auto;
}
.actions__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
}
.actions__feedback {
  /* 2px own padding + 12px = the pick trigger's 14px text inset. */
  margin-left: 12px;
  padding: 3px 2px;
  background: transparent;
  border: none;
  cursor: pointer;
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.actions__feedback:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--teal-soft); border-radius: var(--radius-sm); }
@media (min-width: 720px) { .actions__feedback { font-size: 16px; } }
/* The View/Hide toggle's caret points up when closed, down while open. */
.actions__link[aria-expanded="true"] .actions__caret { transform: rotate(180deg); }
.actions__caret { transition: transform var(--dur-fast) var(--ease); }
.actions__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  background: transparent;
  border: none;
  border-radius: var(--radius-md);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.actions__icon:hover { background: rgba(0, 0, 0, 0.05); }
.actions__icon svg { display: block; }
.actions__center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  flex: 1;
  min-width: 0;
}
.actions__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 3px 6px;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease);
}
/* v39.17b (Ron): the teal hover is DESKTOP-ONLY. On touch screens a tap
   sets :hover and it sticks, flip-flopping the label black/teal — so the
   hover rules live behind (hover: hover), which touch devices never match.
   Phones: black always, with a tap tint. */
@media (hover: hover) {
  .actions__link:hover { color: var(--teal); }
  .actions__link:hover .actions__caret { color: var(--teal); }
  .actions__feedback:hover { color: var(--teal); }
}
.actions__link:active { background: rgba(0, 0, 0, 0.05); }
.actions__caret { color: var(--ink-muted); flex-shrink: 0; }
@media (min-width: 720px) { .actions__link { font-size: 16px; } }
/* Caret right edge 14px in from the column edge = the pick carets' inset. */
.actions__links .actions__link { padding-right: 14px; }

/* ----- Toast (share confirmation) ---------------------------------------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: 28px;
  transform: translate(-50%, 12px);
  max-width: calc(100% - 32px);
  padding: 12px 18px;
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  z-index: 200;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-med) var(--ease), transform var(--dur-med) var(--ease);
}
.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* ----- Bottom sheet (modal) ---------------------------------------------- */
.sheet {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.sheet__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 15, 15, 0.42);
  animation: fadeIn 200ms var(--ease) both;
}
.sheet__panel {
  position: relative;
  width: 100%;
  max-width: 520px;
  max-height: 84vh;
  /* v38: dvh + 100% cap so the panel never outgrows the visible viewport when
     mobile browser toolbars are expanded (84vh could clip the header). */
  max-height: min(84dvh, 100%);
  display: flex;
  flex-direction: column;
  background: var(--bg-elevated);
  border-radius: 18px 18px 0 0;
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: sheetUp 260ms var(--ease) both;
}
.sheet__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px 12px;
  border-bottom: 1px solid var(--line);
}
.sheet__title { margin: 0; font-size: 18px; font-weight: 700; color: var(--ink); }
.sheet__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: none;
  background: transparent;
  color: var(--ink-muted);
  border-radius: 50%;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.sheet__close:hover { background: rgba(0, 0, 0, 0.06); color: var(--ink); }
.sheet__body { padding: 16px 18px 24px; overflow-y: auto; }
@keyframes sheetUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
/* v38: the sheet slides up from the bottom at EVERY viewport size. (The v37
   desktop variant centered it like a popup, which read as disjointed — removed
   per Randy's 2026-07-05 note.) */

/* Sheet content: prose panels, nav menu, add-to-home, song form. */
.sheet-prose { font-size: 15px; color: var(--ink-soft); line-height: 1.55; }
.sheet-prose p { margin: 0 0 12px; }
.sheet-prose p:last-child { margin-bottom: 0; }
.sheet-prose--center { text-align: center; }
.sheet-soon { color: var(--ink-muted); font-size: 16px; padding: 18px 0; }
/* v39.10: About panel typography (Ron's copy, 2026-08-12). */
.sheet-about__title { margin: 0 0 14px; font-size: 19px; font-weight: 800; color: var(--ink); line-height: 1.3; }
.sheet-about__h { margin: 20px 0 8px; font-size: 15px; font-weight: 800; color: var(--teal-dark); line-height: 1.3; }
.sheet-about__close { font-weight: 700; color: var(--ink); }
.sheet-link { color: var(--teal); font-weight: 700; text-decoration: none; }
.sheet-link:hover { text-decoration: underline; }
.sheet-back {
  display: inline-block;
  margin-bottom: 12px;
  padding: 0;
  background: transparent;
  border: none;
  color: var(--ink-muted);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease);
}
.sheet-back:hover { color: var(--teal); }

.navmenu { display: flex; flex-direction: column; }
.navmenu__item {
  display: block;
  width: 100%;
  padding: 13px 6px;
  text-align: left;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease);
}
.navmenu__item:last-child { border-bottom: none; }
.navmenu__item:hover { color: var(--teal); }

.a2hs { display: grid; gap: 18px; }
.a2hs__title { margin-bottom: 8px; font-size: 15px; font-weight: 700; color: var(--ink); }
.a2hs__steps { margin: 0; padding-left: 20px; color: var(--ink-soft); font-size: 14px; line-height: 1.6; }
.a2hs__steps li { margin-bottom: 4px; }

.songform__intro { margin: 0 0 14px; font-size: 15px; color: var(--ink-soft); }
.field { display: flex; flex-direction: column; gap: 5px; margin-bottom: 12px; }
.field > span { font-size: 13px; font-weight: 700; color: var(--ink-soft); }
.field input,
.field textarea,
.field select {
  width: 100%;
  padding: 10px 12px;
  font-size: 16px;
  font-family: inherit;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--bg-elevated);
  color: var(--ink);
  outline: none;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.field input:focus,
.field textarea:focus,
.field select:focus { border-color: var(--teal); box-shadow: 0 0 0 3px var(--teal-soft); }
.field textarea { resize: vertical; min-height: 84px; }
/* Contact form (v39.27): honeypot stays in the layout tree but far off-screen
   (display:none would tip off smarter bots); checkbox row lays out inline. */
.field--hp { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }
.field--check { flex-direction: row; align-items: center; gap: 10px; }
.field--check input { width: 18px; height: 18px; accent-color: var(--teal); flex: none; }
.field--check > span { font-size: 14px; font-weight: 400; color: var(--ink); }
.songform__note { margin: 0 0 12px; font-size: 12px; color: var(--ink-muted); }
.songform__err { min-height: 18px; margin-bottom: 8px; color: #b34242; font-size: 13px; }
.songform__submit {
  width: 100%;
  padding: 12px 18px;
  font-size: 15px;
  font-weight: 700;
  font-family: inherit;
  border: none;
  border-radius: var(--radius-md);
  background: var(--teal);
  color: #fff;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.songform__submit:hover { background: var(--teal-dark); }
.songform__thanks { text-align: center; padding: 16px 0; }
.songform__check {
  width: 54px;
  height: 54px;
  margin: 0 auto 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--teal-soft);
  color: var(--teal);
  font-size: 28px;
  font-weight: 700;
}
.songform__thanks p { margin: 0 0 8px; color: var(--ink-soft); }
.songform__note { font-size: 12px; color: var(--ink-faint); }
/* v39.17: the plain-address alternative under each form (still NO mailto). */
.songform__alt { margin-top: 12px; font-size: 13px; color: var(--ink-muted); text-align: center; }
/* v39.17b: the auto-attached deep link shown under the Feedback context line. */
.songform__where { margin: -6px 0 10px; font-size: 12px; color: var(--ink-faint); word-break: break-all; }

/* ----- v38 additions ------------------------------------------------------ */

/* Visible keyboard focus for the round, borderless controls (the UA default
   ring reads poorly on circular transparent buttons). */
.player__btn:focus-visible,
.actions__icon:focus-visible,
.actions__link:focus-visible,
.sheet__close:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}
.player__seek:focus-visible { outline: 2px solid var(--teal); outline-offset: 4px; border-radius: 4px; }

/* Very narrow screens (320-374px): compress the 7-button control row so it
   never overflows horizontally (v37 needed 356px and clipped on a 320px SE). */
@media (max-width: 374px) {
  .player__controls { gap: 3px; }
  .player__btn--secondary { width: 34px; height: 34px; }
  .player__btn--primary { width: 44px; height: 44px; margin: 0 2px; }
  .brand__logo { max-width: 240px; }
  .pick__trigger { padding: 8px 12px; }
}

/* Platform cards inside the Add to Home Screen panel (v38 rebuild). */
.a2hs__badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.a2hs__badge svg { display: block; color: var(--ink-soft); }
.a2hs__hint { margin: 10px 0 0; font-size: 13px; color: var(--ink-muted); }

/* --- v39.9: Bible text panel ("View Bible Text", Ron's mockup) ----------- */
/* Sits in the dropdowns' slot: same width, side padding, and bottom-hugging
   auto margins as .picks, so opening the panel swaps cleanly into "exactly
   that space" between the player and the action row. */
.textpanel {
  position: relative;
  width: 100%;
  max-width: 516px;
  margin: auto auto 0;
  padding: clamp(10px, 2.4vh, 26px) 18px 0;
  animation: tpIn 260ms var(--ease) both;
  /* v39.20: the card takes exactly the height the viewport has left, so the
     verse band below always stays above the fold (the old fixed 42dvh cap
     pushed it off-screen on shorter desktop windows). flex-basis 0 makes the
     math exact: card = clamp(min, leftover space, max). Below the floor the
     page scrolls normally, like every other over-short layout. */
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-height: 165px;
  max-height: 466px; /* preserves the old tall-screen look: 440px card + max top pad */
}
@keyframes tpIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.textpanel__scroll {
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Fills the flex-sized card above; min-height 0 lets it shrink with it. */
  flex: 1;
  min-height: 0;
  padding: 16px 18px; /* symmetric since v39.20 — the in-card chevron is long gone (v39.17) */
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--ink);
  text-align: left;
}
.tp-verse {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 10px;
  margin-bottom: 10px;
}
.tp-verse:last-child { margin-bottom: 0; }
.tp-verse__num { font-weight: 500; white-space: nowrap; }
.tp-note {
  color: var(--ink-muted);
  text-align: center;
  padding: 34px 0;
}
/* Share sheet (v39.15): grid of copy + social options. Anchors and buttons
   share one look; icons inherit currentColor so the theme stays coherent. */
.sharegrid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  padding: 4px 0;
}
.sharegrid__btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 14px 6px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-elevated);
  color: var(--ink-soft);
  font: inherit;
  font-size: 13px;
  text-decoration: none;
  cursor: pointer;
}
.sharegrid__btn:hover { border-color: var(--line-strong); color: var(--ink); }
.sharegrid__btn svg { width: 26px; height: 26px; display: block; }
.sharegrid__label { line-height: 1; }
