/* TheodoraApp — live captions for a reader who cannot hear.
   Contrast and text size are the product here, so both are set explicitly
   rather than left to defaults.

   Bootstrap does the layout, buttons, offcanvas and modal. This file only
   covers what it has no opinion about — caption typography, the voice dot,
   notch insets — and the few places where its defaults are wrong for an app
   whose whole job is being readable. */

:root {
  /* Driven from JS so the reader can size the text to their own eyes. */
  --caption-size: 42px;
  --app-live: #8a8a8a;
  --bs-body-font-family: Inter, "Noto Sans", Roboto, "Segoe UI", system-ui, sans-serif;
}

/* Bootstrap's #212529 on #fff is the right call for ordinary prose. Here the
   text is the product, so both themes go to the ends of the scale. These come
   after Bootstrap's own rules and match their specificity, so they win. */
[data-theme="light"] {
  --bs-body-bg: #ffffff;
  --bs-body-color: #000000;
  --bs-emphasis-color: #000000;
}

[data-theme="dark"] {
  --bs-body-bg: #0d0d0d;
  --bs-body-color: #ffffff;
  --bs-emphasis-color: #ffffff;
}

/* --- shell --------------------------------------------------------------- */

html, body { height: 100%; }

/* Phone browsers count the collapsing address bar in vh, which leaves the
   footer under it. dvh is the measurement that tracks it. */
@supports (height: 100dvh) {
  body { height: 100dvh; }
}

body {
  overflow: hidden;
  /* Keep clear of notches. The footer handles the home indicator itself, so
     that the border it draws still reaches the bottom of the screen. */
  padding: env(safe-area-inset-top) env(safe-area-inset-right) 0 env(safe-area-inset-left);
}

.app-bar, .app-footer {
  flex: 0 0 auto;
  user-select: none;
}

.app-footer {
  padding-bottom: calc(.5rem + env(safe-area-inset-bottom));
}

/* Stops the ~300ms wait for a possible double-tap on every press. */
.btn { touch-action: manipulation; }

/* --- controls ------------------------------------------------------------ */

/* 56px, not Bootstrap's 38px default: this is a phone app, often held at
   arm's length by someone mid-conversation. */
.app-action {
  min-height: 56px;
  font-size: 1.125rem;
  font-weight: 600;
}

.app-action--side {
  flex: 0 0 auto;
  width: 68px;
  font-size: 1.375rem;
}

.app-icon-btn {
  width: 48px;
  height: 48px;
  padding: 0;
  font-size: 1.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.app-lang {
  min-width: 58px;
  padding: .625rem .75rem;
  font-weight: 600;
  font-size: 1rem;
}

/* --- transcript ---------------------------------------------------------- */

.transcript {
  -webkit-overflow-scrolling: touch;
  /* A flick that runs past the end scrolls the transcript, never the page
     behind it. */
  overscroll-behavior: contain;
}

.line {
  /* A finished sentence: maximum contrast, full weight, all caps. Grey means
     one thing only — words still being revised. */
  font-size: var(--caption-size);
  line-height: 1.25;
  font-weight: 600;
  margin: 0 0 .4em;
  overflow-wrap: break-word;
}

.line--live {
  color: var(--app-live);
  font-weight: 500;
  font-style: italic;
}

.empty { color: var(--bs-secondary-color); }
.empty__mark { font-size: 3.25rem; line-height: 1; margin-bottom: .75rem; opacity: .45; }
.empty__line { font-size: 1.5rem; }
.empty__line--sub { font-size: 1.25rem; opacity: .75; }

/* --- voice indicator ----------------------------------------------------- */

/* Rides on the filled Start/Stop button, so it is sized against that rather
   than the page, and lights up against either button colour. */
.dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: rgba(255, 255, 255, .35);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55);
  transition: background-color .12s ease, box-shadow .12s ease;
}

.dot.is-hearing {
  background: #4ade80;
  box-shadow: 0 0 0 4px rgba(74, 222, 128, .35);
}

/* --- settings panel ------------------------------------------------------ */

.app-settings {
  /* Tall enough for its content and no taller, instead of Bootstrap's 30vh. */
  --bs-offcanvas-height: auto;
}

.app-settings .offcanvas-body {
  padding-bottom: calc(1rem + env(safe-area-inset-bottom));
}

.sample {
  font-size: min(var(--caption-size), 3rem);
  font-weight: 600;
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.diag-rows {
  display: grid;
  grid-template-columns: minmax(130px, auto) 1fr;
  gap: .375rem 1rem;
  margin: 0;
  font-size: .875rem;
}

.diag-rows dt { font-weight: 600; }
.diag-rows dd { margin: 0; color: var(--bs-secondary-color); overflow-wrap: anywhere; }

/* --- cramped screens ----------------------------------------------------- */

@media (max-width: 360px) {
  .app-lang { min-width: 48px; padding-left: .5rem; padding-right: .5rem; }
  .app-action--side { width: 58px; }
  .app-icon-btn { width: 44px; height: 44px; }
}

/* A phone on its side has barely any height to spare, and the transcript is
   the part that must not shrink. */
@media (orientation: landscape) and (max-height: 460px) {
  .app-action { min-height: 44px; }
  .empty__mark { display: none; }
  .empty__line { font-size: 1.25rem; }
  .empty__line--sub { font-size: 1.05rem; }
}
