/* sprint/read/read.css
   Reader chrome for the Weave Sprint corpus. Route-scoped, loaded only by
   sprint/read/index.html.

   Idiom (DEC-002, DEC-006): this is a QUIET surface, not a paper surface. The
   PDF page is the artifact and receives zero Brandcraft grammar. The chrome
   around it is informational: white cards, hairlines, stamps, 0deg always, no
   rotation, no pen annotations, no tape, no torn edges, no dashed or dotted
   borders anywhere. Tap targets 44px minimum. Page numbers in tabular lining
   numerals. Both themes come from css/tokens.css custom properties, which this
   file references and never redefines.

   The one route-local colour is the canvas surround, held in --read-surround:
   light is the sanctioned quiet tone (paper-green at 22 percent over white,
   DESIGN-V4 section 3), dark is the woven-night --paper-quiet token. Neither is
   an invented grey. */

:root {
  --read-surround: #E9EFE3;
  --read-top-h: 52px;
  --read-bottom-h: 88px;
  --read-drawer-w: min(21rem, 88vw);
  /* The PDF page under the canvas stays light in both themes, so the two
     highlight tints are tuned against white paper and do not theme-switch. */
  --read-hl: rgb(239 200 104 / 0.48);
  --read-hl-current: rgb(199 91 57 / 0.40);
}

[data-theme="dark"] { --read-surround: var(--paper-quiet); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --read-surround: var(--paper-quiet); }
}

html { scroll-behavior: auto; }

/* Several route components set their own display, which would otherwise beat
   the user-agent rule for the hidden attribute. The panels below are shown and
   hidden by that attribute alone, so it has to win. */
.read-body [hidden] { display: none !important; }

.read-body {
  margin: 0;
  background: var(--read-surround);
  color: var(--ink);
  font-family: var(--font-ui);
  overscroll-behavior-y: none;
}

.read-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  border: 0;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- Bars ---------- */

.read-bar {
  position: fixed;
  z-index: 40;
  right: 0;
  left: 0;
  background: var(--cloth-card);
  transition: transform var(--duration-ui) var(--ease-weave);
}

.read-bar-top {
  top: 0;
  display: flex;
  gap: var(--space-3);
  align-items: center;
  height: calc(var(--read-top-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) max(var(--space-3), env(safe-area-inset-right)) 0 max(var(--space-3), env(safe-area-inset-left));
  border-bottom: 1px solid var(--hairline);
}

.read-bar-bottom {
  bottom: 0;
  padding: var(--space-1) max(var(--space-3), env(safe-area-inset-right)) calc(var(--space-2) + env(safe-area-inset-bottom)) max(var(--space-3), env(safe-area-inset-left));
  border-top: 1px solid var(--hairline);
}

.read-body.chrome-hidden .read-bar-top { transform: translateY(-100%); }
.read-body.chrome-hidden .read-bar-bottom { transform: translateY(100%); }
.read-body.chrome-hidden .read-find { transform: translateY(200%); }

.read-back {
  display: inline-flex;
  gap: 2px;
  flex: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  padding-right: var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
}

.read-back:hover { color: var(--thread-sage); }

.read-title {
  flex: 1 1 auto;
  overflow: hidden;
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Page indicator reads as a stamp: bordered, uppercase-neutral, tabular. */
.read-count {
  display: inline-flex;
  flex: none;
  gap: 1px;
  align-items: baseline;
  padding: 4px 9px 3px;
  border: 2px solid var(--hairline-firm);
  border-radius: 4px 9px 5px 10px;
  color: var(--ink-2);
  font-size: 0.8125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: 0.02em;
}

.read-count-sep { padding: 0 2px; opacity: 0.7; }

/* No document open: no page count to stamp, and no bottom bar to leave room for. */
.read-no-doc { --read-bottom-h: 0px; }
.read-no-doc .read-count { display: none; }

/* ---------- Controls ---------- */

.read-btn {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}

.read-btn:hover { border-color: var(--hairline-firm); background: var(--fill-cool); }
.read-btn[aria-expanded="true"] { border-color: var(--hairline-firm); background: var(--fill-cool); }
.read-btn[disabled] { color: var(--ink-3); cursor: default; }
.read-btn[disabled]:hover { border-color: transparent; background: transparent; }

.read-slider-row { display: flex; align-items: center; height: 32px; }

.read-slider {
  width: 100%;
  height: 32px;
  margin: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.read-slider::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--hairline-firm);
}

.read-slider::-webkit-slider-thumb {
  width: 22px;
  height: 22px;
  margin-top: -9px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--cloth-card);
  -webkit-appearance: none;
  appearance: none;
}

