/* =============================================================================
   HADZA 360 — everything that sits over the environment.

   Warmer and higher-contrast than the course build. This is a first encounter, so it
   leans a little more confident: bigger type, more air, and the photograph is always the
   loudest thing on screen.
   ============================================================================= */

:root {
  --ink: #17120d;
  --ink-dim: #4a3d31;
  --ink-faint: #7d6f60;
  --paper: #f6efe2;
  --paper-warm: #efe5d3;
  --sand: #c9873f;
  --sand-deep: #a4692a;

  --glass: rgba(246, 239, 226, 0.86);
  --glass-strong: rgba(246, 239, 226, 0.97);
  --line: rgba(23, 18, 13, 0.16);

  --serif: 'Fraunces', Georgia, serif;
  --sans: 'Inter', system-ui, -apple-system, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, monospace;

  --lift: 0 24px 64px rgba(10, 8, 5, 0.4);
  --soft: 0 12px 32px rgba(10, 8, 5, 0.18);
  --ease: cubic-bezier(0.2, 0, 0.2, 1);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* ------------------------------------------------------------------ chrome */

.pill {
  pointer-events: auto;
  padding: 0.6rem 0.95rem;
  background: var(--glass);
  -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
  border: 1px solid var(--line); border-radius: 999px;
  font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink); text-decoration: none;
  display: inline-flex; align-items: center; gap: 0.45rem;
  cursor: pointer; transition: all 0.2s var(--ease);
}
.pill:hover { background: var(--glass-strong); transform: translateY(-1px); }
.pill.is-on { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.pill__glyph { display: none; }
@media (max-width: 560px) {
  .pill__label { display: none; }
  .pill__glyph { display: inline; }
  .pill { padding: 0.5rem 0.65rem; }
}

/* ----------------------------------------------------------------- library */

.lib {
  position: fixed; z-index: 20;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(26px) saturate(1.15); backdrop-filter: blur(26px) saturate(1.15);
  border: 1px solid var(--line);
  display: flex; flex-direction: column;
  box-shadow: var(--soft); font-family: var(--sans);
}

@media (min-width: 900px) {
  .lib {
    top: 50%; left: 1.5rem; transform: translateY(-50%);
    width: 366px; max-height: min(80vh, 780px);
    border-radius: 12px;
    transition: transform 0.42s var(--ease), opacity 0.3s ease;
  }
  .lib.is-hidden { transform: translateY(-50%) translateX(calc(-100% - 2rem)); opacity: 0; pointer-events: none; }
  .lib__grip { display: none; }
}

@media (max-width: 899px) {
  .lib {
    left: 0; right: 0; bottom: 0; height: 90vh; max-height: 90vh;
    border-radius: 18px 18px 0 0; border-bottom: none;
    transform: translateY(var(--lib-offset, 64%));
    transition: transform 0.42s var(--ease);
    touch-action: pan-y;
  }
  .lib.is-hidden { transform: translateY(100%); }
  .lib__grip, .lib__head { touch-action: none; }
}

.lib__grip { padding: 0.65rem 0 0.4rem; display: grid; place-items: center; cursor: grab; flex-shrink: 0; }
.lib__grip::after { content: ''; width: 40px; height: 4px; border-radius: 2px; background: rgba(23,18,13,0.22); }

.lib__head {
  position: relative; flex-shrink: 0;
  padding: 1rem 1.2rem 0.9rem;
  border-bottom: 1px solid var(--line); border-left: 3px solid var(--sand);
}
.lib__min {
  position: absolute; top: 0.6rem; right: 0.6rem;
  width: 28px; height: 28px; border-radius: 50%;
  border: 1px solid var(--line); background: rgba(23,18,13,0.04);
  color: var(--ink-dim); font-size: 1rem; line-height: 1; cursor: pointer;
  display: grid; place-items: center; transition: all 0.18s var(--ease);
}
.lib__min:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.lib__title { font-family: var(--serif); font-style: italic; font-weight: 500; font-size: 1.3rem; color: var(--ink); }
.lib__meter { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.7rem; }
.lib__meterText { font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint); white-space: nowrap; }
.lib__bar { flex: 1; height: 3px; border-radius: 2px; background: rgba(23,18,13,0.12); overflow: hidden; }
.lib__fill { height: 100%; width: 0; background: var(--sand); transition: width 0.55s var(--ease); }

