/*
  The look of churchhelm.stream: the operator's page (.operator) and the big screen (.screen).
  The colours are Church Helm's brand colours (app/static/css/brand.css).
  Text and controls are checked for contrast in both light and dark mode.
*/

/* ---- The brand font, kept on this site so nothing is loaded from elsewhere ---- */
@font-face { font-family: "Sora"; src: url("../brand/fonts/Sora-Regular.ttf") format("truetype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Sora"; src: url("../brand/fonts/Sora-SemiBold.ttf") format("truetype"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Sora"; src: url("../brand/fonts/Sora-Bold.ttf") format("truetype"); font-weight: 700; font-display: swap; }

/* ---- Colours: light mode by default ---- */
:root {
  --bg: #F7F3EA;
  --panel: #FFFFFF;
  --text: #1E3A2F;
  --muted: #4A5A52;
  --border: #8A9389;
  --soft: #EDE7D8;
  --accent: #1E3A2F;
  --on-accent: #FFFFFF;
  --mark: #7A5C18;
  --focus: #7A5C18;
  --error: #9B2C1F;
  --font: "Sora", system-ui, -apple-system, "Segoe UI", sans-serif;
  color-scheme: light;
}

/* The dark colours, as one list used by the two rules below. */
@media (prefers-color-scheme: dark) {
  /* Dark for people whose device asks for it, unless they've chosen light here. */
  :root:not([data-theme="light"]) {
    --bg: #17302A; --panel: #1F3A2F; --text: #F2EEE3; --muted: #CCD5CC; --border: #8FA598; --soft: #2B4A3D;
    --accent: #E0B04A; --on-accent: #17302A; --mark: #E0B04A; --focus: #E0B04A; --error: #FFB4A8;
    color-scheme: dark;
  }
}
/* Dark for people who have chosen it here. */
:root[data-theme="dark"] {
  --bg: #17302A; --panel: #1F3A2F; --text: #F2EEE3; --muted: #CCD5CC; --border: #8FA598; --soft: #2B4A3D;
  --accent: #E0B04A; --on-accent: #17302A; --mark: #E0B04A; --focus: #E0B04A; --error: #FFB4A8;
  color-scheme: dark;
}

/* ---- Basics ---- */
* { box-sizing: border-box; }
/* The hidden attribute must always win, even over a rule that sets how something is laid out. */
[hidden] { display: none !important; }
body { margin: 0; font-family: var(--font); line-height: 1.55; }
h1, h2, h3 { line-height: 1.25; margin: 0 0 .5rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: .95rem; margin-top: 1rem; }
/* One clear focus outline everywhere, for people using a keyboard. */
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
/* Headings that receive focus from script don't need the outline; a screen reader announces them. */
h2:focus, h3:focus { outline: none; }

/* ---- The operator's page ---- */
.operator { background: var(--bg); color: var(--text); }
/* Hidden off-screen until a keyboard user reaches it. */
.skip { position: absolute; left: -999px; top: 0; background: var(--panel); color: var(--text); padding: .5rem 1rem; z-index: 30; }
.skip:focus { left: .5rem; top: .5rem; }

/* The thin bar shown along the top while loading. */
.loadbar { position: fixed; inset: 0 0 auto 0; height: 3px; background: #E0B04A; box-shadow: 0 1px 0 var(--mark); z-index: 40; }

/* The header: the logo, the page's name and the tools, wrapping on narrow screens. */
.topbar { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1rem; padding: .75rem 1rem; background: var(--panel); border-bottom: 1px solid var(--border); }
.topbar h1 { font-size: 1.05rem; margin: 0; }
.topbar-tools { display: flex; flex-wrap: wrap; gap: .5rem; margin-left: auto; }
.logo { height: 32px; width: auto; }
/* Only the logo that suits the current background is shown. */
.logo.on-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .logo.on-light { display: none; }
  :root:not([data-theme="light"]) .logo.on-dark { display: block; }
}
:root[data-theme="dark"] .logo.on-light { display: none; }
:root[data-theme="dark"] .logo.on-dark { display: block; }

/* One column on phones. Wider screens get a second column (see the end of this section). */
.layout { display: grid; gap: 1rem; padding: 1rem; max-width: 1400px; margin: 0 auto; }
.reading, .side { display: grid; gap: 1rem; align-content: start; min-width: 0; }
.panel { background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 1rem; min-width: 0; }

/* Form parts. */
form { display: flex; flex-wrap: wrap; gap: .75rem; align-items: flex-start; }
.field { display: grid; gap: .25rem; margin-bottom: .75rem; }
form .field { margin-bottom: 0; }
.field.grow { flex: 1 1 14rem; }
label { font-weight: 600; font-size: .9rem; }
input[type="search"], select { font: inherit; color: var(--text); background: var(--panel); border: 1px solid var(--border); border-radius: 8px; padding: .55rem .7rem; min-height: 44px; width: 100%; }
input[type="range"] { width: 100%; accent-color: var(--accent); min-height: 24px; }
/* Tick boxes sit beside their words. */
.check { display: flex; align-items: center; gap: .5rem; font-weight: 400; min-height: 44px; }
.check input { width: 20px; height: 20px; accent-color: var(--accent); }
.hint { color: var(--muted); font-size: .85rem; margin: .25rem 0 .5rem; }
form > .button { margin-top: 1.6rem; }

/* Buttons: at least 44px tall, for fingers on a phone in a dim room. */
.button { font: inherit; font-weight: 600; min-height: 44px; padding: .5rem 1rem; border-radius: 8px; border: 1px solid var(--border); background: var(--soft); color: var(--text); cursor: pointer; }
.button.primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.button.quiet { background: transparent; font-weight: 400; }
.button:disabled { background: transparent; color: var(--muted); border-style: dashed; cursor: not-allowed; }
/* A button that's switched on (Blank or Screen saver) looks switched on as well as being announced. */
.button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }

/* A link that looks like a button, and the page shown to anyone not signed in. */
a.button { display: inline-flex; align-items: center; text-decoration: none; }
.signed-out { max-width: 36rem; margin: 3rem auto; padding: 0 1rem; }
.link-row { display: flex; flex-wrap: wrap; gap: .5rem; }

/* For words only screen readers need. */
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* Messages, and the buttons offered with them. */
.message { margin: .75rem 0 0; min-height: 1.5em; }
.message.error { color: var(--error); font-weight: 600; }
.choices { display: flex; flex-wrap: wrap; gap: .5rem; margin: .5rem 0; }
.choices:empty { margin: 0; }

/* The book and chapter choosers: as many columns as fit. */
.picker { margin-top: 1rem; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr)); gap: .4rem; }
.grid.numbers { grid-template-columns: repeat(auto-fill, minmax(3.25rem, 1fr)); }
.grid .button { padding: .4rem; font-weight: 400; overflow-wrap: anywhere; }

