/* Claridge House | SLO — guest manual flipbook
   Warm dark gallery backdrop so the cream pages read as paper. */

:root {
  --ink: #2b2622;
  --backdrop: #211d1a;
  --backdrop-lift: #2c2723;
  --paper: #f4f0e9;
  --cream: #e7e0d4;
  --muted: #a1968a;
  --line: rgba(231, 224, 212, 0.16);
  --accent: #c3a87d;
  /* Chrome is charged to the magazine: the book is limited by height, so
     every fixed pixel here is one the pages don't get. On a short laptop
     window a constant 4.25rem ate a quarter of the height. Scale with the
     space available — continuously, since any breakpoint that drops the bar
     makes a taller window yield a *smaller* book. */
  --bar-h: clamp(3rem, 6vh, 4.25rem);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

/* The overlays below set `display`, which outranks the UA sheet's
   `[hidden] { display: none }` at equal specificity. Without this they stay
   laid out while hidden and swallow every click on the book. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--backdrop);
  color: var(--cream);
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

.viewer {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  /* A soft pool of light behind the book. */
  background:
    radial-gradient(120% 90% at 50% 42%, var(--backdrop-lift) 0%, var(--backdrop) 62%);
}

/* ---------- bars ---------- */

.bar {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  gap: 1rem;
  height: var(--bar-h);
  padding: 0 1.25rem;
  z-index: 3;
}

.bar--bottom {
  justify-content: space-between;
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
}

.counter {
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  min-width: 7ch;
}

.controls {
  display: flex;
  align-items: center;
  gap: 0.25rem;
}

.sep {
  width: 1px;
  height: 1.25rem;
  margin: 0 0.5rem;
  background: var(--line);
}

/* ---------- buttons ---------- */

.btn {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--cream);
  cursor: pointer;
  transition: background 0.18s var(--ease), color 0.18s var(--ease), opacity 0.18s;
}

.btn svg {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.btn:hover:not(:disabled) { background: rgba(231, 224, 212, 0.1); }
.btn:active:not(:disabled) { background: rgba(231, 224, 212, 0.16); }
.btn:disabled { opacity: 0.25; cursor: default; }
.btn[aria-expanded="true"] { background: rgba(231, 224, 212, 0.14); color: var(--accent); }

:where(.btn, .edge, .thumb, .hotspot):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* ---------- stage ---------- */

.stage {
  position: relative;
  flex: 1 1 auto;
  display: grid;
  place-items: center;
  min-height: 0;
  padding: clamp(0.5rem, 1.5vh, 1.5rem);
}

.book {
  /* StPageFlip writes inline width/height here. */
  filter: drop-shadow(0 1.5rem 3rem rgba(0, 0, 0, 0.55));
  touch-action: pan-y;
  /* It also writes an inline min-width/min-height from its settings. Our
     minWidth exists only to place the one-page breakpoint, but StPageFlip
     reuses it as a hard floor — wider than the stage on a narrow phone, which
     shoves the book off the right edge. We size the stage ourselves, so drop
     the floor; the JS setting still drives the breakpoint. Needs !important:
     the values it fights are inline. */
  min-width: 0 !important;
  min-height: 0 !important;
}

.book .page {
  background: var(--paper);
  overflow: hidden;
}

.book .page img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Hold the paper colour until the scan paints in. */
  background: var(--paper);
  user-select: none;
  -webkit-user-drag: none;
}

/* Gutter shading — the inner edge of a bound page dips into the spine. */
.book .page--left::after,
.book .page--right::after {
  content: "";
  position: absolute;
  inset-block: 0;
  width: 8%;
  pointer-events: none;
  z-index: 2;
}

.book .page--left::after {
  right: 0;
  background: linear-gradient(to right, transparent, rgba(43, 38, 34, 0.16));
}

.book .page--right::after {
  left: 0;
  background: linear-gradient(to left, transparent, rgba(43, 38, 34, 0.16));
}

/* ---------- link hotspots ---------- */