.read-slider::-moz-range-track {
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--hairline-firm);
}

.read-slider::-moz-range-thumb {
  width: 20px;
  height: 20px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--cloth-card);
}

.read-tools {
  display: flex;
  gap: var(--space-1);
  align-items: center;
  justify-content: space-between;
}

.read-jump {
  display: inline-flex;
  gap: 6px;
  flex: 0 1 auto;
  align-items: center;
  min-width: 0;
  height: 44px;
}

.read-page-input {
  width: 3.6em;
  height: 36px;
  padding: 0 6px;
  border: 1px solid var(--hairline-firm);
  border-radius: var(--radius-sm);
  background: var(--cloth-card);
  color: var(--ink);
  font-size: var(--text-sm);
  font-variant-numeric: tabular-nums lining-nums;
  text-align: center;
}

.read-jump-of {
  color: var(--ink-3);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
}

.read-dl-wrap { position: relative; flex: none; }

.read-menu {
  position: absolute;
  z-index: 50;
  right: 0;
  bottom: calc(100% + var(--space-2));
  width: max(15rem, 62vw);
  max-width: 20rem;
  padding: var(--space-4);
  border: 2px solid var(--ink);
  border-radius: var(--radius-sm);
  background: var(--cloth-card);
  box-shadow: var(--shadow-lift);
}

.read-menu-item {
  display: block;
  min-height: 44px;
  padding: 11px 0;
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 600;
  line-height: 1.4;
}

.read-menu-note {
  margin: 0;
  color: var(--ink-3);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums lining-nums;
}

/* ---------- Find ---------- */

.read-find {
  position: fixed;
  z-index: 41;
  right: max(var(--space-3), env(safe-area-inset-right));
  bottom: calc(var(--read-bottom-h) + env(safe-area-inset-bottom) + var(--space-2));
  left: max(var(--space-3), env(safe-area-inset-left));
  display: flex;
  gap: var(--space-1);
  align-items: center;
  padding: var(--space-2);
  border: 2px solid var(--ink);
  border-radius: var(--radius-sm);
  background: var(--cloth-card);
  box-shadow: var(--shadow-lift);
  transition: transform var(--duration-ui) var(--ease-weave);
}

.read-find-label {
  flex: none;
  padding-left: 4px;
  color: var(--ink-3);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.read-find-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 40px;
  padding: 0 var(--space-2);
  border: 1px solid var(--hairline-firm);
  border-radius: var(--radius-sm);
  background: var(--cloth-card);
  color: var(--ink);
  font-size: 1rem;
}

.read-find-count {
  flex: none;
  max-width: 8em;
  color: var(--ink-3);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums lining-nums;
  text-align: center;
}

/* On a phone the label, count and three buttons crowd the field until the
   query scrolls out of view. The label is redundant next to a search field
   that already carries a placeholder, so it goes first. */
@media (max-width: 30rem) {
  .read-find-label { display: none; }
  .read-find-count { max-width: 5.5em; font-size: 0.75rem; }
}

.read-find-btn { width: 40px; height: 40px; }

/* ---------- Pages ---------- */

.read-main {
  padding-top: calc(var(--read-top-h) + env(safe-area-inset-top) + var(--space-3));
  padding-bottom: calc(var(--read-bottom-h) + env(safe-area-inset-bottom) + var(--space-3));
}