/* The chapter: heading between its Previous and Next buttons. */
.chapter-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .5rem; }
.chapter-head h2 { margin: 0; text-align: center; flex: 1 1 8rem; }
.verses, .results { list-style: none; margin: 0; padding: 0; }
/* Each verse is one whole button, so it's easy to hit. */
.verse { display: block; width: 100%; text-align: left; font: inherit; color: inherit; background: transparent; border: 0; border-left: 4px solid transparent; padding: .4rem .6rem; cursor: pointer; border-radius: 4px; min-height: 24px; }
.verse:hover { background: var(--soft); }
.verse[aria-pressed="true"] { background: var(--soft); border-left-color: var(--mark); }
.num { font-weight: 700; font-size: .8em; color: var(--muted); margin-right: .35em; }
/* The verses the congregation can see: a solid highlight that can be spotted at a glance, whichever other verses are
   chosen or hovered over. The label says it in words too, so colour isn't the only clue. It sits in line with the
   words and the lettering keeps its weight, so the verses around it don't shift as the highlight moves on. */
.verse.is-live, .verse.is-live:hover { background: var(--accent); color: var(--on-accent); border-left-color: var(--accent); }
.verse.is-live .num { color: var(--on-accent); }
.verse.is-live::before { content: "On screen"; display: inline-block; margin-right: .5em; padding: 0 .45em; border-radius: 4px; background: var(--on-accent); color: var(--accent); font-size: .75em; font-weight: 700; line-height: 1.5; }
.credit { color: var(--muted); font-size: .8rem; margin: .75rem 0 0; }
.results li + li { border-top: 1px solid var(--soft); }
.result-ref { display: block; font-weight: 600; }