.hotspot {
  position: absolute;
  z-index: 3;
  border-radius: 3px;
  /* Invisible until hovered — the print design already styles the text. */
  background: transparent;
  transition: background 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

.hotspot:hover {
  background: rgba(195, 168, 125, 0.22);
  box-shadow: 0 0 0 3px rgba(195, 168, 125, 0.22);
}

/* ---------- edge arrows ---------- */

.edge {
  position: absolute;
  inset-block: 0;
  width: clamp(3rem, 8vw, 6rem);
  border: 0;
  background: transparent;
  cursor: pointer;
  z-index: 2;
  opacity: 0;
  transition: opacity 0.2s var(--ease);
}

.edge::before {
  content: "";
  display: block;
  width: 0.9rem;
  height: 0.9rem;
  margin: 0 auto;
  border-right: 1.5px solid var(--paper);
  border-bottom: 1.5px solid var(--paper);
}

.edge--prev { left: 0; }
.edge--next { right: 0; }
.edge--prev::before { transform: rotate(135deg); }
.edge--next::before { transform: rotate(-45deg); }

.stage:hover .edge:not(:disabled) { opacity: 0.55; }
.edge:hover:not(:disabled) { opacity: 1 !important; }
.edge:disabled { cursor: default; }

.hint {
  position: absolute;
  bottom: 0.25rem;
  margin: 0;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  opacity: 0.75;
  transition: opacity 0.6s var(--ease);
  pointer-events: none;
}

.hint[data-hidden] { opacity: 0; }

/* A phone has no arrow keys. Keyed off hover, not width: a small window on a
   laptop still has a mouse and a keyboard. */
.hint--touch { display: none; }

@media (hover: none) {
  .hint--pointer { display: none; }
  .hint--touch { display: inline; }
}

/* ---------- thumbnails ---------- */

.thumbs {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  background: rgba(33, 29, 26, 0.97);
  backdrop-filter: blur(6px);
  animation: fade 0.22s var(--ease);
}

.thumbs__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 0 0 auto;
  height: var(--bar-h);
  padding: 0 1.25rem;
  border-bottom: 1px solid var(--line);
}

.thumbs__head p {
  margin: 0;
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

.thumbs__grid {
  flex: 1 1 auto;
  overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
  gap: 1rem;
  padding: 1.5rem 1.25rem;
  -webkit-overflow-scrolling: touch;
}

.thumb {
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  font: inherit;
  color: var(--muted);
}

.thumb img {
  display: block;
  width: 100%;
  aspect-ratio: var(--aspect, 0.707);
  object-fit: cover;
  background: var(--backdrop-lift);
  border: 1px solid transparent;
  box-shadow: 0 0.3rem 0.9rem rgba(0, 0, 0, 0.4);
  transition: border-color 0.18s var(--ease), transform 0.18s var(--ease);
}

.thumb span {
  display: block;
  margin-top: 0.45rem;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}

.thumb:hover img { transform: translateY(-2px); border-color: var(--line); }
.thumb[aria-current="true"] img { border-color: var(--accent); }
.thumb[aria-current="true"] span { color: var(--accent); }

/* ---------- zoom ---------- */

.zoom {
  position: absolute;
  inset: 0;
  z-index: 7;
  display: flex;
  flex-direction: column;
  /* Opaque: at 98% the toolbar behind ghosted through the header. */
  background: #14110f;
  animation: fade 0.22s var(--ease);
}

.zoom__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 0 0 auto;
  height: var(--bar-h);
  padding: 0 1.25rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}

.zoom__canvas {
  flex: 1 1 auto;
  overflow: auto;
  padding: 1.25rem;
  text-align: center;
  -webkit-overflow-scrolling: touch;
  cursor: zoom-in;
}

.zoom__canvas img {
  height: auto;
  background: var(--paper);
  box-shadow: 0 1rem 2.5rem rgba(0, 0, 0, 0.5);
}

.zoom__canvas[data-zoomed] { cursor: grab; }
.zoom__canvas[data-zoomed]:active { cursor: grabbing; }

@keyframes fade { from { opacity: 0; } }

/* ---------- fallback ---------- */

.fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  gap: 0.75rem;
  text-align: center;
  padding: 2rem;
}

.fallback a { color: var(--accent); }

/* ---------- small screens ---------- */

@media (max-width: 40rem) {
  :root { --bar-h: 3.5rem; }

  .stage { padding: 0.75rem; }
  .edge { display: none; }
  .hint { font-size: 0.625rem; }
  .btn { width: 2.25rem; height: 2.25rem; }
  .bar { padding: 0 0.75rem; }
  /* Seven buttons won't fit a phone's bar. First/last are the ones to drop:
     the thumbnail index jumps anywhere, and swiping covers short hops. */
  #btn-first, #btn-last { display: none; }
  .thumbs__grid { grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr)); gap: 0.75rem; }
}

/* Fullscreen is for reading, so give the page every pixel the chrome was using:
   the controls float over the backdrop instead of reserving a strip. */
:fullscreen .stage {
  padding: 1rem 1rem 0;
}

:fullscreen .bar--bottom {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  border-top: 0;
  /* Fade the backdrop up behind the controls so they stay legible over a page. */
  background: linear-gradient(to top, rgba(20, 17, 15, 0.85), transparent);
}

/* Reclaimed by the floating bar; keep the hint clear of the controls. */
:fullscreen .hint {
  bottom: 4.5rem;
}

/* Very narrow phones (320px). Tighten the bar rather than let it scroll. */
@media (max-width: 22rem) {
  .btn { width: 2rem; height: 2rem; }
  .btn svg { width: 1.125rem; height: 1.125rem; }
  .sep { display: none; }
  .counter { min-width: 0; }
  .controls { gap: 0; }
}

/* Short landscape windows (phone turned sideways) — reclaim vertical space. */
@media (max-height: 30rem) and (orientation: landscape) {
  .hint { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