.read-pages {
  /* Native pinch zoom stays available on the canvas column; the zoom control
     pair re-renders at a true scale, pinch magnifies what is already painted. */
  touch-action: pan-x pan-y pinch-zoom;

  /* One write here resizes every placeholder, so a zoom step does not touch
     2,295 style objects. Pages that turn out to differ from page one get an
     inline override of their own when they render. */
  --scale-factor: 1;
  --read-page-w: auto;
  --read-page-h: auto;
}

.read-page {
  --user-unit: 1;
  --total-scale-factor: calc(var(--scale-factor) * var(--user-unit));
  --scale-round-x: 1px;
  --scale-round-y: 1px;

  position: relative;
  width: var(--read-page-w);
  height: var(--read-page-h);
  margin: 0 auto var(--space-3);
  background: var(--cloth-card);
  box-shadow: var(--shadow-soft);
  direction: ltr;
}

.read-page canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* No floating page number per page: the top bar carries the position, and the
   volumes print their own folios. A third number would be chrome competing
   with the artifact. */

/* Text layer. These rules reproduce the geometry contract that the vendored
   core TextLayer writes inline (per-span --font-height, --scale-x, --rotate,
   and the container --total-scale-factor). The stock viewer stylesheet is
   deliberately NOT vendored; this is the route's own equivalent. */
.read-textlayer {
  --min-font-size: 1;
  --text-scale-factor: calc(var(--total-scale-factor) * var(--min-font-size));
  --min-font-size-inv: calc(1 / var(--min-font-size));

  position: absolute;
  z-index: 1;
  inset: 0;
  overflow: clip;
  color-scheme: only light;
  caret-color: CanvasText;
  forced-color-adjust: none;
  letter-spacing: normal;
  line-height: 1;
  opacity: 1;
  text-align: initial;
  text-size-adjust: none;
  transform-origin: 0 0;
  word-spacing: normal;
}

.read-textlayer span,
.read-textlayer br {
  position: absolute;
  color: transparent;
  cursor: text;
  transform-origin: 0% 0%;
  user-select: text;
  white-space: pre;
}

.read-textlayer > :not(.markedContent),
.read-textlayer .markedContent span:not(.markedContent) {
  --font-height: 0;
  --scale-x: 1;
  --rotate: 0deg;

  z-index: 1;
  font-size: calc(var(--text-scale-factor) * var(--font-height));
  transform: rotate(var(--rotate)) scaleX(var(--scale-x)) scale(var(--min-font-size-inv));
}

.read-textlayer .markedContent { display: contents; }
.read-textlayer span[role="img"] { cursor: default; user-select: none; }

/* Match highlights are appended inside a positioned text span, so they must
   drop back out of absolute positioning (the same correction the upstream
   viewer applies to its own appended highlights). */
.read-hl {
  position: static;
  margin: -1px;
  padding: 1px;
  border-radius: 3px;
  background-color: var(--read-hl);
}

.read-hl.is-current { background-color: var(--read-hl-current); }

/* ---------- Loading, empty and error ---------- */

/* The status layer covers the page column until the first canvas paints, so
   the reader never shows a bare stack of empty placeholders. It is removed
   from the document once a page is on screen. */
.read-status {
  position: fixed;
  z-index: 30;
  top: calc(var(--read-top-h) + env(safe-area-inset-top));
  right: 0;
  bottom: calc(var(--read-bottom-h) + env(safe-area-inset-bottom));
  left: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  overflow-y: auto;
  background: var(--read-surround);
  text-align: center;
}

.read-skeleton {
  width: auto;
  height: min(52vh, 26rem);
  aspect-ratio: 1 / 1.294;
  margin: 0 auto var(--space-4);
  border: 1px solid var(--hairline);
  background: var(--cloth-card);
  box-shadow: var(--shadow-soft);
}

.read-status-line {
  margin-bottom: var(--space-1);
  color: var(--ink-2);
  font-size: var(--text-sm);
}

.read-progress {
  margin: 0;
  color: var(--ink-3);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums lining-nums;
}

.read-card {
  width: min(34rem, calc(100% - 2rem));
  margin: var(--space-8) auto;
  padding: var(--space-6);
  border: 2px solid var(--ink);
  border-radius: var(--radius-sm);
  background: var(--cloth-card);
  box-shadow: var(--shadow-lift);
  text-align: left;
}

