/* Official King Fahd Complex Warsh script font (uthmanic_warsh_v21) - the
   same typeface family the printed Madinah Warsh mushaf's text was set in,
   and the one this app's Quran text was originally encoded for. */
@font-face {
  font-family: "UthmanicWarsh";
  src: url("fonts/UthmanicWarshV21.ttf") format("truetype");
  font-display: swap;
}

:root {
  --bg: #faf7f0;
  --sidebar-bg: #ffffff;
  --ink: #2b2620;
  --muted: #8a8070;
  --accent: #8a6d3b;
  --border: #e8e0d0;
  --page-bg: #fffdf6;
  --control-bg: #ffffff;
  --control-hover: #f3ede0;
  --active-bg: #efe4c8;
  --shadow: rgba(0, 0, 0, 0.12);
  --backdrop: rgba(0, 0, 0, 0.25);
  --debug-bg: rgba(30, 28, 24, 0.88);
  --debug-ink: #e8e2d4;
  --wrong: #c0392b;
  --uncertain: #b8860b;
  --record-live: #b23b3b;
}

/* Set on <html> by the inline script in <head> (to decide before first
   paint) and by the toggle in app.js. Phones default to this; desktop
   defaults to the light palette above. */
[data-theme="dark"] {
  --bg: #171511;
  --sidebar-bg: #201c17;
  --ink: #ece6d8;
  --muted: #a89f8c;
  --accent: #d1a44e;
  --border: #3a352b;
  --page-bg: #211d17;
  --control-bg: #2a251e;
  --control-hover: #37311f;
  --active-bg: #423823;
  --shadow: rgba(0, 0, 0, 0.5);
  --backdrop: rgba(0, 0, 0, 0.6);
  --debug-bg: rgba(0, 0, 0, 0.75);
  --debug-ink: #e8e2d4;
  --wrong: #e0705a;
  --uncertain: #dcaa4c;
  --record-live: #c0392b;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: "Scheherazade New", "Amiri", serif;
  background: var(--bg);
  color: var(--ink);
}

.app {
  position: relative;
  display: flex;
  /* 100vh is the *largest possible* viewport, ignoring the browser's own
     address/nav bars - Android Chrome's address bar in particular shows up
     on top of that space rather than shrinking it, so 100vh ends up taller
     than what's actually visible, pushing the header/bottom-bar off-screen
     until you scroll. 100dvh ("dynamic viewport height") is meant to track
     the real visible area as browser UI shows/hides - but Android Chrome has
     a known bug where it can compute dvh using a stale metric carried over
     specifically across a page *reload*, rather than re-measuring. The
     --vh custom property (set from window.innerHeight in app.js, on load
     and on resize) is the reliable fallback for that case: JS always
     re-measures correctly, so it's listed last to win over both. Unsupported
     browsers simply ignore whichever declaration they don't understand and
     keep the one above it. */
  height: 100vh;
  height: 100dvh;
  height: calc(var(--vh, 1vh) * 100);
  overflow: hidden;
}

.sidebar {
  position: absolute;
  inset-inline-start: 0;
  top: 0;
  height: 100%;
  width: 280px;
  z-index: 20;
  background: var(--sidebar-bg);
  border-left: 1px solid var(--border);
  box-shadow: 4px 0 16px var(--shadow);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform: translateX(0);
  transition: transform 0.2s ease;
}

.app.sidebar-collapsed .sidebar {
  /* Slides fully off-canvas rather than shrinking, so it floats over the
     reader instead of taking up layout space when expanded. */
  transform: translateX(100%);
  border-left: none;
  box-shadow: none;
}

.sidebar-backdrop {
  position: absolute;
  inset: 0;
  z-index: 15;
  background: var(--backdrop);
  opacity: 1;
  transition: opacity 0.2s ease;
}

.app.sidebar-collapsed .sidebar-backdrop {
  opacity: 0;
  pointer-events: none;
}

.sidebar-header {
  padding: 16px;
  /* Extra room on the toggle's side so the always-on-top ☰ button (which
     shares this corner with the sidebar, since it must stay clickable while
     the sidebar is open) never sits on top of the title or search box. RTL
     text starts at inline-start, same corner the toggle occupies, so it's
     inline-start padding that needs to grow, not inline-end. */
  padding-inline-start: 56px;
  border-bottom: 1px solid var(--border);
}

.sidebar-header h1 {
  margin: 0 0 10px;
  font-size: 20px;
  font-family: "Segoe UI", Tahoma, sans-serif;
}

#surah-search {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: inherit;
  font-size: 14px;
}

.mode-switch {
  display: flex;
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}

