/* Shared chrome for narraloud.com: tokens, Newsreader faces, header
   wordmark, footer, type scale, and the index hero with the CSS-only
   QR morph. The only script on this site is the first-party demo
   player, which talks to nothing. */

@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url(/fonts/Newsreader-latin.woff2) format("woff2");
}
@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url(/fonts/Newsreader-Italic-latin.woff2) format("woff2");
}

:root {
  --paper: #FAFAF8;
  --ink: #1A1A18;
  --muted: #55524C;
  --accent: #C0510F;
  --mark: #FF7F4E;
  --rule: #E7E3DB;
  --card: #FFFFFF;
  --wash: rgba(255, 127, 78, 0.24);
  --card-shadow: 0 24px 60px rgba(26, 26, 24, 0.10), 0 2px 8px rgba(26, 26, 24, 0.06);
}
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #121210;
    --ink: #F2F1ED;
    --muted: #A8A49C;
    --accent: #FF7F4E;
    --rule: #2E2C28;
    --card: #1C1B18;
    --wash: rgba(255, 127, 78, 0.30);
    --card-shadow: 0 24px 60px rgba(0, 0, 0, 0.55), 0 2px 8px rgba(0, 0, 0, 0.4);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-family: ui-sans-serif, system-ui, sans-serif;
  background: var(--paper);
  color: var(--ink);
  line-height: 1.65;
}

.serif {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-optical-sizing: auto;
}

/* Header wordmark: the identity lockup (mark and name in one file,
   so their alignment is fixed by the asset, not by CSS). */
header { padding: 1.25rem 1.5rem; }
.wordmark { display: inline-flex; }
.wordmark img { display: block; height: 1.3rem; width: auto; }

main { flex: 1; }

/* Prose pages (privacy, terms, support). */
.prose {
  width: 100%;
  max-width: 42rem;
  margin: 0 auto;
  padding: 0 1.5rem 3rem;
}
.prose h1 {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 420;
  font-size: 2.4rem;
  line-height: 1.15;
  margin: 1.5rem 0 0.35rem;
}
.prose h2 {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 500;
  font-size: 1.45rem;
  line-height: 1.25;
  margin: 2.25rem 0 0.5rem;
}
.dateline {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-style: italic;
  color: var(--muted);
  font-size: 1rem;
  margin: 0 0 1.75rem;
}
.prose a { color: var(--accent); }

/* Reading Room articles */
.article .eyebrow {
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 2rem 0 0;
}
.article .deck {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-size: 1.25rem;
  line-height: 1.4;
  color: var(--muted);
  margin: 0.25rem 0 0.75rem;
}
.article-hero {
  width: 100%;
  height: auto;
  border-radius: 12px;
  margin: 0.5rem 0 1rem;
}
.pullquote {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-size: 1.4rem;
  line-height: 1.35;
  color: var(--ink);
  border-left: 3px solid var(--accent);
  margin: 2rem 0;
  padding: 0.25rem 0 0.25rem 1.25rem;
}

footer {
  text-align: center;
  padding: 1.75rem 1.5rem;
  font-size: 0.9rem;
  color: var(--muted);
}
footer a {
  color: var(--accent);
  text-decoration: none;
  margin: 0 0.6rem;
}
footer a:hover { text-decoration: underline; }

/* Index hero: one subject, one action, then the product doing the
   thing -- the reader demo card is the page's proof. */
.hero-main {
  display: grid;
  /* One track pinned to the container: an intrinsic track would take
     the feature grid's min-content width and overflow small screens. */
  grid-template-columns: minmax(0, 100%);
  justify-items: center;
  align-items: start;
  align-content: start;
  row-gap: 4.5rem;
  padding: 2rem 1.5rem 3rem;
}
.hero { text-align: center; max-width: 38rem; }

/* The hero pairs a framed screenshot with the pitch: stacked and
   centered on small screens, phone left and left-aligned text right
   once there is room. The bezel is CSS so it stays crisp and cheap. */
.hero-split { width: 100%; }
/* The framed screenshot exists only where the side-by-side fits.
   Stacked layouts drop it: the demo card below is the visual there. */
.hero-phone { display: none; margin: 0; justify-content: center; }
.phone-bezel {
  display: block;
  position: relative;
  padding: 0.4rem;
  background: #1A191B;
  border-radius: 2.2rem;
  box-shadow: var(--card-shadow);
}
/* The capture carries no Dynamic Island (simulator screenshots omit
   it), so the bezel draws one in the hardware ink. Sized for the
   16rem desktop frame, the only place the phone renders. */
.phone-bezel::after {
  content: "";
  position: absolute;
  top: 0.95rem;
  left: 50%;
  transform: translateX(-50%);
  width: 4.55rem;
  height: 1.3rem;
  border-radius: 999px;
  background: #1A191B;
}
.phone-bezel img {
  display: block;
  width: 11rem;
  height: auto;
  border-radius: 1.8rem;
}
@media (min-width: 60rem) {
  .hero-phone { display: flex; }
  .phone-bezel { padding: 0.55rem; border-radius: 3.1rem; }
  .phone-bezel img { width: 16rem; border-radius: 2.55rem; }
  .hero-split {
    display: grid;
    grid-template-columns: minmax(0, 22rem) minmax(0, 34rem);
    gap: 4rem;
    align-items: center;
    justify-content: center;
  }
  .hero-phone { margin: 0; order: -1; }
  .hero { text-align: left; }
  .hero .blurb { margin-left: 0; }
  .hero .get { margin-left: 0; }
}