/* Placeholder lines shown while a chapter loads. */
.skeleton { height: 1.1rem; border-radius: 4px; background: var(--soft); margin: .6rem 0; animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .45; } }
/* No moving effects for people who've asked their device to avoid them. */
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

/* Scrollbars inside panels use the page's colours, so they aren't a bright stripe in dark mode. */
.reading, .side, .preview, .verses, #results, .picker { scrollbar-color: var(--border) transparent; }

/* The two small previews. Their height is fixed, so the buttons below don't move as longer or shorter verses come and go. */
.status { font-weight: 600; margin: 0 0 .5rem; }
.preview { border: 1px solid var(--border); border-radius: 8px; padding: .6rem .75rem; background: var(--bg); height: 9rem; overflow-y: auto; font-size: .9rem; overflow-wrap: anywhere; }
.preview.live { border: 2px solid var(--mark); }
.preview strong { display: block; }

/* The main control buttons: "Show" across the top and the other four beneath it. */
.actions { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: .6rem; }
.actions .wide { grid-column: 1 / -1; }
.actions .button { padding: .5rem .25rem; }

/* The church's own pictures and pages: a small view beside the name, with the buttons underneath. However many are
   added, the list scrolls inside its own box, so the panels below it stay within reach. */
.picture-list { list-style: none; margin: .5rem 0 0; padding: 0; max-height: 20rem; overflow-y: auto; scrollbar-color: var(--border) transparent; }
.picture-row { display: grid; grid-template-columns: 5rem minmax(0, 1fr); gap: .25rem .6rem; align-items: start; padding: .5rem 0; }
.picture-row + .picture-row { border-top: 1px solid var(--soft); }
.picture-row img { grid-row: span 2; width: 5rem; height: 3rem; object-fit: contain; background: #000000; border-radius: 4px; }
.picture-name { font-size: .85rem; overflow-wrap: anywhere; }
.picture-buttons, .button-row { display: flex; flex-wrap: wrap; gap: .4rem; }
.on-screen { font-weight: 600; color: var(--mark); }
/* The small picture in "On screen now". */
.preview img { display: block; max-width: 100%; max-height: 5rem; margin-top: .25rem; }

/* The screen saver chooser: as many small pictures across as fit, scrolling inside its box. Its round buttons stay
   visible, so the choice isn't shown by colour alone. */
.saver-choices { position: relative; border: 0; margin: 0; padding: 0; min-width: 0; }
.saver-choices legend { padding: 0; }
.saver-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr)); gap: .5rem; max-height: 19rem; overflow-y: auto; scrollbar-color: var(--border) transparent; padding: .25rem; }
.saver-choice { display: block; font-weight: 400; font-size: .8rem; line-height: 1.3; cursor: pointer; }
.saver-choice img { display: block; width: 100%; height: auto; border-radius: 4px; }
.saver-choice span { display: flex; align-items: flex-start; gap: .3rem; padding-top: .25rem; }
.saver-choice input { flex: none; width: 18px; height: 18px; margin: 0; accent-color: var(--accent); }

progress { width: 100%; height: 12px; accent-color: var(--accent); margin-bottom: .5rem; }

/* The shortcuts popup. */
dialog { border: 1px solid var(--border); border-radius: 12px; background: var(--panel); color: var(--text); max-width: min(32rem, calc(100vw - 2rem)); padding: 1.25rem; }
dialog::backdrop { background: rgba(0, 0, 0, .6); }
.keys { display: grid; grid-template-columns: auto 1fr; gap: .4rem 1rem; margin: 0 0 1rem; }
.keys dt { font-weight: 600; }
.keys dd { margin: 0; }

/* Phones held upright: the controls stay along the bottom edge. It's only done on screens tall enough
   to spare the room, and the extra padding stops the bar from covering whatever has keyboard focus. */
@media (max-width: 899px) and (min-height: 480px) {
  html { scroll-padding-bottom: 8.5rem; }
  .operator { padding-bottom: 8.5rem; }
  .actions { position: fixed; left: 0; right: 0; bottom: 0; border-radius: 12px 12px 0 0; border-width: 1px 0 0; z-index: 20; }
}
/* Wider screens: the Bible on the left, and the controls always in view on the right. */
@media (min-width: 900px) {
  .layout { grid-template-columns: minmax(0, 3fr) minmax(20rem, 2fr); align-items: start; }
  .side { position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow-y: auto; }
}