.mode-option {
  flex: 1;
  padding: 7px 4px;
  border: none;
  background: var(--control-bg);
  color: var(--muted);
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
}

.mode-option + .mode-option {
  border-inline-start: 1px solid var(--border);
}

.mode-option.active {
  background: var(--active-bg);
  color: var(--accent);
  font-weight: 700;
}

.surah-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
}

.surah-list li {
  padding: 10px 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  border-bottom: 1px solid var(--border);
  font-size: 18px;
}

.surah-list li:hover {
  background: var(--control-hover);
}

.surah-list li.active {
  background: var(--active-bg);
  font-weight: 700;
}

.surah-number {
  font-family: "Segoe UI", Tahoma, sans-serif;
  font-size: 12px;
  color: var(--muted);
  width: 24px;
  text-align: center;
  flex-shrink: 0;
}

.reader {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative; /* anchors the absolutely-positioned debug panel */
}

/* Top bar: menu access + read-only position info (surah, juz'). Actions
   (mic/peek/theme) live in .bottom-bar instead - this bar is purely
   informational, per the "info on top, actions on bottom" layout. Padded for
   the iPhone notch/Dynamic Island (env() only has an effect where
   viewport-fit=cover is set, which it is, in <head>). */
.reader-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(10px + env(safe-area-inset-top)) 14px 10px;
  border-bottom: 1px solid var(--border);
}

.reading-info {
  flex: 1;
  min-width: 0;
  text-align: center;
  font-family: "Segoe UI", Tahoma, sans-serif;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#info-surah {
  color: var(--accent);
  font-weight: 700;
  font-size: 16px;
}

.info-sep {
  margin: 0 6px;
  color: var(--muted);
  opacity: 0.6;
}

#info-juz {
  color: var(--muted);
  font-size: 13px;
}

.sidebar-toggle {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--control-bg);
  color: var(--accent);
  font-size: 17px;
  cursor: pointer;
  /* Must stay above the overlay sidebar (z-index 20), since it shares the
     screen edge the sidebar slides in from and needs to remain clickable
     while it's open - flex items respect z-index without needing an
     explicit non-static position. */
  z-index: 30;
}

.sidebar-toggle:hover {
  background: var(--control-hover);
}

.debug-toggle {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--control-bg);
  font-size: 16px;
  cursor: pointer;
  opacity: 0.55;
}

.debug-toggle.active {
  opacity: 1;
  border-color: #1a73e8;
  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.25);
}

.debug-panel {
  position: absolute;
  bottom: 12px;
  inset-inline-start: 12px;
  z-index: 10;
  background: var(--debug-bg);
  color: var(--debug-ink);
  font-family: "Consolas", "Menlo", monospace;
  font-size: 12px;
  direction: ltr;
  text-align: left;
  padding: 8px 12px;
  border-radius: 6px;
  white-space: pre;
}

/* Bottom bar: the mic (biggest, primary action), peek and theme toggles,
   and the trust meter while recording. Padded for the iPhone home-indicator
   safe area, same reasoning as the header's notch padding above. */
.bottom-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}

.record-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  border: none;
  border-radius: 50%;
  background: var(--control-bg);
  color: var(--accent);
  box-shadow: 0 2px 8px var(--shadow);
  cursor: pointer;
  flex-shrink: 0;
}

.record-toggle.recording {
  background: var(--record-live);
  color: #fff;
}

.peek-toggle,
.theme-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--control-bg);
  color: var(--ink);
  cursor: pointer;
  flex-shrink: 0;
}

.peek-toggle {
  opacity: 0.55;
}

.peek-toggle.active {
  opacity: 1;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 30%, transparent);
}

.trust-meter {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: "Segoe UI", Tahoma, sans-serif;
  font-size: 13px;
  color: var(--muted);
}

.trust-bar {
  width: 60px;
  height: 8px;
  border-radius: 4px;
  background: var(--border);
  overflow: hidden;
}

.trust-bar-fill {
  height: 100%;
  width: 0%;
  background: var(--muted);
  transition: width 0.2s ease, background-color 0.3s ease;
}

#trust-value {
  transition: color 0.3s ease;
}

/* Per-chunk latency readout (network vs GPU split, fed by record.js) - shown
   while recording so the numbers are readable on a phone, where there's no
   console. Latin measurement text inside an RTL bar needs its own base
   direction or the "net X · gpu Y" parts render out of order. */