.hero-mark { height: 3.25rem; width: auto; color: var(--mark); }
.hero h1 {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 420;
  font-size: clamp(2.6rem, 8vw, 4rem);
  line-height: 1.08;
  letter-spacing: -0.01em;
  margin: 1rem 0 1.25rem;
}
.hero h1 em {
  font-style: italic;
  font-weight: 440;
}
.blurb {
  color: var(--muted);
  max-width: 32rem;
  margin: 0 auto 2.5rem;
}
/* Friction-killer under the store button. */
.get-note {
  color: var(--muted);
  font-size: 0.85rem;
  margin: 1rem 0 0;
}

/* The Get-the-app control. On touch devices it is a plain App Store
   button. On hover-capable fine-pointer devices (the desktop signal)
   the button morphs into a scannable QR card on hover -- pure CSS.
   The wrapper keeps the button's flow size so the morph overlays
   instead of shifting layout. */
.get {
  position: relative;
  width: 17rem;
  height: 3.5rem;
  margin: 0 auto;
}
.get-app {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 17rem;
  height: 3.5rem;
  overflow: hidden;
  display: block;
  border: 1.5px solid var(--accent);
  border-radius: 2rem;
  background: transparent;
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
  z-index: 1;
  transition: width 0.35s ease, height 0.35s ease, border-radius 0.35s ease,
    background-color 0.35s ease, border-color 0.35s ease;
}
.get-label {
  position: absolute;
  inset: 0 0 auto 0;
  height: 3.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: opacity 0.2s ease;
}
.get-qr { display: none; }

@media (hover: hover) and (pointer: fine) {
  .get-qr {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.7rem;
    opacity: 0;
    transform: scale(0.92);
    transition: opacity 0.25s ease 0.08s, transform 0.3s ease 0.08s;
  }
  /* The QR card stays paper-on-ink in both schemes so cameras can scan it. */
  .get-qr img { width: 10.5rem; height: 10.5rem; display: block; }
  .get-caption {
    font-family: "Newsreader", ui-serif, Georgia, serif;
    font-style: italic;
    font-weight: 450;
    font-size: 0.95rem;
    color: #55524C;
  }
  .get-app:hover,
  .get-app:focus-visible {
    width: 17rem;
    height: 16.75rem;
    border-radius: 1.25rem;
    background: #FFFFFF;
    border-color: #E7E3DB;
  }
  .get-app:hover .get-label,
  .get-app:focus-visible .get-label { opacity: 0; }
  .get-app:hover .get-qr,
  .get-app:focus-visible .get-qr {
    opacity: 1;
    transform: none;
  }
}

/* The reader demo: a page card with the word wash sweeping the text,
   the app's word-by-word highlight rebuilt in CSS. No script, no
   screenshot -- the product itself, demonstrated. */
.reader-demo {
  margin: 0;
  width: 100%;
  max-width: 34rem;
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 1.25rem;
  box-shadow: var(--card-shadow);
  padding: 1.75rem 2rem 1.5rem;
}
.reader-chapter {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-style: italic;
  font-size: 0.95rem;
  color: var(--muted);
  margin-bottom: 0.9rem;
}
.reader-page {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 420;
  font-size: 1.4rem;
  line-height: 1.75;
  margin: 0 0 1.4rem;
}
.reader-page .w {
  border-radius: 0.3em;
  padding: 0.06em 0.12em;
  margin: -0.06em -0.12em;
  animation: wordwash 9.9s infinite;
}
/* Real playback: the script drives .lit from the audio clock and the
   passive sweep stands down. */
.playing .reader-page .w { animation: none; }
.reader-page .w.lit { background-color: var(--wash); }
@keyframes wordwash {
  0%, 4.2% { background-color: var(--wash); }
  7%, 100% { background-color: transparent; }
}
.reader-page .w:nth-child(2)  { animation-delay: 0.45s; }
.reader-page .w:nth-child(3)  { animation-delay: 0.9s; }
.reader-page .w:nth-child(4)  { animation-delay: 1.35s; }
.reader-page .w:nth-child(5)  { animation-delay: 1.8s; }
.reader-page .w:nth-child(6)  { animation-delay: 2.25s; }
.reader-page .w:nth-child(7)  { animation-delay: 2.7s; }
.reader-page .w:nth-child(8)  { animation-delay: 3.15s; }
.reader-page .w:nth-child(9)  { animation-delay: 3.6s; }
.reader-page .w:nth-child(10) { animation-delay: 4.05s; }
.reader-page .w:nth-child(11) { animation-delay: 4.5s; }
.reader-page .w:nth-child(12) { animation-delay: 4.95s; }
.reader-page .w:nth-child(13) { animation-delay: 5.4s; }
.reader-page .w:nth-child(14) { animation-delay: 5.85s; }
.reader-page .w:nth-child(15) { animation-delay: 6.3s; }
.reader-page .w:nth-child(16) { animation-delay: 6.75s; }
.reader-page .w:nth-child(17) { animation-delay: 7.2s; }
.reader-page .w:nth-child(18) { animation-delay: 7.65s; }
.reader-page .w:nth-child(19) { animation-delay: 8.1s; }
.reader-page .w:nth-child(20) { animation-delay: 8.55s; }
.reader-page .w:nth-child(21) { animation-delay: 9.0s; }
.reader-page .w:nth-child(22) { animation-delay: 9.45s; }