/* min-height:0 or the body grows to fit every row and the overflow is simply clipped */
.lib__body {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
}

.lib__row {
  width: 100%; text-align: left; background: transparent; border: none;
  border-bottom: 1px solid rgba(23,18,13,0.08);
  padding: 0.85rem 1.2rem; display: flex; gap: 0.85rem; align-items: center;
  cursor: pointer; font-family: var(--sans); transition: background 0.18s ease;
}
.lib__row:hover, .lib__row:focus-visible { background: rgba(23,18,13,0.05); outline: none; }
.lib__row.is-seen .lib__name { color: var(--ink-dim); }
.lib__thumb {
  width: 62px; height: 46px; border-radius: 5px; flex-shrink: 0;
  background: rgba(23,18,13,0.1) center/cover no-repeat;
  display: grid; place-items: center; font-size: 1rem; color: var(--ink-faint);
}
.lib__main { flex: 1; min-width: 0; }
.lib__kind { font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--sand-deep); }
.lib__name { font-family: var(--serif); font-weight: 500; font-size: 1rem; line-height: 1.2; color: var(--ink); margin-top: 0.15rem; }
.lib__sub { font-size: 0.75rem; color: var(--ink-faint); margin-top: 0.12rem; }
.lib__tick { width: 20px; text-align: center; color: var(--sand); font-size: 0.85rem; flex-shrink: 0; }

/* ------------------------------------------------------------------ viewer */

.v-scrim {
  position: fixed; inset: 0; z-index: 40;
  background: rgba(8, 6, 4, 0.72);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  display: flex; align-items: center; justify-content: center; padding: 1.5rem;
  opacity: 0; pointer-events: none; transition: opacity 0.3s ease;
}
.v-scrim.is-open { opacity: 1; pointer-events: auto; }

.v-panel {
  position: relative;
  width: min(1100px, 100%); height: min(88vh, 880px);
  background: var(--paper); border-radius: 14px; overflow: hidden;
  display: grid; grid-template-rows: minmax(0, 1fr) auto;
  box-shadow: var(--lift);
  transform: translateY(16px) scale(0.985); transition: transform 0.4s var(--ease);
}
.v-scrim.is-open .v-panel { transform: none; }

/* A document has to be guaranteed most of the panel. The footer carries a title, a blurb
   and the navigation, and on a short screen that stack alone left the reading area at
   ~100px — a sliver of one page out of eight, which is indistinguishable from broken.
   The stage gets a floor; the footer gets a ceiling and scrolls if it needs to. */
.v-panel--pdf { grid-template-rows: minmax(58vh, 1fr) auto; }
.v-panel--pdf .v-foot {
  max-height: 30vh; overflow-y: auto; touch-action: pan-y;
  padding-top: 0.8rem; padding-bottom: 0.9rem;
}
.v-panel--pdf .v-blurb { display: none; }          /* the document is the point, not the caption */
@media (max-height: 720px) {
  .v-panel--pdf { grid-template-rows: minmax(66vh, 1fr) auto; }
  .v-panel--pdf .v-foot { max-height: 24vh; }
  .v-panel--pdf .v-title { font-size: 1.15rem; }
}

.v-stage {
  position: relative; min-height: 0; overflow: hidden;
  background: #0b0906; display: flex; align-items: center; justify-content: center;
}
.v-stage video { width: 100%; height: 100%; object-fit: contain; display: block; }
/* A document must fill the stage, not sit centred in it. The stage is a flex container
   with align-items:center, which is right for a photograph and fatal for a document:
   height:100% never stretches, so the PDF collapsed to a 32px strip with nothing in it.
   Documents get block layout and take the whole frame. */
.v-stage--doc {
  background: var(--paper-warm);
  display: block; align-items: stretch;
}

/* A photograph gets a frame it can be dragged around inside. The old behaviour was a
   click that swapped object-fit contain/cover, which is a two-state guess at what somebody
   wanted to look at. Now they choose: pinch, double-tap, drag, wheel. */