/* Wider screens with room to spare: the page itself stops scrolling, and each side scrolls in its own box, so moving
   through a reading never shifts the page. Very short windows, such as a zoomed-in browser, keep ordinary page scrolling. */
@media (min-width: 900px) and (min-height: 560px) {
  .operator { height: 100vh; height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
  .topbar { flex: none; }
  .layout { flex: 1 1 auto; min-height: 0; width: 100%; grid-template-rows: minmax(0, 1fr); align-items: stretch; }
  /* Each column fills the height. Anything too tall for its column scrolls inside it. */
  .side { position: static; max-height: none; min-height: 0; }
  .reading { display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
  .reading > .panel { flex: none; }
  /* The chapter takes whatever height is left, and only its verses scroll, so its heading and buttons stay in view. */
  .reading > .chapter-panel { flex: 1 1 14rem; min-height: 14rem; display: flex; flex-direction: column; }
  /* The padding leaves room for the focus outline, which would otherwise be cut off at the box's edges. */
  .chapter-panel .verses { flex: 1 1 0; min-height: 0; overflow-y: auto; padding: .25rem; }
  /* The book chooser and search results can be long, so they scroll in their own space and leave room for the chapter. */
  .picker { max-height: 35vh; overflow-y: auto; padding: .25rem; }
  .reading > #results { max-height: 35vh; overflow-y: auto; }
}

/* ---- The big screen ---- */
.screen { margin: 0; height: 100vh; overflow: hidden; }
/* The three colour choices. */
.screen[data-look="dark"] { background: #000000; color: #FFFFFF; }
.screen[data-look="forest"] { background: #1E3A2F; color: #FFFFFF; }
.screen[data-look="light"] { background: #FFFFFF; color: #1E3A2F; }
.screen[data-font="serif"] .words { font-family: Georgia, "Times New Roman", serif; }
.screen[data-align="left"] .words { text-align: left; }
.screen[data-align="center"] .words { text-align: center; }

/* The whole screen: the passage in the middle, and the credit along the bottom. */
.stage { height: 100vh; padding: 4vh 5vw 2vh; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.fit { flex: 1 1 auto; min-height: 0; width: 100%; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.words { width: 100%; line-height: 1.35; }
.title { font-size: .62em; font-weight: 600; margin: 0 0 .5em; opacity: .9; }
.screen-verses { margin: 0; }
.screen-verses sup { font-size: .55em; font-weight: 700; margin-right: .2em; }
/* The credit is required with licensed text, so it's always shown with a passage. */
.screen-credit { margin: 1vh 0 0; font-size: max(14px, 1.8vh); text-align: center; }
/* A screen saver fills the whole screen. Someone's own picture is shown whole, with black in any space left over. */
.screen-saver, .screen-picture { position: fixed; inset: 0; width: 100%; height: 100%; }
.screen-saver { object-fit: cover; }
.screen-picture { object-fit: contain; }
.waiting { font-size: 3vh; margin: 0; }

/* Which parts show in each mode. Blank shows nothing at all. */
.screen .screen-saver, .screen .screen-picture, .screen .fit, .screen .screen-credit, .screen .waiting { display: none; }
.screen[data-mode="waiting"] .waiting { display: block; }
.screen[data-mode="text"] .fit { display: flex; }
.screen[data-mode="text"] .screen-credit { display: block; }
.screen[data-mode="saver"] .screen-saver { display: block; }
.screen[data-mode="picture"] .screen-picture { display: block; }
/* Blank always means fully black, whichever colours are chosen, so the screen really goes dark. So does the space around a picture. */
.screen[data-mode="blank"], .screen[data-mode="picture"], .screen[data-mode="saver"] { background: #000000; }

/* The full screen button: gone once full screen is on, so the congregation never sees it. */
.fullscreen { position: fixed; right: 1rem; bottom: 1rem; font: 600 1rem var(--font); min-height: 44px; padding: .5rem 1rem; border-radius: 8px; border: 1px solid #FFFFFF; background: #1E3A2F; color: #FFFFFF; cursor: pointer; }
/* The mouse pointer disappears when it hasn't moved for a few seconds. */
.screen.idle { cursor: none; }