.reader-player {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  border-top: 1px solid var(--rule);
  padding-top: 1.1rem;
}
.reader-play {
  /* 44px is the minimum comfortable touch target; the glyph stays small */
  width: 44px;
  height: 44px;
  margin-left: -6px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  cursor: pointer;
  display: grid;
  place-items: center;
}
.reader-play::before {
  content: "";
  width: 0;
  height: 0;
  border-left: 0.7rem solid currentColor;
  border-top: 0.45rem solid transparent;
  border-bottom: 0.45rem solid transparent;
}
.playing .reader-play::before {
  width: 0.75rem;
  height: 0.9rem;
  border: 0;
  background: linear-gradient(
    to right,
    currentColor 33%, transparent 33%,
    transparent 67%, currentColor 67%
  );
}
.reader-play:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 0.25rem;
}
.reader-track {
  flex: 1;
  height: 3px;
  border-radius: 2px;
  background: var(--rule);
  overflow: hidden;
}
.reader-elapsed {
  display: block;
  width: 8%;
  height: 100%;
  border-radius: 2px;
  background: var(--accent);
}
.reader-time {
  font-size: 0.8rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.reader-error {
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
  color: var(--ink);
}

/* Feature trio: quiet columns, the demo card above stays the page's
   one signature. */
.features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
  gap: 2.75rem 2.5rem;
  width: 100%;
  max-width: 62rem;
}
.feature h2 {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 500;
  font-size: 1.4rem;
  line-height: 1.2;
  margin: 0 0 0.5rem;
}
.feature p {
  margin: 0;
  color: var(--muted);
  font-size: 0.975rem;
}
.feature a { color: var(--accent); }

/* Closing beat: one italic line and the store pill again. */
.closing { text-align: center; padding-bottom: 1rem; }
.closing-line {
  font-family: "Newsreader", ui-serif, Georgia, serif;
  font-optical-sizing: auto;
  font-size: clamp(1.5rem, 4vw, 2rem);
  margin: 0 0 1.5rem;
}

/* Plain pill link (404 back link). */
/* The official App Store badge closes the page. It ships black with
   its own white keyline, made for any ground, so it is one asset in
   both color schemes. */
.get-badge { display: inline-block; }
.get-badge img { display: block; height: 4.25rem; width: auto; }

.get-app-plain {
  display: inline-block;
  padding: 0.65rem 1.75rem;
  border: 1.5px solid var(--accent);
  border-radius: 2rem;
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}
.get-app-plain:hover {
  background: var(--accent);
  color: var(--paper);
}

/* Press kit page. */
.facts { width: 100%; border-collapse: collapse; }
.facts th, .facts td {
  text-align: left;
  padding: 0.45rem 1rem 0.45rem 0;
  vertical-align: top;
  border-bottom: 1px solid var(--rule);
  font-weight: 400;
}
.facts th { color: var(--muted); white-space: nowrap; width: 8.5rem; }
.asset-row { display: flex; flex-wrap: wrap; gap: 1rem; margin: 1.25rem 0; }
/* Asset tiles preview each variant on its intended ground, fixed in
   both color schemes, so the ink forms never sit on a dark card. The
   download links carry matching fixed accents for the same reason. */
.asset-tile {
  flex: 1 1 15rem;
  border: 1px solid #E7E3DB;
  border-radius: 12px;
  padding: 2rem 1.5rem 1.25rem;
  text-align: center;
  background: #FAFAF8;
}
.asset-tile .dl a { color: #C0510F; }
.asset-tile.night { background: #121210; border-color: #2E2C28; }
.asset-tile.night .dl a { color: #FF7F4E; }
.asset-tile img { max-width: 100%; height: auto; }
.asset-tile .asset-mark { height: 5rem; width: auto; }
.asset-tile .asset-icon { height: 7rem; width: auto; }
.asset-tile .dl { display: block; margin-top: 1rem; font-size: 0.85rem; }
.shots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: 1rem;
}
.shots img {
  width: 100%;
  height: auto;
  border-radius: 12px;
  border: 1px solid var(--rule);
  display: block;
}

@media (prefers-reduced-motion: reduce) {
  .get-app, .get-label, .get-qr { transition: none; }
  /* The passive demo holds one lit word instead of sweeping; real
     playback still follows the audio clock. */
  .reader-page .w { animation: none; }
  .reader-demo:not(.playing) .reader-page .w:nth-child(7) {
    background-color: var(--wash);
  }
}