.v-imgwrap {
  position: relative; width: 100%; height: 100%; overflow: hidden;
  display: grid; place-items: center; touch-action: pan-y; cursor: grab;
}
.v-imgwrap:active { cursor: grabbing; }
.v-img {
  max-width: 100%; max-height: 100%; object-fit: contain; display: block;
  opacity: 0; transition: opacity 0.35s var(--ease);
  will-change: transform;
}
.v-img.is-ready { opacity: 1; }

/* Controls sit together in one cluster rather than scattered around the panel, so there is
   a single place to look for "how do I make this bigger / fill the screen / leave". */
.v-tools {
  position: absolute; top: 0.7rem; right: 0.7rem; z-index: 4;
  display: flex; align-items: center; gap: 0.35rem;
  padding: 0.25rem; border-radius: 999px;
  background: rgba(20,16,11,0.55);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.v-tool {
  width: 34px; height: 34px; flex-shrink: 0;
  border-radius: 50%; border: none; background: transparent;
  color: rgba(248,244,236,0.9); font-size: 1rem; line-height: 1;
  cursor: pointer; display: grid; place-items: center;
  transition: background 0.16s var(--ease), color 0.16s var(--ease);
}
.v-tool:hover { background: rgba(248,244,236,0.9); color: var(--ink); }
/* Resting state over a picture. Still visible enough to find, faint enough to look through. */
.v-tools { transition: opacity 0.5s var(--ease); }
.v-tools.is-idle { opacity: 0.28; }
/* :focus-within was wrong here. The dialog moves focus to the first control when it opens,
   which is a tool button, so the cluster was always "focused" and never actually faded —
   the class toggled correctly and the opacity never moved. :focus-visible only matches
   keyboard focus, which is the case the exception is for. */
.v-tools.is-idle:has(:focus-visible) { opacity: 1; }
.v-tool--close { background: rgba(248,244,236,0.16); }
.v-tool--level { width: auto; padding: 0 0.55rem; border-radius: 999px; }
.v-tools__level {
  font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.06em;
  min-width: 3.2em; text-align: center;
}
.v-tool--level.is-active { background: rgba(248,244,236,0.22); }

/* Full screen is the control people reach for on a small phone, so the panel has to
   actually become the screen rather than stay a centred card inside it. */
.v-panel.is-full { width: 100%; height: 100%; max-width: none; border-radius: 0; }

/* Something visible while a large video negotiates itself. */
.v-spin {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: rgba(248,244,236,0.6); pointer-events: none;
}

.v-foot {
  padding: 1.1rem 1.4rem 1.2rem;
  border-top: 1px solid var(--line);
  display: flex; align-items: flex-end; justify-content: space-between; gap: 1.5rem;
  flex-wrap: wrap;
}
.v-meta { min-width: 0; flex: 1 1 20rem; }
.v-kind { font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--sand-deep); }
.v-title { font-family: var(--serif); font-weight: 500; font-size: 1.5rem; line-height: 1.12; margin-top: 0.2rem; }
.v-sub { font-size: 0.84rem; color: var(--ink-faint); margin-top: 0.15rem; }
.v-blurb { font-family: var(--serif); font-size: 0.95rem; line-height: 1.55; color: var(--ink-dim); margin-top: 0.6rem; max-width: 56ch; }