.timing-readout {
  direction: ltr;
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.page-area {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 24px;
  overflow: hidden;
}

.page-frame {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(680px, 100%);
  height: 100%;
  max-height: 880px;
  background: var(--page-bg);
  border: 2px solid var(--accent);
  border-radius: 6px;
  outline: 1px solid var(--border);
  outline-offset: 6px;
  box-shadow: 0 2px 14px var(--shadow);
}

/* Clips the horizontal slide during a swipe drag - .page-content and
   .page-preview are both absolutely positioned inside this, so they can
   overlap/slide past each other instead of pushing layout around. */
.page-viewport {
  flex: 1;
  position: relative;
  overflow: hidden;
}

.page-content {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  padding: 28px 34px 8px;
  font-family: "UthmanicWarsh", "Scheherazade New", "Amiri", serif;
  font-size: 26px;
  line-height: 2.2;
  text-align: justify;
  /* the final line of the flowing text is almost always shorter than the page
     width - center it instead of leaving it ragged against the margin */
  text-align-last: center;
}

/* The adjacent page, live-rendered and dragged in alongside the current one
   during a swipe (see app.js's touch handlers) - identical look to
   .page-content (shares that class), just starts off-screen and hidden. */
.page-preview {
  visibility: visible;
}

.page-preview[hidden] {
  display: block; /* still needs layout/measurements while off-screen - only actually invisible via being positioned outside the clipped viewport */
  visibility: hidden;
}

/* Retriggered (class removed+re-added) after every renderPage that ISN'T
   the tail end of a swipe (see app.js: swipes already animated the drag
   itself, a fade on top would just double up) - button/keyboard/sidebar
   navigation still gets a plain fade since there's no "finger position" to
   follow for those. The DOM swap itself is never delayed for this - only
   the new content's opacity is animated - so nothing that expects
   renderPage to be synchronous (e.g. record.js scrolling to the
   just-rendered ayah right after goToPage) is affected. */
@keyframes page-fade-in {
  from {
    opacity: 0;
  }
}

.page-content.page-turn {
  animation: page-fade-in 0.22s ease;
}

.page-number {
  text-align: center;
  padding: 6px 0 10px;
  font-family: "Segoe UI", Tahoma, sans-serif;
  font-size: 14px;
  color: var(--muted);
}

.page-nav {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--control-bg);
  color: var(--accent);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
}

.page-nav:hover:not(:disabled) {
  background: var(--control-hover);
}

.page-nav:disabled {
  opacity: 0.3;
  cursor: default;
}

.surah-header {
  text-align: center;
  font-size: 30px;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 8px;
  margin: 10px 30px;
  padding: 2px 0;
}

.ayah {
  display: inline;
}

.ayah-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin: 0 4px;
  border: 1px solid var(--accent);
  border-radius: 50%;
  font-size: 15px;
  font-family: "Segoe UI", Tahoma, sans-serif;
  color: var(--accent);
  vertical-align: middle;
}

.provisional {
  opacity: 0.5;
}

/* not-yet-reached text during a live recitation, so the reciter can't read
   ahead - fully hidden rather than blurred (a blur was still readable with
   enough effort), but keeps its layout space so text doesn't jump around
   as it's revealed. */
.unrevealed {
  visibility: hidden;
  user-select: none;
}

/* debug mode: corrector internals overlaid on the text */
.debug-win-edge {
  background: #1a73e8;
  color: #fff !important;
  border-radius: 3px;
}

.debug-win-range {
  background: rgba(26, 115, 232, 0.12);
}

/* per-letter correctness states, from the correction model's 1/-1/0 (/2 = not yet judged) codes */
.state-1 {
  color: inherit;
}

.state--1 {
  color: var(--wrong);
  text-decoration: underline wavy var(--wrong);
}

.state-0 {
  color: var(--uncertain);
}

.state-2 {
  color: inherit;
}

/* On a phone, the flanking prev/next circles plus all the page-frame's
   decorative padding/outline together ate about half the screen width,
   leaving the mushaf text squeezed into a narrow column. Below this width,
   the nav buttons become a floating overlay instead of taking flex-row
   space, and the frame's decoration shrinks, so the text column uses
   nearly the full screen. Desktop layout above this breakpoint is
   untouched. */
@media (max-width: 700px) {
  .page-area {
    padding: 6px;
    gap: 0;
    position: relative;
  }

  .page-frame {
    width: 100%;
    border-width: 1px;
    outline: none;
  }

  .page-content {
    padding: 18px 10px 6px;
    font-size: 22px;
  }

  /* Swipe (see app.js) covers page navigation on touch devices now, so the
     prev/next circles are just redundant clutter over the text on mobile. */
  .page-nav {
    display: none;
  }

  .trust-meter {
    font-size: 11px;
    gap: 4px;
  }

  .trust-bar {
    width: 44px;
  }

  /* Dev-only control - desktop only, per request. */
  .debug-toggle {
    display: none;
  }
}