.read-card h1 {
  max-width: none;
  margin-bottom: var(--space-3);
  font-family: var(--font-serif);
  font-size: 1.375rem;
  font-weight: 600;
  transform: none;
}

.read-card p { color: var(--ink-2); font-size: var(--text-sm); }
.read-card p:last-child { margin-bottom: 0; }
.read-card a { color: var(--ink); font-weight: 600; }

.read-card-actions { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center; }

/* Every action in a card is a real target, including the plain-text ones, so
   the pre-load choice is equally reachable one-thumb. */
.read-card-actions a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.read-retry {
  min-height: 44px;
  padding: 0 var(--space-5);
  border: 2px solid var(--ink);
  border-radius: var(--radius-sm);
  background: var(--cloth-card);
  color: var(--ink);
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
}

.read-retry:hover { background: var(--fill-cool); }

/* ---------- Drawer ---------- */

.read-scrim {
  position: fixed;
  z-index: 60;
  inset: 0;
  background: rgb(43 35 32 / 46%);
}

.read-drawer {
  position: fixed;
  z-index: 61;
  top: 0;
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  width: var(--read-drawer-w);
  padding-right: var(--space-2);
  padding-left: max(var(--space-4), env(safe-area-inset-left));
  border-right: 1px solid var(--hairline-firm);
  background: var(--cloth-card);
  box-shadow: var(--shadow-lift);
}

.read-drawer-head {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  justify-content: space-between;
  padding-top: calc(var(--space-3) + env(safe-area-inset-top));
  padding-right: var(--space-2);
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--hairline);
}

.read-drawer-title {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-serif);
  font-size: 1.125rem;
  font-weight: 600;
  letter-spacing: 0;
  transform: none;
}

.read-drawer-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding-top: var(--space-4);
  padding-right: var(--space-2);
  padding-bottom: calc(var(--space-6) + env(safe-area-inset-bottom));
  overscroll-behavior: contain;
}

.read-chips-block { margin-bottom: var(--space-5); }

.read-chips-label {
  margin-bottom: var(--space-2);
  color: var(--ink-3);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.read-chips { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* Day chips borrow the sitewide stamp chip: bordered, tabular, 0deg here. */
.read-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 6px 12px;
  border: 2px solid var(--hairline-firm);
  border-radius: 4px 9px 5px 10px;
  background: var(--cloth-card);
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums lining-nums;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
}

.read-chip:hover { border-color: var(--ink); background: var(--fill-cool); }

.read-outline-list { margin: 0; padding: 0; list-style: none; }

.read-outline-item {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 11px var(--space-2) 11px 0;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  background: transparent;
  color: var(--ink-2);
  font-size: 1rem;
  line-height: 1.35;
  text-align: left;
  cursor: pointer;
}

.read-outline-item:hover { color: var(--ink); }
.read-outline-item[data-depth="0"] { color: var(--ink); font-weight: 600; }
.read-outline-item[data-depth="1"] { padding-left: var(--space-4); }
.read-outline-item[data-depth="2"] { padding-left: var(--space-8); }
.read-outline-item[data-depth="3"] { padding-left: var(--space-10); }

.read-outline-empty { color: var(--ink-3); font-size: var(--text-sm); }

/* ---------- No-JS ---------- */

.read-noscript {
  width: min(34rem, calc(100% - 2rem));
  margin: var(--space-10) auto;
  color: var(--ink);
  font-size: 1rem;
  line-height: 1.6;
}

@media (min-width: 48rem) {
  :root { --read-top-h: 56px; --read-bottom-h: 60px; }

  .read-bar-bottom {
    display: flex;
    gap: var(--space-4);
    align-items: center;
    padding-top: var(--space-1);
  }

  .read-slider-row { flex: 1 1 auto; order: 2; }
  .read-tools { flex: none; order: 1; gap: var(--space-2); }
  .read-find { right: auto; width: min(30rem, calc(100% - 2rem)); }
}

@media (prefers-reduced-motion: reduce) {
  .read-bar, .read-find { transition: none; }
}