.v-nav { display: flex; align-items: center; gap: 0.65rem; flex-shrink: 0; }
.v-navbtn, .v-chip {
  padding: 0.55rem 0.95rem; border-radius: 999px;
  border: 1px solid var(--line); background: transparent; cursor: pointer;
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink-dim); transition: all 0.18s var(--ease);
}
.v-navbtn:hover:not(:disabled), .v-chip:hover:not(:disabled) { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.v-navbtn:disabled, .v-chip:disabled { opacity: 0.35; cursor: default; }
.v-count { font-family: var(--mono); font-size: 0.62rem; color: var(--ink-faint); min-width: 3.6em; text-align: center; }

/* pdf */
.v-pdf { width: 100%; height: 100%; display: flex; flex-direction: column; background: var(--paper-warm); }
.v-pdf__pages {
  flex: 1 1 auto; min-height: 0;
  overflow: auto; -webkit-overflow-scrolling: touch;
  touch-action: pan-y; overscroll-behavior: contain;
  padding: 1rem; display: flex; flex-direction: column; gap: 1rem; align-items: center;
}
/* Zoom is width, not transform: scrolling stays native in both directions and the type
   stays sharp because the page is re-rendered at the size it is actually displayed. */
.v-pdf__pages canvas {
  width: calc(100% * var(--pdf-zoom, 1));
  max-width: none; height: auto; flex-shrink: 0;
  border-radius: 3px; box-shadow: 0 4px 16px rgba(10,8,5,0.2);
}
/* Centring a flex item that is wider than its container makes the left edge unreachable by
   scrolling, so once zoomed the pages align to the start instead. */
.v-pdf__pages.is-zoomed { align-items: flex-start; touch-action: pan-x pan-y; }
.v-pdf__bar {
  flex-shrink: 0; padding: 0.55rem 0.9rem; background: var(--paper);
  border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  flex-wrap: wrap;                      /* zoom and full screen live here too */
}
/* The cluster is styled for a dark scrim; in the bar it sits on warm paper and has to
   invert, or the glyphs are near-white on near-white. */
.v-pdf__bar .v-tool { color: var(--ink-dim); width: 32px; height: 32px; }
.v-pdf__bar .v-tool:hover { background: var(--ink); color: var(--paper); }
.v-pdf__bar .v-tool--level { width: auto; border: 1px solid var(--line); }
.v-pdf__bar .v-tool--level.is-active { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.v-pdf__group { display: flex; align-items: center; gap: 0.5rem; }
/* A hairline between "which page" and "how big", so the bar reads as two things. */
.v-pdf__group--tools { padding-left: 0.55rem; border-left: 1px solid var(--line); }
@media (max-width: 520px) {
  /* Once the groups stack, a left border is a line hanging off the side of nothing. */
  .v-pdf__group--tools { border-left: none; padding-left: 0; }
  .v-pdf__bar { gap: 0.35rem; padding: 0.45rem 0.6rem; }
  .v-pdf__pos { min-width: 7.5em; }
}
.v-pdf__pos { font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); min-width: 9em; text-align: center; }
/* Only the close button floats over a document now, so the pages need to clear exactly
   one button in the top-right corner rather than a whole cluster. */
.v-panel--pdf .v-tools { padding: 0; background: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.v-panel--pdf .v-tool--close { background: rgba(20,16,11,0.55); }

.v-fallback { padding: 2.5rem 1.5rem; text-align: center; color: var(--ink-dim); font-size: 0.9rem; line-height: 1.6; }

@media (max-width: 899px) {
  .v-scrim { padding: 0; align-items: flex-end; }
  .v-panel { width: 100%; height: 94vh; border-radius: 16px 16px 0 0; }
  .v-foot { padding: 0.9rem 1.1rem 1.1rem; flex-direction: column; align-items: stretch; gap: 0.9rem; }
  /* flex-basis follows the flex direction. `flex: 1 1 20rem` was written for the desktop row,
     where 20rem is a width; the moment this block turns the footer into a column that same
     20rem becomes a 320px floor on the HEIGHT, and it grows to take whatever is left. On a
     582px-tall window that gave the film 156px — 28% of the panel — and the caption 399px.
     The caption should take the room it needs and no more. */
  .v-meta { flex: 0 1 auto; }
  /* A photograph panel sizes to the photograph. Held at a fixed 94vh, a 4:3 picture on a
     tall phone sat in ~290px of empty black — the picture was complete but looked lost.
     The caption stays put at the bottom of whatever height the picture asks for. */
  .v-panel--image { height: auto; max-height: 94vh; }
  .v-panel--image .v-img { max-height: 68vh; }
  .v-title { font-size: 1.25rem; }
  .v-blurb { font-size: 0.88rem; }
  .v-nav { justify-content: space-between; }
  .v-tools { top: 0.5rem; right: 0.5rem; }
  .v-tool { width: 38px; height: 38px; }      /* thumb-sized, not cursor-sized */
}

/* -------------------------------------------------------------------- a11y */

.civic-sr-only, .sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.civic-skip {
  position: fixed; top: -100px; left: 1rem; z-index: 200;
  padding: 0.7rem 1.1rem; border-radius: 0 0 6px 6px;
  background: var(--ink); color: var(--paper); text-decoration: none;
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.12em; text-transform: uppercase;
  transition: top 0.18s ease;
}
.civic-skip:focus { top: 0; }
.pill:focus-visible, .lib__row:focus-visible, .v-navbtn:focus-visible,
.v-chip:focus-visible, .v-tool:focus-visible, .lib__min:focus-visible, canvas:focus-visible {
  outline: 2px solid var(--sand); outline-offset: 2px;
}

/* toast, reused by the stream-failure notice */
.civic-toast {
  position: fixed; left: 50%; bottom: 2rem; transform: translate(-50%, 12px);
  padding: 0.85rem 1.3rem; z-index: 60;
  background: var(--glass-strong); border: 1px solid var(--line); border-radius: 8px;
  -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px);
  font-family: var(--mono); font-size: 0.7rem; color: var(--ink);
  opacity: 0; pointer-events: none; transition: all 0.3s var(--ease);
  box-shadow: var(--soft); max-width: 84vw; text-align: center;
}
.civic-toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

@media (prefers-reduced-motion: reduce) {
  .lib, .v-panel, .v-scrim, .v-img, .lib__fill, .civic-toast { transition-duration: 0.01ms !important; }
}

/* ------------------------------------------------------------------- room */

.room {
  position: fixed; top: 4.6rem; right: 1.25rem; z-index: 19;
  width: min(280px, calc(100vw - 2.5rem));
  padding: 1rem 1.1rem 1.1rem;
  background: var(--glass-strong); border: 1px solid var(--line); border-radius: 12px;
  -webkit-backdrop-filter: blur(26px) saturate(1.15); backdrop-filter: blur(26px) saturate(1.15);
  box-shadow: var(--soft);
  opacity: 0; transform: translateY(-8px) scale(0.98);
  pointer-events: none; transition: all 0.26s var(--ease);
}
.room.is-open { opacity: 1; transform: none; pointer-events: auto; }

.room__label {
  font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--ink-faint);
  margin: 0.9rem 0 0.5rem;
}
.room__label:first-child { margin-top: 0; }

.room__chips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.room__chip {
  padding: 0.4rem 0.7rem; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: transparent; color: var(--ink-dim);
  font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.1em; text-transform: uppercase;
  transition: all 0.16s var(--ease);
}
.room__chip:hover { border-color: var(--ink-dim); color: var(--ink); }
.room__chip.is-on { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.room__range {
  width: 100%; margin: 0.2rem 0 0.3rem; accent-color: var(--sand);
  height: 22px; cursor: pointer;
}
.room__note { font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-faint); }

.room__toggle {
  display: flex; align-items: center; gap: 0.5rem; cursor: pointer;
  font-size: 0.78rem; color: var(--ink-dim); line-height: 1.35;
}
.room__toggle input { accent-color: var(--sand); width: 15px; height: 15px; flex-shrink: 0; }

.room__reset {
  width: 100%; margin-top: 0.2rem; padding: 0.55rem;
  border: 1px solid var(--line); border-radius: 6px; background: transparent; cursor: pointer;
  font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-faint); transition: all 0.16s var(--ease);
}
.room__reset:hover { color: var(--ink); border-color: var(--ink-dim); }

@media (max-width: 899px) {
  .room { top: auto; bottom: 5.6rem; left: 0.8rem; right: 0.8rem; width: auto; }
}

/* Placed last on purpose. A landscape phone matches both this and the max-width:899px
   block above; with equal specificity the later rule wins, and when this sat first every
   line of it was silently overridden. */
/* A phone in landscape is somebody who rotated in order to read more comfortably, and it
   was the one case where they got less: 212px of reading on an 812x375 screen, with 90px
   spent on a title block naming the thing they had just tapped. So on a short viewport the
   footer collapses to a single row — title on one line, navigation beside it — and the
   panel takes the whole screen. That is 212px to ~300px, on the orientation people choose
   specifically for reading. */
@media (max-height: 480px) {
  .v-panel { height: 100vh; border-radius: 0; }
  .v-foot {
    max-height: none; padding: 0.4rem 0.85rem;
    flex-direction: row; align-items: center; gap: 0.85rem; flex-wrap: nowrap;
  }
  .v-kind, .v-sub, .v-blurb { display: none; }
  .v-meta { flex: 1 1 auto; min-width: 0; }
  .v-title {
    font-size: 0.95rem; margin-top: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .v-panel--pdf { grid-template-rows: minmax(0, 1fr) auto; }
  .v-panel--pdf .v-foot { max-height: none; }
  .v-nav { flex-shrink: 0; }
}


/* Reading mode: the document, and nothing else.
 *
 * AJ's note was that the article is hard to read on a phone and tight on a laptop, and that
 * zooming in cuts it off. The cut-off is the giveaway - browser zoom shrinks the layout
 * viewport, so a panel sized in vh keeps its share of a smaller screen while the type gets
 * bigger, and the caption block ends up eating a reader that was already short. Dropping the
 * caption gives those rows back to the page instead.
 */
.v-panel--pdf.is-reading { grid-template-rows: 1fr; height: 100%; max-height: none; }
.v-panel--pdf.is-reading .v-foot { display: none; }
.v-pdf__group--view { padding-left: 0.55rem; border-left: 1px solid var(--line); }
.v-chip[target] { text-decoration: none; display: inline-flex; align-items: center; }

@media (max-width: 720px) {
  .v-panel--pdf.is-reading { height: 100vh; border-radius: 0; }
  .v-pdf__group--view { border-left: none; padding-left: 0; }
}

/* Short viewports - a laptop at 150% zoom, or a phone in landscape - are the case AJ hit.
 * Below this height the caption is costing more than it explains, so the document takes the
 * panel whether or not anyone pressed Expand. */
@media (max-height: 560px) {
  .v-panel--pdf { grid-template-rows: 1fr; }
  .v-panel--pdf .v-foot { display: none; }
}


/* Touch targets.
 *
 * Measured on a 375x812 phone, every control in the build came in under the 44px that
 * Apple's HIG and WCAG 2.5.5 both land on: the pills 29-33px, the zoom keys and the close
 * button 38, the library's minimise 28, the room chips 26 tall. Each one is individually
 * "fine" and collectively it is a site you have to aim at - which is exactly the wrong ask
 * of someone reading on a phone on a bus, or of anyone whose hands are less steady than a
 * designer's.
 *
 * Scoped to coarse pointers so a mouse-driven desktop keeps its tighter, quieter chrome.
 */
@media (hover: none) and (pointer: coarse) {
  .pill { min-height: 44px; min-width: 44px; }
  .v-tool { width: 44px; height: 44px; }
  .lib__min { width: 44px; height: 44px; }
  .v-chip { min-height: 44px; padding-top: 0; padding-bottom: 0; }
  .room__chip { min-height: 40px; }
  .room__reset { min-height: 44px; }
  .lib__row { min-height: 56px; }
}

/* Where the rest of it is.
 *
 * A phone in portrait sees about 36 degrees of a 360 degree room - roughly a tenth of it,
 * against a laptop's hundred-odd. With eight pieces spread right around you, that means one
 * orb on screen at a time and no way to tell whether you have found everything or are
 * standing with your back to half of it. The list answers that, but only if you think to
 * open the list.
 *
 * So: a count at each edge of what is still unopened that way, and tapping it turns you to
 * the nearest one. Widening the lens instead was the obvious alternative and the wrong one -
 * it would have shrunk the orbs and their labels to buy the same information.
 */
.peek {
  position: fixed; top: 50%; transform: translateY(-50%);
  z-index: 12; display: none; align-items: center; gap: 0.3rem;
  padding: 0.7rem 0.6rem; border: none; cursor: pointer;
  font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.06em;
  color: var(--ink); background: var(--glass-strong);
  -webkit-backdrop-filter: blur(9px); backdrop-filter: blur(9px);
  box-shadow: var(--soft);
  min-height: 52px; min-width: 44px; justify-content: center;
}
.peek.is-on { display: flex; }
.peek--l { left: 0; border-radius: 0 22px 22px 0; padding-left: 0.45rem; }
.peek--r { right: 0; border-radius: 22px 0 0 22px; padding-right: 0.45rem; }
.peek__n { font-weight: 600; }
.peek__c { font-size: 0.95rem; line-height: 1; opacity: 0.75; }
.peek:hover { background: var(--paper); }

@media (prefers-reduced-motion: reduce) {
  .peek { transition: none; }
}
