/* Report Builder workspace shell.
   Desktop composition layout; the sheet stays visible on tablet and phone.
   Does not restyle Distress, Floor Survey, or the Customer File home. */

.rb-shell {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  width: 100%;
}

body.report-builder-open .canvas {
  overflow: hidden;
}

.rb-identity .file-status {
  color: var(--accent-dark);
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.rb-toolbar {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  width: 100%;
  min-width: 0;
  padding: 6px 12px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  box-sizing: border-box;
}

.rb-toolbar__lead {
  flex: 1 1 280px;
  min-width: 0;
  margin: 0;
  color: var(--ink-soft);
  font-size: 12px;
  line-height: 1.35;
}

.rb-export {
  flex: 0 0 auto;
  min-height: 32px;
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.rb-ai-status {
  flex: 1 1 100%;
  min-width: 0;
  margin: 0;
  color: var(--ink-soft);
  font-size: 12px;
  line-height: 1.35;
}

.rb-ai-status:empty {
  display: none;
}

.rb-workspace {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: 184px minmax(0, 1fr) 280px;
  grid-template-rows: minmax(0, 1fr);
  min-height: 0;
  min-width: 0;
}

.rb-rail,
.rb-panel {
  min-width: 0;
  min-height: 0;
  background: rgba(255, 255, 255, 0.94);
  box-sizing: border-box;
}

.rb-rail {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 10px;
  border-right: 1px solid var(--line);
  overflow: hidden;
}

.rb-rail__head strong {
  display: block;
  color: var(--navy);
  font-size: 14px;
}

.rb-rail__head span {
  display: block;
  margin-top: 2px;
  color: var(--ink-soft);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.rb-rail__list {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  overflow: auto;
  padding-right: 2px;
}

.rb-thumb {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
  width: 100%;
  padding: 6px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-align: left;
}

.rb-thumb.is-active {
  border-color: var(--navy);
  background: #f4f7f8;
}

.rb-thumb__sheet {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  aspect-ratio: 17 / 11;
  width: 100%;
  padding: 4px 6px;
  border: 1px solid #1a1a1a;
  background: #fff;
  box-sizing: border-box;
  overflow: hidden;
}

/* The page itself, drawn small. The sheet is a size container and everything
   on it is sized in cqh, so this is a true miniature rather than a scaled
   screenshot -- it reads at 150 px for the same reason it reads at 17 in.
   It is a picture of the page, never a second place to edit one, so nothing
   in here takes a pointer. */
/* The preview is a full-size sheet, shrunk.
   Rendering the page straight into a 150 px box looked like the obvious
   move -- the sheet is a size container and its type is in cqh -- but the
   report's type is written as clamp(16px, 2.6cqb, 26px), and on a stamp
   every one of those clamps hits its pixel floor. The result was a page of
   16 px headings over a thumbnail-sized plan. So the preview is laid out at
   the sheet's own size, where every clamp lands where it does on the real
   page, and then scaled down as one picture. --rb-thumb-scale is set from
   the width it has to fit. */
.rb-sheet--thumb {
  position: absolute;
  left: 0;
  top: 0;
  /* The paper's own size -- PAPER_W x PAPER_H in report-builder.js, which is
     11x17 at 96dpi. fitThumb divides the box width by PAPER_W to get the
     scale, so these two numbers have to BE that size. They were 680 x 440,
     the stage's old size, and when the sheet became the paper this was left
     behind: every preview was then drawn at 680/1632 of its box -- a page
     crammed into the top-left corner of the stamp with white to the right of
     it and below it. Tim, Oct 23, 2026: "The slides don't show fully." */
  width: 1632px;
  height: 1056px;
  margin: 0;
  border: 0;
  overflow: hidden;
  background: #fff;
  color: #111;
  box-shadow: none;
  box-sizing: border-box;
  container-type: size;
  transform-origin: top left;
  transform: scale(var(--rb-thumb-scale, 0.22));
  pointer-events: none;
  user-select: none;
}

/* A preview shows the page, not the editor around it. The same chrome the
   print deck drops -- the lock bar, the Import toolbar, the placement
   outlines and the resize corners -- has no business in a stamp either, and
   it is sized in px rather than cqh, so it came out full size on a 150 px
   preview and buried the page underneath it. */
.rb-sheet--thumb .rb-floor-toolbar,
.rb-sheet--thumb .rb-cover__contents-jump,
.rb-sheet--thumb .rb-cover__overview-actions,
.rb-sheet--thumb .rb-cover__overview-empty,
.rb-sheet--thumb .rb-cover-box__resize,
.rb-sheet--thumb .rb-cover-box__move,
.rb-sheet--thumb .rb-floor-box__resize,
.rb-sheet--thumb .rb-floor-overview__remove,
.rb-sheet--thumb .rb-floor-empty,
.rb-sheet--thumb .rb-discussion__overflow,
.rb-sheet--thumb .rb-discussion__move,
.rb-sheet--thumb .rb-discussion__resize,
/* The live drawing cannot mount in a preview, and saying so on a stamp is
   noise -- the picture of the drawing goes here instead, once one has been
   taken. */
.rb-sheet--thumb .rb-topo-page__drawing--live .rb-sheet__note {
  display: none !important;
}

.rb-sheet--thumb .rb-cover-box,
.rb-sheet--thumb .rb-floor-box,
.rb-sheet--thumb [data-rb-rich] {
  outline: none !important;
}

/* A Floor Survey slide's drawing, photographed while it was on screen. */
.rb-thumb__shot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: fill;
}

/* The page number sits over the preview, so it stays readable on a dark
   plan. */
.rb-thumb__num {
  position: relative;
  z-index: 2;
  padding: 0 4px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.86);
}

.rb-thumb__num,
.rb-thumb__caption {
  color: var(--ink-soft);
  font-size: 11px;
  font-weight: 700;
}

.rb-thumb__caption {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  line-height: 1.25;
  white-space: normal;
}

.rb-rail__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.rb-rail__actions .btn {
  min-height: 32px;
  padding: 4px 8px;
  font-size: 12px;
}

/* The stage shows the paper zoomed to fit. The sheet keeps its own 1632 x
   1056 and a transform does the zooming, so the box it visually fills has to
   be a real box of its own -- a transformed element still reserves its full
   unscaled size in layout, and the stage would centre THAT. */
.rb-stage__paper {
  position: relative;
  flex: 0 0 auto;
  overflow: hidden;
  background: #fff;
  border: 1px solid #1a1a1a;
  box-shadow: 0 14px 36px rgba(8, 32, 54, 0.16);
  box-sizing: content-box;
}

.rb-stage__paper > .rb-sheet {
  transform-origin: top left;
}

.rb-stage {
  display: flex;
  min-width: 0;
  min-height: 0;
  padding: 16px;
  background:
    linear-gradient(180deg, rgba(8, 32, 54, 0.04), rgba(8, 32, 54, 0.02)),
    #e5e0d6;
  box-sizing: border-box;
}

.rb-sheet {
  /* ONE REPORT, ONE TYPEFACE. Declared on the paper so everything drawn on
     it inherits, rather than on each block -- which is how the fault got in.
     The cover and the discussion each declared this stack; the figure pages
     declared a Segoe one; and the Picture Locations sheet declared nothing
     at all, so it fell through to the app's own UI font and the distress
     descriptions came out in a third face. Tim, Oct 23, 2026: "everything
     should be in the discussion page cover font stream."
     The drawing title rail is the one deliberate exception -- see
     .rb-rail__rail, which is a serif title block on an engineering sheet. */
  --rb-face: Calibri, Carlito, "Segoe UI", system-ui, -apple-system, sans-serif;
  font-family: var(--rb-face);
  position: relative;
  flex: 0 0 auto;
  align-self: center;
  /* THE SHEET IS THE PAPER. 11x17 landscape is 1632 x 1056 CSS pixels at
     96dpi, and the sheet is drawn at that size everywhere -- the editor, the
     flip chart, the printer. Every view only ZOOMS it.
     It used to be resized to fill whatever window it was in, so a style set
     in pixels rather than in container units took up a different share of
     the page on every screen, and the PDF could never agree with the editor.
     A pixel here is now a real, fixed size on the paper: 96 to the inch. */
  width: 1632px;
  height: 1056px;
  max-width: none;
  overflow: hidden;
  background: #fff;
  color: #111;
  /* No edge of its own. A 1px border with box-sizing: border-box ate two
     pixels of the page, so the content box was 1630 wide on screen and 1632
     on paper -- a measurement taken at one size and used at another, which
     is the whole class of bug this change exists to end. The paper's edge
     and its shadow belong to the stage, which is where they are drawn. */
  border: 0;
  box-sizing: border-box;
  container-type: size;
  /* The rail's layout assumes the sheet is its own stacking context. */
  isolation: isolate;
}

/* One frame, the same shape in the same place on every page. It is drawn
   against the sheet, so the content box below only holds the content in. */
.rb-sheet__frame {
  position: absolute;
  border: 0.19cqh solid #1a1a1a;
  box-sizing: border-box;
  pointer-events: none;
  /* Over the page content, not under it. At 0 it sat beneath the Floor Survey
     drawing, and once that drawing went full bleed it painted straight over
     the border -- white canvas on top of a black line, so the page border
     vanished on exactly that slide. */
  z-index: 4;
}

/* DRAFT, across the sheet. Sized in cqh like everything else on the page so
   the thumbnail, the stage, Presentation and the printer all show the same
   stamp at their own scale. It sits ABOVE the content, not behind it: on a
   Floor Survey figure the drawing goes full bleed, so a stamp underneath
   would simply be invisible. Low alpha is what makes it read as a watermark.
   print-color-adjust keeps the printer from dropping it as background. */
.rb-sheet__draft {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 5;
  font-family: 'Oswald', 'Arial Narrow', Arial, sans-serif;
  font-size: 26cqh;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1;
  white-space: nowrap;
  color: rgba(176, 32, 32, 0.16);
  transform: rotate(-24deg);
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

.rb-sheet__margin {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  /* As tall as the sheet LESS its own two margins. It used to be the full
     height of the sheet and then pushed down by the top margin, so every
     page sat the margin's depth below where it ended -- invisible behind
     overflow:hidden on most pages, and the reason a full Pictures page ran
     past the bottom of the paper. The margin is a percentage of the sheet's
     WIDTH, as CSS margins are, so the height subtracts the same unit: 9cqw
     is exactly the two of them. */
  height: calc(100% - 9cqw);
  margin: 4.5cqw;
  /* No border of its own: it used to draw a second, different box at a 4.5%
     inset in another colour, which is what made the page border land in a
     different place depending on which page you were looking at. */
  border: 0;
  padding: 3.5% 4% 2.5%;
  box-sizing: border-box;
  overflow: hidden;
}

.rb-sheet__kicker,
.rb-sheet__title,
.rb-sheet__note,
.rb-sheet__page {
  margin: 0;
  color: #6d6a64;
  font-weight: 500;
}

.rb-sheet__kicker {
  font-size: clamp(10px, 1.4cqb, 13px);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.rb-sheet__kicker--quiet {
  margin-top: 2px;
  letter-spacing: 0.04em;
  text-transform: none;
}

.rb-sheet__title {
  margin-top: 4px;
  color: #222;
  font-size: clamp(16px, 3cqb, 28px);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.rb-evidence-frame {
  display: flex;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  margin-top: 8px;
  overflow: auto;
  gap: 10px;
}

.rb-evidence-plan {
  position: relative;
  flex: 1 1 58%;
  min-width: 0;
  overflow: hidden;
  background: #f5f3ef;
}

.rb-evidence-plan__image,
.rb-evidence-figure,
.rb-evidence-pdf {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.rb-evidence-pin {
  position: absolute;
  display: grid;
  place-items: center;
  min-width: 17px;
  height: 17px;
  border-radius: 50%;
  background: #9b2b21;
  color: white;
  font-size: 10px;
  transform: translate(-50%, -50%);
}

.rb-evidence-observations {
  flex: 1 1 42%;
  min-width: 0;
  overflow: auto;
}

.rb-evidence-observation {
  margin-bottom: 8px;
  border-bottom: 1px solid #ddd;
  font-size: 11px;
}

.rb-evidence-observation__heading,
.rb-evidence-observation__text,
.rb-evidence-photo__caption {
  margin: 2px 0;
  white-space: pre-wrap;
}

.rb-evidence-observation__heading { font-weight: 700; }
.rb-evidence-photo { display: inline-block; width: 72px; margin: 4px; vertical-align: top; }
.rb-evidence-photo__image { display: block; max-width: 100%; max-height: 80px; object-fit: contain; }

.rb-sheet__note {
  max-width: 40em;
  margin-top: 6px;
  font-size: clamp(11px, 1.7cqb, 14px);
  line-height: 1.35;
}

.rb-sheet__meta {
  margin: 2px 0 0;
  color: #333;
  font-size: clamp(12px, 1.8cqb, 16px);
  line-height: 1.35;
}

.rb-sheet__body,
.rb-toc,
.rb-dl {
  min-height: 0;
}

.rb-toc {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 8px;
  overflow: auto;
}

.rb-toc__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 28px;
  padding: 2px 0;
  border: 0;
  background: transparent;
  color: #222;
  font: inherit;
  font-size: clamp(12px, 1.8cqb, 16px);
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
}

.rb-toc__item span:first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rb-toc__num {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

.rb-dl {
  display: grid;
  grid-template-columns: 9.5em minmax(0, 1fr);
  gap: 4px 10px;
  margin: 10px 0 0;
}

.rb-dl dt,
.rb-dl dd {
  margin: 0;
  font-size: clamp(12px, 1.8cqb, 15px);
  line-height: 1.35;
}

.rb-dl dt {
  color: #6d6a64;
  font-weight: 700;
}

.rb-dl dd {
  color: #222;
  overflow-wrap: anywhere;
}

.rb-figure {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  margin-top: 8px;
  padding: 8px;
  border: 1px solid #1a1a1a;
  background: #f7f7f5;
  color: #444;
  font-size: clamp(12px, 1.8cqb, 16px);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-align: center;
}

.rb-sheet__page {
  margin-top: auto;
  padding-top: 12px;
  align-self: flex-end;
  color: #111;
  font-size: clamp(11px, 1.6cqb, 14px);
  font-weight: 700;
}

.rb-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 14px 18px;
  border-left: 1px solid var(--line);
  overflow: auto;
}

.rb-panel h2,
.rb-panel h3 {
  margin: 0;
  color: var(--navy);
  letter-spacing: -0.02em;
}

.rb-panel h2 {
  font-size: 18px;
}

.rb-panel h3 {
  font-size: 15px;
}

.rb-panel__lead {
  margin: 0;
  color: var(--ink-soft);
  font-size: 13px;
  line-height: 1.4;
}

.rb-panel__links {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
}

.rb-panel__links .btn {
  width: 100%;
  justify-content: center;
}

.rb-panel__links .btn.is-current {
  border-color: var(--navy);
  box-shadow: inset 0 0 0 1px var(--navy);
}

@media (max-width: 1100px) {
  .rb-workspace {
    grid-template-columns: 132px minmax(0, 1fr);
    grid-template-rows: minmax(240px, 1fr) auto;
    overflow: auto;
  }

  .rb-panel {
    grid-column: 1 / -1;
    border-left: 0;
    border-top: 1px solid var(--line);
    max-height: 34vh;
  }
}

@media (max-width: 720px) {
  .rb-toolbar {
    padding: 6px 10px;
  }

  .rb-toolbar__lead {
    flex-basis: 100%;
  }

  .rb-workspace {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(210px, 1fr) auto;
  }

  .rb-rail {
    flex-direction: row;
    align-items: stretch;
    gap: 8px;
    padding: 8px 10px;
    border-right: 0;
    border-bottom: 1px solid var(--line);
    overflow: auto;
  }

  .rb-rail__head {
    flex: 0 0 auto;
    width: 92px;
  }

  .rb-rail__head strong {
    font-size: 13px;
  }

  .rb-rail__list {
    flex: 1 1 auto;
    flex-direction: row;
    align-items: flex-start;
    overflow-x: auto;
    overflow-y: hidden;
  }

  .rb-thumb {
    width: 108px;
    flex: 0 0 auto;
  }

  .rb-rail__actions {
    flex: 0 0 auto;
    width: 108px;
    align-content: flex-start;
  }

  .rb-stage {
    padding: 10px;
  }

  .rb-panel {
    max-height: none;
    padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  }
}

/* Mitchell / 1515 fixed-slot Floor Level pages.
   Legend + H/L/Δ + relative-readings are report chrome, not field Topo paste. */

.rb-sheet__margin--topo,
.rb-sheet__margin--pictures {
  margin: 2.2%;
  /* A margin of its own means a height of its own. The base rule subtracts
     the 4.5cqw margins it sets; these pages set 2.2% instead, and without
     this they went on subtracting the larger pair -- three quarters of an
     inch of page that nothing could be put on. A CSS margin is a share of
     the WIDTH either way, so the height subtracts the same unit. */
  height: calc(100% - 4.4cqw);
  padding: 1.6% 2% 1.4%;
  border-color: rgba(30, 64, 110, 0.55);
}

/* An imported Floor Survey slide draws on the sheet, not inside the inset box
   every other page uses. That inset -- 2.2% of margin plus 1.6%/2%/1.4% of
   padding, clipped by overflow:hidden on .rb-sheet__margin -- was a band of
   white the plan could never be moved into, and the same boundary cut the plan
   off when it was panned, which read as geometry having been deleted. It is
   also why the band was not symmetrical: the top and bottom padding differ. */
/* The pages that bleed: no margin, no padding, and -- the part that has to
   travel with them -- the whole height of the sheet.
   .rb-sheet__margin takes its height as the sheet LESS its own two margins,
   so a page that sets margin:0 and nothing else came out a margin's depth
   short of the paper: a sixth of an inch and a half of writing area gone,
   with the brand mark still drawn against the sheet and so left stranded
   below it. Tim, looking at the discussion page: "we can go down a bit
   further." Keeping the two declarations in one rule is what stops the next
   bled page losing the same inch and a half. */
.rb-sheet__margin--cover,
.rb-sheet__margin--discussion,
.rb-sheet__margin--topo-bleed {
  margin: 0;
  padding: 0;
  border: 0;
  height: 100%;
}

.rb-topo-page {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  gap: 0.5%;
  color: #17130e;
  /* One report, one typeface. The figure pages were on a Segoe stack while
     the cover and the discussion were on Calibri, so the distress
     descriptions in the Picture Locations table -- which set no font of
     their own and inherit this one -- came out in a different face from
     everything Tim had written. Tim, Oct 23, 2026: "whatever font you use
     in Report Builder on the main screen, it needs to apply to the distress
     survey descriptions as well"; "everything should be in the discussion
     page cover font stream." This is that stack, character for character.
     The drawing title rail keeps Georgia on purpose -- see .rb-rail__rail. */
  font-family: var(--rb-face);
}

/* The drawing's upper-left header is gone. The rail carries the figure
   number, the drawing title, the date and the identity -- Tim, Oct 21: the
   figure number "does not need to be in the upper left-hand corner anymore
   now that we have the title block." */

.rb-topo-page__north {
  width: 28px;
  height: 36px;
  flex: 0 0 auto;
}

.rb-topo-page__north svg {
  display: block;
  width: 100%;
  height: 100%;
}

.rb-topo-page__body {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: stretch;
  justify-content: center;
}

/* The hosted Floor Survey view fills its box on the page. The canvas inside
   sizes itself to this, and the camera is expressed against fit, so the same
   stored view frames the same thing here and on 11 x 17 paper. */
/* The workspace rail — the controls for whatever slide is open. Import at the
   top, that workspace's own controls in the middle, the way back at the
   bottom.

   Named rb-ws, NOT rb-rail: .rb-rail is already the pages rail on the left and
   carries overflow:hidden, which clipped every control below Palette the
   moment this reused the name. */
/* One scroller for the whole rail.
 *
 * The buttons at the top used to be pinned and the controls beneath them got
 * whatever height was left. Add two buttons and that share shrinks: on a
 * 1536 x 864 screen the Floor Survey controls -- Contours, Mode, Step, Line
 * thickness, Palette, a thousand pixels of them -- were squeezed into a 64px
 * scroller, which reads as gone. Tim, looking at his own rail after three
 * locks replaced one: "I didn't tell you to get rid of all the contour
 * settings, did I?"
 *
 * Nothing is pinned now, so nothing can be squeezed out: the rail is one
 * list that scrolls, the way a settings panel does. The cost is that the way
 * back scrolls with it, which is a smaller loss than a panel disappearing. */
.rb-ws {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 2px 8px 8px;
}
/* Title and the tab/tool row stick as one piece. Separate sticky offsets
   overlapped once the Topo row made the tool block taller than the old 28px. */
.rb-ws__sticky {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: rgba(255, 255, 255, 0.96);
}
.rb-ws__title {
  margin: 0;
  font-size: 18px;
  line-height: 22px;
  position: static;
  background: transparent;
  padding-bottom: 0;
}
.rb-ws__top,
.rb-ws__foot { display: flex; flex-direction: column; gap: 6px; flex: 0 0 auto; }
.rb-ws__top {
  position: static;
  background: transparent;
  padding-bottom: 6px;
}
.rb-ws__body {
  flex: 0 0 auto;
  min-height: 0;
  overflow: visible;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.rb-ws__btn { width: 100%; }
.rb-ws__controls { display: block; }
.rb-ws__controls .floor-survey-host,
.rb-ws__controls .rtw-root--controls { display: block; height: auto; }

/* GPT-036: Sheet Layout | Topo as folder tabs on the rail's top edge.
   Rounded tops, flat bottoms, no capsule. The active tab is the white
   panel; the baseline continues under the inactive tab. */
.rb-ws__sticky:has(.rb-ws__task-tabs) {
  gap: 6px;
  margin-bottom: -10px;
  background: #fff;
}
.rb-ws__top:has(.rb-ws__task-tabs) {
  gap: 0;
  padding-bottom: 0;
  background: #fff;
}
.rb-ws__sticky:has(.rb-ws__task-tabs) + .rb-ws__body {
  padding-top: 10px;
  background: #fff;
}
.rb-ws__task-tabs {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  margin: 0;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--line, #dce1e4);
  border-radius: 0;
  background: transparent;
}
.rb-ws__task-tab {
  appearance: none;
  position: relative;
  flex: 0 0 auto;
  margin: 0 0 -1px;
  border: 1px solid var(--line, #dce1e4);
  border-bottom-color: var(--line, #dce1e4);
  border-radius: 6px 6px 0 0;
  box-shadow: none;
  min-height: 36px;
  padding: 6px 12px;
  font: inherit;
  font-size: 13px;
  font-weight: 650;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--navy, #07283d);
  background: #e5ebee;
  cursor: pointer;
}
.rb-ws__task-tab:hover:not(.is-active) {
  background: #d9e4e9;
}
.rb-ws__task-tab:focus {
  outline: none;
}
.rb-ws__task-tab:focus-visible {
  outline: 2px solid var(--navy, #07283d);
  outline-offset: -3px;
}
.rb-ws__task-tab.is-active {
  z-index: 1;
  background: #fff;
  color: var(--navy, #07283d);
  border-bottom-color: #fff;
  box-shadow: none;
}
/* Topo and its three sub tabs are one set. Sheet Layout stays the gray tab. */
.rb-ws__task-tab.is-active[data-rb-floor-task="topo"] {
  color: #c14a2b;
  font-weight: 700;
}
/* Second tier under Topo: the same folder tabs, drawn smaller.
   Rounded tops, flat bottoms, cool-gray inactive, white active tab that
   interrupts this row's baseline. Not a pill, and not an underline. */
.rb-ws__subtabs {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  margin: 3px 0 0;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--line, #dce1e4);
  border-radius: 0;
  background: transparent;
}
.rb-ws__subtab {
  appearance: none;
  position: relative;
  flex: 0 0 auto;
  min-width: 0;
  min-height: 26px;
  margin: 0 0 -1px;
  padding: 2px 7px 3px;
  border: 1px solid var(--line, #dce1e4);
  border-bottom-color: var(--line, #dce1e4);
  border-radius: 5px 5px 0 0;
  background: #e5ebee;
  box-shadow: none;
  color: #c14a2b;
  font: inherit;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
}
.rb-ws__subtab:hover:not(.is-active) {
  background: #d9e4e9;
}
.rb-ws__subtab:focus {
  outline: none;
}
.rb-ws__subtab:focus-visible {
  outline: 2px solid var(--navy, #07283d);
  outline-offset: -3px;
}
.rb-ws__subtab.is-active {
  z-index: 1;
  background: #fff;
  border-bottom-color: #fff;
  box-shadow: none;
}
.rb-ws__section-label {
  margin: 4px 0 0;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-soft, #7a7468);
}
.rb-panel__idle h2 { margin: 0 0 6px; font-size: 18px; }

/* The stage a stripped Floor Survey slide positions its frame against. */
.rb-floor-stage--bare { position: absolute; inset: 0; }

.rb-topo-page__drawing--live {
  position: relative;
  overflow: hidden;
}

/* The floor plan's corner resize grips.
 *
 * Hidden until the plan is selected, the way every other handle on a report
 * sheet behaves -- the logo's resize corner, the cover boxes' move handle, an
 * annotation's grip and delete pip. Left always-on they read as part of the
 * drawing rather than as a control, and they were printing, because they are
 * the one handle in Report Builder that never got a print rule. */
[data-plan-resize] { display: none; }
.rb-sheet--plan-selected [data-plan-resize] { display: block; }

@media print {
  [data-plan-resize] { display: none !important; }
}

/* The plan's own corner pulls: the same crop-mark bracket as the frame's. */
.rb-plan-corner {
  border: 0 solid #1e406e;
  background: transparent;
  box-shadow: none;
  filter: drop-shadow(0 0 1px #fff) drop-shadow(0 0 1px #fff);
}

.rb-plan-corner--nw { border-top-width: 2px; border-left-width: 2px; }
.rb-plan-corner--ne { border-top-width: 2px; border-right-width: 2px; }
.rb-plan-corner--sw { border-bottom-width: 2px; border-left-width: 2px; }
.rb-plan-corner--se { border-bottom-width: 2px; border-right-width: 2px; }

/* Two views of one level, side by side. Which one the rail's controls are
   driving is marked by brackets at its corners -- the same crop-mark language
   as the resize pulls, and like them it is a thing the investigator is doing,
   so it never reaches the paper. */
.rb-floor-box[data-rb-topo-frame] { cursor: pointer; }

.rb-floor-box.is-active::before,
.rb-floor-box.is-active::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border: 0 solid #1e406e;
  pointer-events: none;
}

.rb-floor-box.is-active::before {
  left: -4px; top: -4px;
  border-top-width: 2px; border-left-width: 2px;
}

.rb-floor-box.is-active::after {
  right: -4px; bottom: -4px;
  border-bottom-width: 2px; border-right-width: 2px;
}

@media print {
  .rb-floor-box.is-active::before,
  .rb-floor-box.is-active::after { content: none; }
}

/* The still picture a printed slide draws when the live view is on another
   slide. It fills the frame the live view would have filled, so the slide
   prints the way it looks. */
.rb-topo-still {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  z-index: 1;
}

.rb-topo-live {
  position: absolute;
  inset: 0;
  /* Under the frame's own handles. The drawing covers the whole frame, so at a
     higher layer it swallowed the corner and the frame could not be resized --
     the same mistake as putting the logo over its own Lock button. */
  z-index: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.rb-topo-live .floor-survey-host,
.rb-topo-live .rtw-root {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.rtw-note {
  padding: 1.5cqh 1.5cqw;
  color: #6b625a;
  font-size: 1.5cqh;
}

.rb-topo-page__drawing {
  position: relative;
  z-index: 0;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  overflow: hidden;
}

.rb-topo-page__image {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* High / Low markers. Placed boxes like the colour scale and the pill, not
   pixels inside the figure, so they can be nudged off a wall or a doorway. */
.rb-topo-pin {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.12em 0.5em 0.12em 0.14em;
  border: 1px solid rgba(17, 17, 17, 0.35);
  border-radius: 999px;
  background: #fff;
  font-size: 1.35cqh;
  line-height: 1.5;
  white-space: nowrap;
}

.rb-topo-pin__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6em;
  height: 1.6em;
  border-radius: 50%;
  background: #E9C46A;
  color: #1a1a1a;
  font-weight: 800;
}

.rb-topo-pin--hi .rb-topo-pin__dot { background: #E9C46A; }
.rb-topo-pin--lo .rb-topo-pin__dot { background: #E9C46A; }
.rb-topo-pin__value { font-weight: 700; }

/* The colour scale on a Floor Survey page: Floor Survey's own scale, painted
   by Floor Survey and placed here as a picture.
 *
 * Its size is the paper's, not the screen's. Tim: "it does not lock the
 * size." It was drawn here in screen pixels -- an 8px label and an 88px bar
 * -- so the scale was a different fraction of the sheet on every window and
 * a different size again on the printed page. 20.5cqw is the size the Floor
 * Survey screen draws it: 226 units of its own 1100-unit reference across the
 * long side of what it is drawn on, which on a sheet is the paper. Legend
 * size still scales it from there, the same control as in the field. */
.rb-topo-legend {
  width: 7.44cqw;
  height: 20.5cqw;
}

.rb-topo-legend__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
}

/* The report slide's H / L / delta pill. Set like the field app's, which is
   set like the shipped Mitchell deck: the readings packed close to their
   dividers, and each one in the colour of its own letter -- the reds and
   blues measured off that deck, which this had drifted away from. See
   floor-survey/src/lib/stats-pill.ts, the one place those numbers are
   written down. */
.rb-topo-stats {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 3px 4px;
  padding: 3px 4px;
  border: 1px solid rgba(23, 19, 14, 0.45);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.96);
  font-size: 9px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  white-space: nowrap;
}

.rb-topo-stats__label {
  color: #6b7280;
  font-weight: 700;
}

.rb-topo-stats__hi {
  color: #b51d16;
}

.rb-topo-stats__lo {
  color: #1f5f9f;
}

.rb-topo-stats__delta {
  color: #6b7280;
}

.rb-topo-stats b {
  font-weight: 800;
}

.rb-topo-page__footer {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-end;
  /* The readings block used to sit opposite a logo drawn in this footer. The
     logo is placed against the sheet now, so the readings keep their side
     rather than sliding across to fill the gap. */
  justify-content: flex-end;
  gap: 12px;
  margin-top: 0.4%;
}

.rb-topo-page__brand {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.rb-topo-page__brand-mark {
  width: 34px;
  height: 18px;
  background:
    linear-gradient(135deg, transparent 42%, #111 42% 58%, transparent 58%),
    linear-gradient(45deg, transparent 38%, #111 38% 52%, transparent 52%),
    linear-gradient(160deg, transparent 45%, #333 45% 55%, transparent 55%);
  background-size: 14px 14px, 12px 12px, 10px 10px;
  background-position: 0 4px, 10px 4px, 20px 6px;
  background-repeat: no-repeat;
}

.rb-topo-page__brand-name {
  font-size: clamp(11px, 1.7cqb, 15px);
  font-weight: 800;
  letter-spacing: 0.04em;
}

.rb-topo-page__readings {
  flex: 0 0 auto;
  min-width: min(42%, 260px);
  max-width: 48%;
  padding: 0.55em 0.75em 0.45em;
  border: 1.5px solid #2f5f9a;
  background: #fff;
}

.rb-topo-page__readings-row {
  display: flex;
  align-items: center;
  gap: 0.45em;
  margin-bottom: 0.28em;
  font-size: clamp(10px, 1.45cqb, 13px);
  font-weight: 600;
  line-height: 1.2;
}

.rb-topo-page__readings-badge {
  display: grid;
  place-items: center;
  width: 1.35em;
  height: 1.35em;
  border-radius: 50%;
  background: #f2d34a;
  border: 1px solid #111;
  font-size: 0.85em;
  font-weight: 800;
  flex: 0 0 auto;
}

.rb-topo-page__readings-total {
  margin-top: 0.35em;
  padding-top: 0.35em;
  border-top: 1px solid rgba(23, 19, 14, 0.35);
  text-align: center;
  font-size: clamp(10px, 1.45cqb, 13px);
  font-weight: 700;
}

/* Mitchell title page: movable filled boxes + optional site overview. */
/* ------------------------------------------------------------------ *
 * Title / cover page — measured from the shipped decks.
 *
 * PowerPoint positions against the whole 11 x 17 slide, so the cover
 * stage is the whole sheet and .rb-sheet__margin--cover is full bleed.
 * The visible border is Mitchell's own frame rectangle (0.9% inset),
 * not the inset margin box the other page types draw.
 *
 * Type is sized in cqh with NO clamp: the page is 11 in = 792 pt, so
 * 1 pt = 0.12626 cqh and the sheet stays proportional at any size,
 * preview or print. A clamp would cap growth and break that.
 *   60 pt = 7.576   32 pt = 4.040   16 pt = 2.020
 *   14 pt = 1.768   13 pt = 1.641   12 pt = 1.515
 * ------------------------------------------------------------------ */

.rb-sheet__margin--cover {
  overflow: visible;
}

.rb-cover {
  --rb-copper: #8B5E3C;
  --rb-sage: #8FA17E;
  --rb-ink: #1A1A1A;
  --rb-gray: #595959;
  --rb-frame: #C8C0B4;
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  height: 100%;
  background: #fff;
  color: var(--rb-ink);
  font-family: var(--rb-face);
}

.rb-cover__stage {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
}

/* Mitchell "Picture 20": the page frame, 0.9% in from the slide edge. */
.rb-cover-box {
  position: absolute;
  box-sizing: border-box;
  touch-action: none;
}

/* A box shows its dashed edge and its two corner pulls when it is pointed
   at, not before. Tim, Oct 17: "all those corner blocks -- that's one of the
   things I really dislike about this page." It is the rule the Floor Survey
   pieces already follow: twenty brackets standing on a finished title page
   are our chrome printed over his report. */
.rb-cover:not(.is-locked) .rb-cover-box {
  outline: none;
  cursor: move;
}

/* Pointed at, or clicked on. Hover alone was not enough: a cover box is
   mostly text, so pointing at one usually means pointing at a field, and the
   contents frame had its list hanging below its own rectangle -- so the rows
   being clicked were not inside the box and nothing lit up. Tim: "I do like
   the corner pull but I don't like them visible all the time. I wanted them
   to where you highlighted it, but I highlighted that box numerous times
   yesterday and it would not show the pulls." */
.rb-cover:not(.is-locked) .rb-cover-box:hover,
.rb-cover:not(.is-locked) .rb-cover-box:focus-within,
.rb-cover:not(.is-locked) .rb-cover-box.is-active {
  outline: 1px dashed rgba(139, 94, 60, 0.5);
}

.rb-cover.is-locked .rb-cover-box {
  outline: none;
  cursor: default;
}

.rb-cover-box__resize {
  position: absolute;
  right: 0;
  bottom: 0;
  display: none;
  width: 14px;
  height: 14px;
  border-right: 2px solid var(--rb-copper);
  border-bottom: 2px solid var(--rb-copper);
  cursor: nwse-resize;
  /* Above whatever the box carries. The aerial's button bar was taken out of
     the flow so it could not change the picture's size, and absolute at
     bottom 0 it then lay over this corner: the pull was visible and could not
     be grabbed, because the bar was what the pointer found. */
  z-index: 4;
}

/* Highlighted, never merely hovered. Tim: the pulls "only show up when the
   box is highlighted, period." A pointer passing over a box is not a choice
   to work on it; clicking it, or reaching it by keyboard, is. */
.rb-cover:not(.is-locked) .rb-cover-box:focus-within .rb-cover-box__resize,
.rb-cover:not(.is-locked) .rb-cover-box.is-active .rb-cover-box__resize {
  display: block;
}

/* Fields are transparent inputs so the locked page reads as plain text. */
/* Report-owned text edits in place. These are rich-text regions, not inputs:
   an input carries one uniform style, so a word inside it cannot be bolded. */
.rb-cover [data-rb-rich] {
  display: block;
  width: 100%;
  margin: 0;
  border: 0;
  padding: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  box-sizing: border-box;
  white-space: pre-wrap;
  word-break: break-word;
}

.rb-cover [data-rb-rich]:focus {
  outline: 1px solid rgba(139, 94, 60, 0.55);
  outline-offset: 1px;
}

.rb-cover [data-rb-rich]:focus-visible { outline-offset: 1px; }

/* ---- Prepared For: label left, contact stacked right (TextBox 24) ---- */

.rb-cover-box--prepared {
  display: flex;
  align-items: flex-start;
  gap: 0;
}

.rb-cover__label {
  flex: 0 0 30%;
  margin: 0;
  color: var(--rb-sage);
  font-size: 1.768cqh;
  font-weight: 700;
  letter-spacing: 0.143em;
  white-space: nowrap;
}

.rb-cover__contact {
  flex: 1 1 auto;
  min-width: 0;
}

.rb-cover .rb-cover__name,
.rb-cover .rb-cover__email {
  color: var(--rb-sage);
  font-size: 2.02cqh;
  font-weight: 700;
  line-height: 1.32;
}

.rb-cover .rb-cover__phone {
  color: var(--rb-ink);
  font-size: 2.02cqh;
  font-weight: 700;
  line-height: 1.32;
}

/* ---- Identity: FLOOR LEVEL SURVEY / street / city (TextBox 28/30/33) ----
   Box top is 31.36% of the page. Street sits at 35.91% and the city line at
   46.10%, so the gaps below are the measured deltas, not taste. */

.rb-cover__product {
  margin: 0;
  color: var(--rb-copper);
  font-size: 2.02cqh;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: 0.25em;
}

.rb-cover .rb-cover__street {
  margin-top: 2.23cqh;
  color: var(--rb-ink);
  font-size: 7.576cqh;
  font-weight: 700;
  /* PowerPoint single-spaces on the font's own line height (~1.22 for
     Calibri), which puts leading above AND below the glyphs. line-height:1
     dropped all the slack below the street and inflated the gap to the city
     line even though both boxes were landing on the deck's coordinates. */
  line-height: 1.22;
  letter-spacing: -0.017em;
}

.rb-cover .rb-cover__city {
  /* Street box 35.91% + its 9.24cqh line box ends at 45.15%; the deck puts
     the city box at 46.10%, so the remaining gap is 0.95. */
  margin-top: 0.95cqh;
  color: var(--rb-gray);
  font-size: 4.04cqh;
  font-weight: 400;
  line-height: 1.22;
}

/* ---- Rule + survey date (Rectangle 35 at 57.45%, TextBox 37 at 60.18%) ---- */

.rb-cover__rule {
  width: 45.7%;
  height: 0.41cqh;
  margin: 0 0 2.32cqh;
  background: var(--rb-copper);
}

.rb-cover__date-row {
  display: flex;
  align-items: baseline;
  gap: 0;
}

.rb-cover__date-row .rb-cover__label { flex: 0 0 30%; }

.rb-cover .rb-cover__date-value {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--rb-gray);
  font-size: 1.768cqh;
  font-weight: 400;
  line-height: 1.4;
}

.rb-cover .rb-cover__corrected {
  margin-left: 30%;
  width: 70%;
  color: var(--rb-gray);
  font-size: 1.768cqh;
  font-weight: 400;
  line-height: 1.4;
}

/* ---- CONTENTS (Rectangle 40: no fill, 3 pt #C8C0B4 frame) ---- */

.rb-cover-box--contents { overflow: visible; }

/* As tall as what is in it. The frame used to be a fixed rectangle with the
   list clipped inside it, so a job with more figures than the rectangle held
   printed a contents that was missing its last pages. */
.rb-cover__contents {
  min-height: 100%;
  border: 0.379cqh solid var(--rb-frame);
  padding: 2.45cqh 1.6cqw 1.6cqh 2.35cqw;
  background: transparent;
  box-sizing: border-box;
  overflow: visible;
}

.rb-cover__contents-item:hover .rb-cover__contents-jump,
.rb-cover__contents-jump:focus-visible {
  opacity: 1;
}

.rb-cover__contents-title {
  margin: 0 0 2.73cqh;
  color: var(--rb-copper);
  font-size: calc(1.515cqh * var(--rb-contents-fit, 1));
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.25em;
}

.rb-cover__contents-list {
  display: flex;
  flex-direction: column;
  /* The deck's list box is 21.73% of page height over 7 lines = 3.10% each.
     13 pt at 1.25 leading is 2.05, so the gap carries the remaining 1.05. */
  gap: calc(1.05cqh * var(--rb-contents-fit, 1));
}

/* Two columns: "Figure N" is derived from slide order and is not editable,
   so it can never be typed into the title and double-prefix the line. */
.rb-cover__contents-item {
  /* The jump chevron hangs off this, out of the flow -- see
     .rb-cover__contents-jump. */
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 0;
  width: 100%;
  color: var(--rb-ink);
  font-size: calc(1.641cqh * var(--rb-contents-fit, 1));
  line-height: 1.25;
}

.rb-cover__contents-num {
  /* The deck tabs titles to 66.0% of page width and the list starts at
     61.47%, so the figure column is 4.53% of the page = 16% of the list.
     That is a MINIMUM, not a fixed width: if Calibri is unavailable the
     substitute font is wider, and a hard 16% would either butt the title
     against the number or clip the longest real title. Growing past the
     tab stop keeps both readable on whatever font the device has. */
  flex: 0 0 auto;
  min-width: 16%;
  padding-right: 1.2cqw;
  font-weight: 700;
  white-space: nowrap;
}

.rb-cover .rb-cover__contents-field {
  flex: 1 1 auto;
  min-width: 0;
  font-size: inherit;
  font-weight: 400;
}

/* The discussion line carries no figure number and spans both columns. */
.rb-cover__contents-item--discussion .rb-cover__contents-num { display: none; }

.rb-cover__contents-item--discussion input.rb-cover__contents-field {
  font-weight: 700;
}

/* The jump to a slide, not a decoration. DECISIONS.md: the contents never
   uses chevrons -- and a row of them down the contents is exactly what this
   looked like, because it was always showing. It appears on the line being
   pointed at, the way every other piece of chrome on a sheet now does. */
/* Out of the flow, because it is editor chrome and the printed page does not
   have it. In the flow it was 2.2cqh tall against a 1.6cqh line, so every
   contents row was taller on screen than on paper: the box measured 815px in
   the editor and 693px in the print deck, and the list then shrank to 0.776
   on screen and 0.810 on paper. What is being fitted has to be the same thing
   in both places or no arithmetic can make them agree. */
.rb-cover__contents-jump {
  opacity: 0;
  transition: opacity 120ms ease;
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 2.2cqh;
  height: 2.2cqh;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--rb-copper);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

/* Never on the finished page. */
.rb-cover.is-locked .rb-cover__contents-jump { display: none; }

/* The readings pill hangs from its CENTRE, not its left edge.
   Pinned by the left edge, "Main Level H 9.7 L 6.7 D 3.0" and "Garage H 9.0
   L 5.3 D 3.7" are different widths, so the same stored spot put them in
   visibly different places and the lock looked broken even when it was
   holding the spot faithfully. The spot it holds is the middle now, so two
   sheets line up whatever their level is called. Tim: "High-low delta
   [pill] should be pinned to the center."
   A report made before this shifts that pill left by half its width, once. */
[data-rb-floor-kind="pill"] {
  transform: translateX(-50%);
}

/* ---- Site overview ---- */

.rb-cover-box--overview {
  display: flex;
  flex-direction: column;
  gap: 0.6cqh;
  background: transparent;
}

/* The bar is a place for its buttons to sit, not a surface. Stretched across
   the foot of the box it swallowed every press along the bottom edge --
   including the resize pull in the corner. Only its own controls take the
   pointer. */
.rb-cover__overview-actions { pointer-events: none; }
.rb-cover__overview-actions > * { pointer-events: auto; }

/* Neither the placeholder nor the buttons may take space away from the
   picture. They sat in the same column as the image and were merely made
   invisible -- and something invisible still occupies its place -- so the
   aerial was shorter whenever that chrome was present and grew the moment
   Lock took it out of the flow. Tim: "look at the blue button and the
   picture size ... locking or unlocking the layout changes what this looks
   like." Out of the flow entirely; the picture is one size either way. */
.rb-cover__overview-empty,
.rb-cover__overview-actions {
  position: absolute;
  left: 0;
  right: 0;
}
.rb-cover__overview-empty { top: 0; bottom: 0; }
.rb-cover__overview-actions { bottom: 0; }

.rb-cover__overview-image {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0.13cqh solid #333;
}

.rb-cover__overview-empty {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed #b9aa98;
  color: #999;
  font-size: 1.5cqh;
}

.rb-cover.is-locked .rb-cover__overview-empty { display: none; }

/* The empty frame and the buttons under it are ours, not the report's, so
   they wait until the investigator points at that corner of the page. Tim,
   Oct 17: "if I don't drop in a picture I want all the other buttons to go
   away." Hidden rather than removed, so nothing jumps or resizes when they
   appear -- the photo keeps the same place on the page either way. */
.rb-cover:not(.is-locked) .rb-cover__overview-empty,
.rb-cover:not(.is-locked) .rb-cover__overview-actions {
  visibility: hidden;
}

.rb-cover:not(.is-locked) .rb-cover-box--overview:hover .rb-cover__overview-empty,
.rb-cover:not(.is-locked) .rb-cover-box--overview:hover .rb-cover__overview-actions,
.rb-cover:not(.is-locked) .rb-cover-box--overview:focus-within .rb-cover__overview-empty,
.rb-cover:not(.is-locked) .rb-cover-box--overview:focus-within .rb-cover__overview-actions {
  visibility: visible;
}

.rb-cover__overview-actions {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

.rb-cover.is-locked .rb-cover__overview-actions { display: none; }

.rb-cover__maps-link {
  color: var(--rb-copper);
  font-size: 1.35cqh;
  font-weight: 700;
}


/* Mitchell Pictures pages — 2×5 grid, Photo NN + editable caption */
.rb-pictures-page {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  color: #111;
}

/* The photographs get the page.
   They were briefly held to three quarters, because ten of them running edge
   to edge crowded the Sandia Geo logo in the corner -- Tim: "they're too big
   so it covers most of the page". The logo is off this page now, so there is
   nothing to crowd and nothing to hold them back: "I am happy maximizing the
   space on the page". */
/* The how-many-across buttons sit in one row on the rail. */
.rb-ws__row {
  display: flex;
  gap: 6px;
}

.rb-ws__row .rb-ws__btn {
  flex: 1;
  min-width: 0;
}

/* Five grids will not sit across the panel in one row -- squeezed to fit,
   each one clipped its own name. They wrap onto a second line instead. */
.rb-ws__row--wrap {
  flex-wrap: wrap;
}

.rb-ws__row--wrap .rb-ws__btn {
  flex: 1 1 28%;
  min-width: 3.6rem;
  width: auto;
}

/* The figure rail — a narrow column down the right of a figure page.
   Everything in it is reference matter: whose property this is, what the
   drawing is, when it was surveyed, the readings, and the mark. It must not
   pull the eye off the drawing.

   This block is the layout ChatGPT wrote to the specification, pasted in as
   written. It fixes two things I had wrong: the rail now sits inside the
   page border's stroke rather than painting over it, and the foot is a grid
   track of its own so the figure number and the mark are centred on one axis
   and can never be clipped by the sections above. */

/* Existing border ends at:
   right: 0.98cqw
   bottom: 0.75cqh

   Add its 0.19cqh stroke thickness to each inset.
   Keep this rail outside the border element, as its sibling. */
.rb-rail__rail {
  position: absolute;
  top: calc(1.52cqh + 0.19cqh);
  right: calc(0.98cqw + 0.19cqh);
  bottom: calc(0.75cqh + 0.19cqh);
  width: 12.5cqw;
  z-index: 3;

  display: grid;
  grid-template-rows: minmax(0cqh, 1fr) 13cqh;

  box-sizing: border-box;
  border-left: 0.09cqh solid #1a1a1a;
  background: #fff;
  color: #1a1a1a;

  font-family: Georgia, "Times New Roman", serif;
  font-size: 1.12cqh;
  font-weight: 400;
  line-height: 1.55cqh;
  text-align: left;
  /* Georgia defaults to oldstyle figures, which set the 1 at x-height: on a
     drawing sheet "FIGURE 1" then reads as a typo and the readings column
     looks uneven. Lining figures throughout. */
  font-variant-numeric: lining-nums;
}

.rb-rail__rail *,
.rb-rail__rail *::before,
.rb-rail__rail *::after {
  box-sizing: border-box;
}

.rb-rail__body {
  min-width: 0cqw;
  min-height: 0cqh;
  overflow: hidden;
  padding: 1.5cqh 1.05cqw 0cqh;
}

.rb-rail__compass {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35cqh;
  margin: 0cqh 0cqw 2.5cqh;
}

/* North is not always up, so the rose can be turned by dragging it. */
.rb-rail__compass {
  cursor: grab;
  touch-action: none;
}

.rb-rail__compass:active {
  cursor: grabbing;
}

/* Size only. Rotation lives on .rb-rail__rose-rot as an SVG transform — the
   same way Distress Survey turns #northWidgetRot — so Present / Print / PDF
   always lay the mark out. A CSS rotate here was dropped by Chrome's print. */
.rb-rail__rose {
  display: block;
  width: 5.8cqh;
  height: 5.8cqh;
  flex-shrink: 0;
  overflow: visible;
}

.rb-rail__client,
.rb-rail__address,
.rb-rail__label,
.rb-rail__title,
.rb-rail__date,
.rb-rail__note,
.rb-rail__level-name {
  margin: 0cqh 0cqw;
  min-width: 0cqw;
  max-width: 10.3cqw;
  overflow-wrap: anywhere;
}

.rb-rail__client {
  font-size: 1.48cqh;
  line-height: 1.85cqh;
  font-weight: 700;
  text-transform: uppercase;
}

.rb-rail__address {
  margin-top: 0.65cqh;
  font-size: 1.12cqh;
  line-height: 1.6cqh;
  font-style: normal;
}

.rb-rail__section {
  margin-top: 2cqh;
  padding-top: 1.65cqh;
  border-top: 0.07cqh solid #a7a7a7;
}

.rb-rail__label {
  margin-bottom: 0.8cqh;
  color: #666;
  font-size: 0.91cqh;
  line-height: 1.25cqh;
  letter-spacing: 0.085cqh;
  font-weight: 400;
  text-transform: uppercase;
}

.rb-rail__title {
  font-size: 1.7cqh;
  line-height: 2.2cqh;
  font-weight: 400;
}

.rb-rail__date {
  font-size: 1.2cqh;
  line-height: 1.65cqh;
}

.rb-rail__note {
  margin-top: 0.55cqh;
  color: #666;
  font-size: 1.02cqh;
  line-height: 1.5cqh;
}

/* The note the investigator writes into the rail. It is a writing field, so
   it shows where it is when the pointer is over it or the caret is in it,
   and it is invisible otherwise -- an empty box ruled on every figure would
   be chrome on a page whose whole point is not having any. */
.rb-rail__note--body {
  min-height: 2.4cqh;
  color: #333;
  font-size: 1.06cqh;
  line-height: 1.5cqh;
}

.rb-rail__note--body[contenteditable="true"]:hover {
  outline: 1px dashed rgba(139, 94, 60, 0.4);
  outline-offset: 2px;
}

.rb-rail__note--body[contenteditable="true"]:focus {
  outline: 1px solid rgba(139, 94, 60, 0.55);
  outline-offset: 2px;
}

.rb-rail__note--body:empty::before {
  content: "Note";
  color: #b9aa98;
}

.rb-rail__note--body:focus:empty::before { content: ""; }

@media print {
  /* Nothing of the field itself reaches the paper -- only what was written. */
  .rb-rail__note--body { min-height: 0; outline: none; }
  .rb-rail__note--body:empty { display: none; }
  .rb-rail__note--body:empty::before { content: ""; }
}

.rb-rail__level + .rb-rail__level {
  margin-top: 1.7cqh;
}

.rb-rail__level-name {
  margin-bottom: 0.5cqh;
  font-size: 1.15cqh;
  line-height: 1.6cqh;
  font-weight: 700;
}

.rb-rail__readings {
  display: grid;
  gap: 0.25cqh;
  margin: 0cqh 0cqw;
}

.rb-rail__reading {
  display: grid;
  grid-template-columns: minmax(0cqw, 1fr) 4.3cqw;
  column-gap: 0.35cqw;
  align-items: baseline;
}

.rb-rail__reading-label,
.rb-rail__reading-value {
  min-width: 0cqw;
  margin: 0cqh 0cqw;
  font-size: 1.08cqh;
  line-height: 1.5cqh;
  overflow-wrap: anywhere;
}

.rb-rail__reading-value {
  text-align: right;
  font-variant-numeric: lining-nums tabular-nums;
}

/* Separate from the clipped body: always retains its own space. */
.rb-rail__foot {
  min-width: 0cqw;
  min-height: 0cqh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 1.3cqh;
  padding: 1cqh 0.8cqw 1.5cqh;
  background: #fff;
  text-align: center;
}

.rb-rail__figure {
  margin: 0cqh 0cqw;
  font-size: 1.15cqh;
  line-height: 1.6cqh;
  letter-spacing: 0.17cqh;
  font-weight: 400;
}

/* Fixed image box; contain preserves the entire logo,
   regardless of its intrinsic aspect ratio. */
.rb-rail__logo {
  display: block;
  flex-shrink: 0;
  width: 10cqw;
  height: 4.5cqh;
  object-fit: contain;
  object-position: center;
}

@media print {
  .rb-rail__rail {
    print-color-adjust: exact;
    -webkit-print-color-adjust: exact;
  }
}

/* The drawing keeps clear of the rail. */
.rb-sheet__margin--railed {
  padding-right: calc(12.5cqw + 1.8cqh);
}

.rb-pictures-page__grid {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  margin: 0 auto;
  display: grid;
  /* How many across is the investigator's choice; the rows follow from how
     many pictures the page holds, so nothing can be left without a cell.
     Fewer across widens every cell, which is what makes the pictures bigger
     on a page that only carries a few. The 74% is the three-quarter rule
     above: however many rows there are, they share that, and the bottom of
     the page stays clear. */
  grid-template-columns: repeat(var(--rb-pics-cols, 5), minmax(0, 1fr));
  /* Rows share what is left AFTER the gaps, which is what a fraction does
     and what a percentage does not: `100% / rows` asked for the whole height
     and then the gaps were added on top, so every Pictures page stood a
     little taller than its own sheet. On screen the bottom was clipped; in
     the printed deck it was a page that could spill. */
  grid-template-rows: repeat(var(--rb-pics-rows, 2), minmax(0, 1fr));
  gap: 1.4% 1.8%;
  align-content: stretch;
}

/* One row sits at the top of the sheet and is as tall as it needs to be,
   rather than being stretched down the page with its pictures hanging off
   the bottom edge. */
.rb-pictures-page__grid--one-row {
  grid-template-rows: auto;
  align-content: start;
}

.rb-pictures-page__cell {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  min-width: 0;
  min-height: 0;
  margin: 0;
  /* A cell is its row and no taller. */
  overflow: hidden;
  /* The caption's size, held apart from the caption itself.

     The caption's own font shrinks to fit (fitCaptions), and the block it
     sits in must NOT shrink with it or the picture above would move every
     time a description got long -- which is the thing being fixed. So the
     block is measured from this, which never changes, and the type inside it
     is measured from the inline size fitCaptions sets.

     Tim, Oct 20: "If you clip the picture the exact same size every fucking
     time, the middle never changes." */
  --rb-cap-size: clamp(9px, 1.2cqb, 12px);
  --rb-cap-lines: 3;
}

/* The frame is a plate of a fixed shape, as wide as its column.
   It used to stretch to fill the row, which was invisible at five across and
   two rows because the picture nearly filled the cell anyway. Choose four
   across for four photographs and the row became the full height of the
   block, so each picture sat marooned in a tall grey slab. Giving the frame a
   portrait proportion ties its height to its width instead: fewer across
   means a wider column, a taller plate and a bigger picture, and every plate
   in a row is the same height so the labels line up. The row still caps it,
   so a page that runs to four rows shrinks the plates to fit rather than
   running off the paper. */
.rb-pictures-page__frame {
  /* The picture takes every bit of its cell that the label and the caption
     are not using. It used to be a plate of a fixed portrait shape, which
     kept the captions in a row starting on one line but letterboxed any
     photograph that was not 3:4 -- a landscape shot sat small in the middle
     of a tall white box. Tim: "we just need to maximise the space, too
     small of a picture doesn't do anything." */
  /* Takes the room the label and the caption are not using, which gives the
     picture inside it a real height to be measured against. The picture sits
     at the FOOT of it, so the caption is directly under the photograph and
     whatever is left over falls above -- and the pictures along a row line
     up on their bottom edge. */
  flex: 1 1 auto;
  width: 100%;
  height: auto;
  min-height: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  overflow: hidden;
  /* No tint behind the picture. The plate is a fixed portrait shape so that
     every caption in a row starts on the same line, and a photograph that
     does not fill it used to leave a tan band above and below. Tim: "there's
     a tan in the background for portrait pictures -- I don't want that to
     show." The space is still reserved; it is just paper now. */
  background: none;
}

.rb-pictures-page__image {
  display: block;
  /* Sized to the picture, not to the box: as large as the cell allows in
     whichever direction runs out first, and no larger. The element is then
     exactly the photograph, which is what makes the black rule hug it
     instead of standing off it on white. */
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  /* Tim, Oct 17: "we need a black border around all pictures." A rule round
     the photograph itself, not round the space it sits in, so a tall picture
     and a wide one are each framed to their own edge. */
  border: 0.12cqh solid #1a1a1a;
  box-sizing: border-box;
}

/* One line, always: "Photograph 12" wrapping in one cell and not in the next
   would move that cell's picture, which is the same fault as a long caption. */
.rb-pictures-page__label {
  flex: 0 0 auto;
  margin: 0.35em 0 0.1em;
  font-size: clamp(10px, 1.35cqb, 13px);
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The caption is a block of fixed height, three lines deep, in every cell on
   every sheet. The words fit it by coming down in size (fitCaptions), never
   by taking room from the photograph -- so the plate above is identical from
   cell to cell and the pictures along a row line up exactly.

   It used to be the other way about: the caption took the room its words
   needed and the plate gave way, which put one picture in a row higher than
   its neighbours. Tim, on his own deck: "Pictures look good except for the
   one in the upper right hand corner, which has apparently too much text to
   center the picture." */
.rb-pictures-page__caption {
  flex: 0 0 auto;
  width: 100%;
  height: calc(var(--rb-cap-size) * 1.25 * var(--rb-cap-lines));
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  resize: none;
  background: transparent;
  color: #222;
  font: inherit;
  font-size: var(--rb-cap-size);
  line-height: 1.25;
  overflow: hidden;
}

.rb-pictures-page__caption:focus {
  outline: 1px solid rgba(193, 74, 43, 0.45);
  outline-offset: 1px;
}

.rb-pictures-page__footer {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-end;
  margin-top: 0.5%;
}

.rb-penlog {
  /* This sheet is not drawn inside .rb-topo-page, so it never inherited the
     figure page's font -- it inherited the app shell's. Named here so the
     Picture Locations table and the distress descriptions in it are on the
     report's face and not the application's. */
  font-family: var(--rb-face);
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #fff;
}

.rb-penlog__missing {
  margin: 0;
  color: #222;
}

.rb-penlog__plan {
  position: absolute;
  overflow: visible;
  background: #fff;
  border: 0;
  box-sizing: border-box;
}

.rb-penlog__fit {
  position: absolute;
}

/* The plan and the schedule are placed pieces. Each shows its edge and its
   two pulls when it is pointed at and nothing before, the rule every other
   placed thing on a sheet follows. Tim: "Everything here needs to be
   movable. I should be able to move the floor plan if I want, and I want to
   be able to move the notes if I want." */
.rb-penlog__plan,
.rb-penlog__schedule {
  outline: none;
  outline-offset: 3px;
}

.rb-penlog__plan:hover,
.rb-penlog__schedule:hover {
  outline: 1px dashed rgba(139, 94, 60, 0.4);
}

.rb-penlog__move,
.rb-penlog__resize {
  position: absolute;
  display: none;
  z-index: 6;
  width: 14px;
  height: 14px;
}

.rb-penlog__move {
  left: -3px;
  top: -3px;
  border-left: 2px solid var(--rb-copper, #8B5E3C);
  border-top: 2px solid var(--rb-copper, #8B5E3C);
  cursor: move;
}

.rb-penlog__resize {
  right: -3px;
  bottom: -3px;
  border-right: 2px solid var(--rb-copper, #8B5E3C);
  border-bottom: 2px solid var(--rb-copper, #8B5E3C);
  cursor: nwse-resize;
}

[data-rb-penlog-box].is-picked > .rb-penlog__move,
[data-rb-penlog-box].is-picked > .rb-penlog__resize,
[data-rb-penlog-box]:focus-within > .rb-penlog__move,
[data-rb-penlog-box]:focus-within > .rb-penlog__resize {
  display: block;
}

.rb-sheet--thumb .rb-penlog__move,
.rb-sheet--thumb .rb-penlog__resize { display: none !important; }

@media print {
  .rb-penlog__move,
  .rb-penlog__resize { display: none !important; }
  .rb-penlog__plan,
  .rb-penlog__schedule { outline: none !important; }
}

.rb-penlog__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;
}

/* The contour layer lies on the plan, at the same extent, under the pins. */
.rb-penlog__image--contour {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.rb-penlog__missing {
  position: absolute;
  left: 8%;
  right: 8%;
  top: 42%;
  color: #5c574e;
  font-size: 12px;
  font-size: 1.5cqh;
  text-align: center;
}

/* Pin size comes from the PLAN, published by pen-log.js as --rb-pin-size, so a
   pin on a report page is the size Distress Survey's own pin-log PDF draws it:
   diameter 1.75% of the plan's long side. The literal cqh values are the
   fallback for the instant before the first layout pass, and the px lines
   before them are the fallback for a browser without container queries.
   The red is Distress's --accent; this was #9b2b21, a different red, which
   showed the moment a Picture Locations page sat near anything carrying the
   field app's ink. */
.rb-penlog__pin {
  position: absolute;
  z-index: 1;
  display: grid;
  place-items: center;
  /* Distress strokes its pin with a white ring, lineWidth R x 0.18 centred on
     the circle, so the coloured disc is 0.91 of the nominal diameter and the
     ring reaches R x 0.09 beyond it -- 0.045 of the DIAMETER, not 0.09 of it. Splitting it the same way here makes the two
     identical rather than merely the same nominal size -- a bare disc and a
     ringed one read differently against a busy plan even at matching numbers.
     --rb-pin-size is the NOMINAL diameter, as in Distress. */
  min-width: 16px;
  min-width: calc(var(--rb-pin-size, 2.15cqh) * 0.91);
  height: 16px;
  height: calc(var(--rb-pin-size, 2.15cqh) * 0.91);
  padding: 0 0.25cqh;
  border-radius: 999px;
  background: #c14a2b;
  box-shadow: 0 0 0 calc(var(--rb-pin-size, 2.15cqh) * 0.045) #fff;
  color: #fff;
  font-size: 10px;
  /* Distress sets the label at R x 1.05, i.e. 0.525 of the nominal diameter. */
  font-size: calc(var(--rb-pin-size, 2.15cqh) * 0.525);
  font-weight: 700;
  line-height: 1;
  transform: translate(-50%, -50%);
}

/* Draggable: several photographs at one spot arrive as separate pins on
   identical coordinates, and this is how they get pulled apart on the page. */
.rb-penlog__pin {
  cursor: grab;
  touch-action: none;
}
.rb-penlog__pin:active { cursor: grabbing; }

@media print {
  .rb-penlog__pin { cursor: default; }
}

.rb-penlog__pin.is-exterior {
  background: #6b7280;
}

/* Which pin is being worked on is not something the drawing says -- on the
   sheet, in the PDF, on the wall, or on the editing screen. Scoping it to
   print left it ringed in the editor, which is where Tim was looking: "pin 1
   is still highlighted. I told you I didn't want that." The class stays for
   the code that tracks selection; it just draws nothing. */
.rb-penlog__pin.is-selected {
  box-shadow: none;
}

.rb-penlog__schedule {
  position: absolute;
  display: flex;
  flex-direction: column;
  /* A short schedule sits in the middle of its column rather than hanging
     from the top of a page it does not fill. */
  justify-content: center;
  box-sizing: border-box;
  overflow: hidden;
  background: #fff;
}

/* Where the splitter measures: one sheet at 100 px to the inch, off-screen.
   A size container, because everything on this page is sized in cqh and has
   to resolve against a page of known dimensions -- measuring inside the live
   sheet made the split depend on the window width, so the same report broke
   15/11 on a laptop and 16/10 on a desktop. */
.rb-penlog-probe-host {
  position: fixed;
  left: -30000px;
  top: 0;
  container-type: size;
  overflow: hidden;
  visibility: hidden;
  pointer-events: none;
}

/* The copy it measures in starts at the top rather than centred: the rows are
   measured from the top of the box, and a centred grid taller than its box
   starts above it, which made every row look higher up the page than it
   would really be. */
.rb-penlog__schedule--probe {
  justify-content: flex-start;
  visibility: hidden;
  pointer-events: none;
}

.rb-penlog__grid {
  display: grid;
  /* Each row is as tall as its own text. No fixed row count, and no row
     without a photograph in it. */
  grid-auto-rows: min-content;
  width: 100%;
  border-top: 1px solid #222;
  border-left: 1px solid #222;
  box-sizing: border-box;
}

.rb-penlog__cell {
  display: flex;
  /* The photograph number and the pin sit in the middle of their field, as
     they always have. Only the note starts at the top -- it is the thing
     that makes the row tall, and text reads from the top down. */
  align-items: center;
  justify-content: center;
  min-width: 0;
  /* A row is as tall as its text, but never shorter than the row this page
     has always used: 0.3 in of an 11 in sheet. */
  min-height: 2.73cqh;
  /* The old row was a fixed height with the text centred inside it, so it
     needed no padding of its own. A row that hugs its text does, or the
     writing touches the rules above and below it. */
  padding: 0.3cqh 0.35cqh;
  border-right: 1px solid #222;
  border-bottom: 1px solid #c8c8c8;
  overflow: hidden;
  color: #222;
  font-size: 11px;
  font-size: 1.28cqh;
  line-height: 1.15;
}

.rb-penlog__cell.is-note {
  position: relative;
  display: block;
}

/* The room the pin is in, run in at the head of its note: "Kitchen -
   stair-step crack, north wall." It sits out of the flow and the note's
   first line is indented past it, so the note reads on from the room and
   still wraps back to the left margin. Setting the two side by side instead
   stepped every following line in by the length of the room name, which
   left the column ragged down the page. */
.rb-penlog__room {
  position: absolute;
  top: 0.3cqh;
  left: 0.35cqh;
  font-weight: 700;
  white-space: nowrap;
}

.rb-penlog__room::after {
  content: " \2014";
  font-weight: 400;
}

.rb-penlog__cell--head {
  /* 0.32 in, the header height this page has always had. */
  min-height: 2.91cqh;
  background: #ebe6de;
  border-bottom-color: #222;
  font-weight: 700;
}

.rb-penlog__cell.is-left {
  justify-content: flex-start;
}

@media print {
  /* Which pin is being worked on is not something the figure says. The row
     highlight is gone entirely; the ring on the marker stays on screen, where
     it is the only sign of which pin a drag will move, and off the paper.
     This block sits below the rule it overrides: equal specificity, so source
     order decides. */
  .rb-penlog__pin.is-selected { box-shadow: none; }
}

/* The printed deck and the flip chart are both rendered on screen, where
   @media print never fires. Which pin is being worked on is screen chrome:
   it belongs on the editing sheet and nowhere else. */
.rb-print .rb-penlog__pin.is-selected { box-shadow: none; }

.rb-penlog__photo {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: 600;
  line-height: 1;
  text-decoration: underline;
  text-underline-offset: 0.12em;
  cursor: pointer;
}

.rb-penlog__pinnum {
  display: inline-grid;
  place-items: center;
  width: 1.45em;
  height: 1.45em;
  border: 1px solid #333;
  border-radius: 50%;
  font-weight: 700;
}

.rb-penlog__note {
  display: block;
  width: 100%;
  /* Height is set from the text by autosizeNote(); this is only the floor it
     starts from before the first measurement. */
  height: auto;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  overflow: hidden;
  resize: none;
  background: transparent;
  color: inherit;
  font: inherit;
  line-height: 1.15;
}

/* Print / Present: room + note as ordinary flowing text. Absolute room +
   textarea first-line indent is the editor layout; Chrome's print of that
   combination painted overlapping / clipped characters on the Janis PDF. */
.rb-penlog__room--inline {
  position: static;
  top: auto;
  left: auto;
  font-weight: 700;
  white-space: normal;
}

.rb-penlog__room--inline::after { content: none; }

.rb-penlog__note--print {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.rb-penlog-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--line, #d7d2c8);
}

.rb-penlog-panel[hidden] {
  display: none;
}

.rb-panel__status {
  margin: 0;
  color: var(--navy, #143044);
  font-size: 12px;
  font-weight: 700;
  min-height: 1em;
}

.rb-panel__status:empty {
  display: none;
}

.rb-panel__label {
  color: var(--ink, #222);
  font-size: 12px;
  font-weight: 700;
}

.rb-penlog-pinsize {
  display: flex;
  align-items: center;
  gap: 10px;
}
.rb-penlog-pinsize input[type="range"] {
  flex: 1 1 auto;
  min-width: 0;
  accent-color: var(--accent, #c14a2b);
}
.rb-penlog-pinsize__val {
  flex: 0 0 auto;
  min-width: 3.2em;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink, #222);
  font-variant-numeric: tabular-nums;
}

.rb-panel__note,
.rb-panel__note.rb-panel__note {
  width: 100%;
  min-height: 72px;
  padding: 8px;
  border: 1px solid var(--line-strong, #b8b2a6);
  border-radius: 8px;
  background: #fff;
  color: var(--ink, #222);
  font: inherit;
  font-size: 16px;
  line-height: 1.35;
  resize: vertical;
}

.rb-panel__subhead {
  margin: 8px 0 0;
  font-size: 13px;
}

.rb-photo-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.rb-photo {
  margin: 0;
  padding: 0 0 8px;
  border-bottom: 1px solid var(--line, #d7d2c8);
}

.rb-photo.is-current {
  background: #f7f1e4;
}

.rb-photo figcaption,
.rb-photo p {
  margin: 0 0 4px;
  color: var(--ink, #222);
  font-size: 12px;
  font-weight: 700;
}

.rb-photo img {
  display: block;
  width: 100%;
  max-height: 180px;
  object-fit: contain;
  background: #f6f3ec;
}

/* Floor Survey Import → place → Lock */
.rb-floor-toolbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 0.4%;
  min-height: 1.8em;
}

.rb-floor-toolbar__hint {
  font-size: clamp(10px, 1.3cqb, 12px);
  color: #555;
}

.rb-floor-stage {
  position: relative;
  overflow: hidden;
  /* Its own stacking context, so a piece sent behind the others (a negative
     z) still sits above the stage and can be picked up again. */
  isolation: isolate;
}

.rb-floor-empty {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  color: #666;
  font-size: clamp(12px, 1.7cqb, 15px);
  text-align: center;
  padding: 1em;
  border: 1px dashed #cbbba8;
  background: #fbfaf7;
}

.rb-floor-box {
  position: absolute;
  z-index: 2;
  box-sizing: border-box;
  touch-action: none;
}

.rb-floor-box--topo {
  z-index: 1;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
  border: 1px solid transparent;
}

.rb-floor-box--topo .rb-topo-page__drawing {
  width: 100%;
  height: 100%;
}

.rb-floor-box--topo .rb-topo-page__image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* The colour scale and a boundary's readings, as one piece on the page.
 *
 * They used to be painted into the plan's own picture, so panning the plan
 * carried them along. Tim: "putting the contour legend in the pill, one
 * place, and being able to move the floor plan with contours separately."
 * One box: scale on the left, the boundary's name and its H / L / delta
 * beside it, dragged like any other box on the sheet. */
/* The colour scale and the readings are as wide as what is written in them,
   wherever they are put.
 *
 * They are absolutely positioned inside the sheet, and `width: auto` means an
 * absolutely positioned box is squeezed by its container's edge: dragged to
 * the right-hand margin the readings pill went from 138px to 84px and the
 * line wrapped onto itself. Tim: "The pill actually compresses if you move it
 * too far to the right." max-content takes the edge out of it -- the box is
 * the size of its own contents and nothing else. */
.rb-floor-box--chrome {
  display: block;
  width: max-content;
  max-width: none;
  height: auto;
  z-index: 4;
}



/* The piece shows its handles and its dashed edge when it is pointed at,
   not before. Tim: "the corner chevrons don't need to be there unless it's
   selected." A finished figure carries no chrome of ours. */
.rb-floor-box.rb-floor-box--chrome:not(.is-locked) {
  outline: none;
  background: none;
}

.rb-floor-box.rb-floor-box--chrome:not(.is-locked):hover,
.rb-floor-box.rb-floor-box--chrome:not(.is-locked):focus-within {
  outline: 1px dashed rgba(139, 94, 60, 0.45);
  outline-offset: 2px;
}

/* The colour scale and the readings carry no corner pulls at all: each is
   sized from the control that has always sized it, and two controls for one
   size is one too many. */
.rb-floor-box--chrome .rb-floor-box__resize { display: none !important; }

/* The site overview on a Floor Survey page.
 *
 * The cover's aerial view of the property, carried onto the figure pages by
 * itself and placed where the shipped decks put it: lower left, clear of the
 * rail. It is moved and sized like any other box, and the x takes it off this
 * page alone. Settled Oct 10, 2026; Tim, Oct 16: "able to delete on FS pages
 * if too cluttered, and moveable by user." */
.rb-floor-box--overview {
  z-index: 3;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 0 0 1px rgba(23, 19, 14, 0.22);
}

.rb-floor-overview__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  user-select: none;
}

/* Its corner pulls appear when it is pointed at, not before. Tim: "the
   corner chevrons on the corners of it don't need to be there unless it's
   selected." Four brackets standing on a finished figure are chrome on the
   drawing, which is the one thing the rail rebuild was for. */
.rb-floor-box--overview:focus-within .rb-floor-box__resize,
.rb-floor-box--overview.is-picked .rb-floor-box__resize {
  display: block;
}

.rb-floor-overview__remove {
  position: absolute;
  top: 2%;
  right: 2%;
  z-index: 7;
  width: 4cqh;
  height: 4cqh;
  min-width: 14px;
  min-height: 14px;
  padding: 0;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(23, 19, 14, 0.62);
  color: #fff;
  font-size: 2.6cqh;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 120ms ease;
}

.rb-floor-box--overview:hover .rb-floor-overview__remove,
.rb-floor-overview__remove:focus-visible {
  opacity: 1;
}

@media print {
  .rb-floor-overview__remove { display: none; }
  .rb-floor-box--overview { box-shadow: none; }
}

.rb-floor-box:not(.is-locked) {
  cursor: move;
  background: rgba(255, 255, 255, 0.02);
}

/* The dashed edge is for the box being pointed at, as on the cover. It was
   the unlocked look when boxes had a lock; with the lock gone it stood on
   every drawing at rest. */
.rb-floor-box:not(.is-locked):hover,
.rb-floor-box:not(.is-locked):focus-within {
  outline: 1px dashed rgba(30, 64, 110, 0.35);
}

.rb-floor-box:not(.is-locked):focus {
  outline: 2px solid rgba(193, 74, 43, 0.55);
}

/* The frame's corner pulls.
 *
 * Two lines meeting at a right angle, like a crop mark, rather than a filled
 * tile. Tim: "I don't like the circles on the corners, I like the corner 90
 * degree pulls better for this, and only present when the floorplan surface
 * is selected." A filled tile sits ON the drawing and reads as part of it; a
 * bracket frames the corner it belongs to and leaves the drawing visible
 * underneath.
 *
 * The box stays 16px so it is still easy to hit on a touch screen -- only
 * two of its four borders are drawn. */
.rb-floor-box__resize {
  position: absolute;
  /* Big enough to find and hit. 12px was a speck on a full-page frame, and
     16px was still hard to see on the aerial, which is a small box over a
     busy photograph. Tim: "the corner poles ... need to be more prevalent."
     The bracket is drawn thicker and carries a solid tip, so it reads as a
     grab point rather than a hairline. */
  width: 20px;
  height: 20px;
  border: 0 solid #1e406e;
  background: transparent;
  /* A white companion line under the dark one, so the bracket reads against
     a dark contour as well as against white paper. */
  filter: drop-shadow(0 0 1px #fff) drop-shadow(0 0 1px #fff);
  border-width: 0;
  border-color: #1e406e;
  /* Above the drawing it sits on. */
  z-index: 6;
}

/* Only while the floorplan surface is selected -- the same rule the plan's
   own grips already follow. A handle standing on an unselected drawing is
   chrome on a figure. */
/* The one box being worked on. It used to be the whole sheet: clicking the
   drawing lit the pulls on the plan AND on the aerial view at once, which is
   chrome standing on a figure nobody is touching. */
.rb-floor-box__resize { display: none; }
.rb-floor-box.is-picked > .rb-floor-box__resize,
.rb-floor-box:focus-within > .rb-floor-box__resize { display: block; }

/* A picked box says so, the way a picked cover box does -- except the plan
   itself, which IS the sheet on an imported slide, and the colour scale and
   readings, which are sized from the rail and have nothing to pull. */
.rb-floor-box.is-picked:not(.rb-floor-box--topo):not(.rb-floor-box--chrome) {
  outline: 1px dashed rgba(30, 64, 110, 0.55);
  outline-offset: 2px;
}

.rb-floor-box__resize--nw {
  left: -10px; top: -10px; cursor: nwse-resize;
  border-top-width: 3px; border-left-width: 3px;
}

.rb-floor-box__resize--ne {
  right: -10px; top: -10px; cursor: nesw-resize;
  border-top-width: 3px; border-right-width: 3px;
}

.rb-floor-box__resize--sw {
  left: -10px; bottom: -10px; cursor: nesw-resize;
  border-bottom-width: 3px; border-left-width: 3px;
}

.rb-floor-box__resize--se {
  right: -10px; bottom: -10px; cursor: nwse-resize;
  border-bottom-width: 3px; border-right-width: 3px;
}

.rb-topo-page--chrome-only .rb-topo-page__body {
  min-height: 55%;
}

/* ------------------------------------------------------------------ *
 * Rich text blocks (shared by every report-owned field)
 * ------------------------------------------------------------------ */

.rb-rt__p { margin: 0; }

.rb-rt__list {
  margin: 0;
  padding-left: 1.4em;
  list-style: disc;
}

.rb-rt__list--number { list-style: decimal; }

.rb-rt__p--bullet,
.rb-rt__p--number { display: list-item; }

/* ------------------------------------------------------------------ *
 * Formatting toolbar — always across the top, every page, the way the
 * PowerPoint Home ribbon is. Pages left, canvas centre, Toolbox right.
 * ------------------------------------------------------------------ */

/* The formatting bar takes whatever room is left beside Print and Export,
   rather than asking for its content width and pushing them onto a second
   row. With a basis of auto the toolbar was two rows tall while the hint was
   showing and one row once it went, so the whole sheet jumped nineteen
   pixels the moment a field took focus. */
.rb-toolbar__format {
  flex: 1 1 0;
  min-width: 0;
}

.rb-format {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 7px;
  min-width: 0;
}

.rb-format__group {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding-right: 6px;
  border-right: 1px solid var(--line);
}

.rb-format__group:last-of-type { border-right: 0; }

.rb-format__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Ribbon-sized. 28px was tight for a touch target and cramped the icons;
     there is room across the top for the real thing. 30px with the gutters
     pulled in keeps the whole bar on one row down to a 1600px screen, which
     three more controls had cost it -- a second row of ours comes straight
     off the height of the sheet. */
  min-width: 30px;
  height: 32px;
  padding: 0 7px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--ink);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}

.rb-format__btn--icon { padding: 0 6px; gap: 2px; }

/* On a smaller desktop the bar pulls itself in rather than taking a second
   row: a row of ours comes straight off the height of the sheet, and the
   sheet is the thing being worked on. Full ribbon sizing comes back as soon
   as there is room for it. */
@media (max-width: 1800px) {
  .rb-format { gap: 2px 5px; }
  .rb-format__group { padding-right: 4px; }
  .rb-format__btn { min-width: 28px; padding: 0 5px; }
  .rb-format__btn--icon { padding: 0 4px; }
}

.rb-format__btn svg {
  display: block;
  /* The icons are drawn in currentColor at one weight, so they pick up the
     button's own state -- hover, pressed, and the lit state of a mark that is
     already on -- without a second set of artwork. */
  flex: 0 0 auto;
}

.rb-format__btn--icon .rb-format__caret { font-size: 9px; opacity: 0.7; }


.rb-format__btn:hover { background: rgba(8, 32, 54, 0.07); }

.rb-format__btn.is-on {
  border-color: var(--line);
  background: var(--accent-soft, #f3d8ce);
  color: var(--accent, #c14a2b);
}

.rb-format__btn--b { font-weight: 800; }
.rb-format__btn--i { font-style: italic; }
.rb-format__btn--u { text-decoration: underline; }

/* The alignment glyphs share one character; skew them so the group reads
   as left / centre / right at a glance rather than three identical marks. */
.rb-format__btn[data-rb-fmt="center"] { justify-content: center; }
.rb-format__btn[data-rb-fmt="right"] { justify-content: flex-end; }
.rb-format__btn[data-rb-fmt="left"] { justify-content: flex-start; }

.rb-format__menu { position: relative; display: inline-flex; }

.rb-format__menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  height: 28px;
  padding: 0 6px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel, #fff);
  color: var(--ink);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
}

.rb-format__menu-btn:hover { background: rgba(8, 32, 54, 0.05); }

.rb-format__caret { color: var(--muted, #6b6b6b); font-size: 9px; }

.rb-format__list {
  position: absolute;
  z-index: 40;
  top: calc(100% + 2px);
  left: 0;
  display: flex;
  flex-direction: column;
  min-width: 100%;
  max-height: 48vh;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel, #fff);
  box-shadow: 0 10px 28px rgba(8, 32, 54, 0.18);
  overflow: auto;
}

.rb-format__list[hidden] { display: none; }

.rb-format__item {
  padding: 6px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--ink);
  font-size: 12px;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.rb-format__item:hover { background: rgba(8, 32, 54, 0.08); }

.rb-format__item[aria-current="true"] {
  background: var(--accent-soft, #f3d8ce);
  color: var(--accent, #c14a2b);
  font-weight: 700;
}

/* The hint takes whatever room is left and never forces the bar onto a
   second row -- and it is hidden rather than removed when a field has focus.
   Removing it collapsed that second row, so the bar got shorter and the whole
   sheet jumped up the moment you started typing. */
.rb-format__hint {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--muted, #6b6b6b);
  font-size: 12px;
}

.rb-format.is-ready .rb-format__hint { visibility: hidden; }

/* Until a field has focus the text commands have nothing to act on. The
   drawing tools, the weights, the colours and the insert buttons always do --
   they act on the sheet, not on a selection -- so they are exempt. */
.rb-format:not(.is-ready)
  .rb-format__group:not(.rb-format__group--draw):not(.rb-format__group--ink)
  .rb-format__btn,
.rb-format:not(.is-ready) .rb-format__menu-btn {
  opacity: 0.45;
  pointer-events: none;
}

/* An armed drawing tool turns the annotation layer into a full-sheet shield.
   There are three pointerdown listeners on the sheet plus React's own inside
   the Floor Survey canvas; rather than add a fourth and fight them for the
   event, the layer simply sits above everything and receives it first. z-index
   9 clears the brand (7), its lock button (8), the floor resize grips (6) and
   the page frame (4). Disarmed, the layer is pointer-events:none and is not in
   the event path at all, so nothing else changes. */
.rb-sheet--inking .rb-ov-layer {
  pointer-events: auto;
  z-index: 9;
  cursor: crosshair;
  touch-action: none;
}
/* and existing annotations do not swallow a stroke drawn across them, nor take
   focus into a contenteditable mid-gesture */
.rb-sheet--inking .rb-ov { pointer-events: none; }

/* The eraser needs to hit things, so ink and boxes become targets -- but not
   the text field, the resize grip or the delete pip inside a box. */
.rb-sheet--erasing .rb-ov-layer__ink { pointer-events: auto; }
.rb-sheet--erasing .rb-ov { pointer-events: auto; cursor: pointer; }
.rb-sheet--erasing .rb-ov__text,
.rb-sheet--erasing .rb-ov__resize,
.rb-sheet--erasing .rb-ov__remove { pointer-events: none; }

/* The armed tool and the chosen weight, shown the way Distress shows them. */
.rb-format__btn[data-rb-insert].is-on,
.rb-format__btn[data-rb-tool].is-on,
.rb-format__btn[data-rb-thick].is-on {
  border-color: var(--line);
  background: var(--accent, #c14a2b);
  color: #fff;
}

@media (max-width: 720px) {
  .rb-format__group {
    padding-right: 6px;
    gap: 1px;
  }
  .rb-format__btn { min-width: 26px; }
  .rb-format__menu-btn { font-size: 11px; }
}

/* ------------------------------------------------------------------ *
 * Print / PDF
 *
 * The deliverable is the PDF, and it comes out of the browser's own print
 * path -- so what prints is the same DOM the investigator just approved on
 * screen, not a second renderer that can drift away from it.
 *
 * The sheet is a size container and its type is sized in cqh, so setting the
 * printed sheet to exactly 11 x 17 makes every measurement resolve against
 * the real page. That is why the clamp() had to come off the cover type: a
 * clamped size stops growing and would print smaller than it previews.
 * ------------------------------------------------------------------ */

/* Laid out but off-screen, rather than display:none.
   The deck is built and measured by JS before printing -- a Picture Locations
   page sizes its plan box from the frame's clientWidth -- and display:none
   makes every measurement zero, so the plan collapsed to 0 x 0 and its pins
   with it. Nothing in the deck can be measured while it does not participate
   in layout, and no amount of re-running the layout changes that.
   Pushed far off-screen instead: invisible, inert, and measurable. */
.rb-print {
  /* The printed deck is built and measured at THE SIZE THE EDITOR'S SHEET IS
     RIGHT NOW, and each finished sheet is then scaled up to the paper inside
     its own page box. Measuring at paper size is what made the PDF disagree
     with the editor: text re-wrapped, captions shrank by a different amount,
     photographs were measured against a different box and pin size came off
     a different plan rect. Nothing is fitted for paper now -- the paper
     shows the sheet the editor settled, enlarged.
     The three numbers are written on the deck from script, because the
     editing sheet is sized to whatever the stage gives it. 11x17 landscape
     is 1632 x 1056 CSS pixels at 96dpi, so the scale is 1632 / sheet width
     and the sheet's own 17:11 shape makes the height come out exact. */
  --rb-print-sheet-w: 1632px;
  --rb-print-sheet-h: 1056px;
  --rb-print-scale-x: 2.4;
  --rb-print-scale-y: 2.4;
  position: fixed;
  left: -20000px;
  top: 0;
  width: var(--rb-print-sheet-w);
  pointer-events: none;
}

/* One sheet of paper, holding one editor-sized sheet. Off-screen, where the
   deck is measured, it is the sheet's own size; on paper it becomes the page
   and the sheet inside it fills it. */
.rb-print__page {
  position: relative;
  width: var(--rb-print-sheet-w);
  height: var(--rb-print-sheet-h);
}

/* And the sheet inside it is that size WHILE IT IS BEING MEASURED, not only
   once the paper rules come in. .rb-sheet's own 680px would otherwise be the
   size every fit on the deck measured against -- a different size from the
   editing sheet, which is the whole thing this is here to stop. */
.rb-print .rb-sheet {
  width: var(--rb-print-sheet-w);
  height: var(--rb-print-sheet-h);
  max-width: none;
}

/* Editor chrome is never on a sheet the investigator is SHOWING somebody.
 *
 * Every rule that took it off the paper lived inside @media print, and the
 * flip chart is that same deck on a SCREEN -- where print rules never fire.
 * So Presentation carried the lot: the dashed outline round a text box, the
 * corner pulls, the x on the aerial, the Paste overview button, the plan's
 * own grips. Tim, looking at a preview sheet: "Look at the small white
 * layout. That's our text box. I don't want it visible", and on the next
 * sheet, "the white line exists in these photos too."
 *
 * Scoped to the deck rather than to the medium, so one rule serves the
 * printer and the flip chart and the editing sheet keeps its chrome. */
.rb-print [data-plan-resize],
.rb-print .rb-penlog__move,
.rb-print .rb-penlog__resize,
.rb-print .rb-floor-overview__remove,
.rb-print .rb-cover-box__move,
.rb-print .rb-cover-box__resize,
.rb-print .rb-floor-box__resize,
.rb-print .rb-floor-toolbar,
.rb-print .rb-cover__contents-jump,
.rb-print .rb-cover__overview-actions,
.rb-print .rb-cover__overview-empty,
.rb-print .rb-floor-empty,
.rb-print .rb-brand__resize,
.rb-print .rb-discussion__move,
.rb-print .rb-discussion__resize,
.rb-print .rb-discussion__overflow,
.rb-print .rb-ov__resize,
.rb-print .rb-ov__remove,
.rb-print .rb-ov__hint,
.rb-print .rb-stackmenu {
  display: none !important;
}

/* And the outlines those boxes carry, which are a placement aid and not
   part of the drawing. */
.rb-print .rb-cover-box,
.rb-print .rb-floor-box,
.rb-print .rb-discussion__box,
.rb-print [data-rb-rich] {
  outline: none !important;
}

.rb-print .rb-floor-box.is-active::before,
.rb-print .rb-floor-box.is-active::after { content: none; }

/* Presentation: the printed deck, brought on screen one sheet at a time.
   It is deliberately the same deck the printer is given -- composed contour
   maps and all -- so what is flipped through is what comes out of the PDF.
   Tim: "that allows me to see the report before I PDF it ... there is my
   flip chart that I've been looking for." */
body.is-presenting { overflow: hidden; }

.rb-print--present {
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  width: 100vw;
  height: 100vh;
  padding: 0;
  background: #0b1b27;
  pointer-events: auto;
  overflow: hidden;
  z-index: 9000;
}

.rb-print--present .rb-sheet { display: none; }

/* The page boxes stand aside in the flip chart: the sheet being shown is
   placed against the full-screen deck itself. */
.rb-print--present .rb-print__page { display: contents; }

/* Placed and scaled from script, from the top-left corner. Centring a sheet
   that is larger than the window cannot be left to the layout: inside a
   clipping box the browser pins an oversized centred item to the start, and
   the paper ran off the bottom-right corner. */
.rb-print--present .rb-sheet.is-present-current {
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  /* The editing sheet's own size, scaled to the window from script. The flip
     chart shows the same geometry the editor does, which is the whole point
     of it being the preview -- and the same geometry the paper gets.
     max-width is lifted because .rb-sheet caps itself at 100%, which here is
     the window, and that squashed the sheet to the window's shape. */
  width: var(--rb-print-sheet-w);
  height: var(--rb-print-sheet-h);
  max-width: none;
  min-width: 0;
  flex: none;
  margin: 0;
  background: #fff;
  transform-origin: top left;
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.55);
}

.rb-present-bar {
  position: fixed;
  left: 50%;
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px;
  border-radius: 999px;
  background: rgba(10, 26, 38, 0.82);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  z-index: 9001;
  opacity: 0.25;
  transition: opacity 140ms ease;
}

.rb-present-bar:hover,
.rb-present-bar:focus-within { opacity: 1; }

.rb-present-bar button {
  min-width: 38px;
  height: 34px;
  padding: 0 12px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}

.rb-present-bar button:hover:not(:disabled) { background: rgba(255, 255, 255, 0.24); }
.rb-present-bar button:disabled { opacity: 0.35; cursor: default; }

.rb-present-bar__count {
  min-width: 74px;
  padding: 0 8px;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .rb-present-bar { transition: none; }
}

@media print {
  .rb-present-bar { display: none !important; }

  /* Printing from the flip chart prints the whole deck, not the one sheet
     being shown. It is the same deck either way -- the presentation is the
     printed deck -- so this only undoes the full-screen framing and lets
     every sheet back out onto the paper. */
  .rb-print--present {
    position: static;
    left: auto;
    top: auto;
    right: auto;
    bottom: auto;
    width: auto;
    height: auto;
    overflow: visible;
    background: #fff;
  }

  .rb-print--present .rb-print__page { display: block; }

  .rb-print--present .rb-sheet,
  .rb-print--present .rb-sheet.is-present-current {
    display: block;
    position: relative;
    left: auto;
    top: auto;
    /* Back to the paper scale. The flip chart's own fit-to-window transform
       is cleared from script before printing, and this is what prints. */
    transform: scale(var(--rb-print-scale-x), var(--rb-print-scale-y));
    transform-origin: top left;
    box-shadow: none;
  }
}

@media print {
  .rb-print {
    position: static;
    left: auto;
    width: auto;
  }

  /* 11x17 paper, landscape: 17 inches across the page. */
  @page {
    size: 17in 11in;
    margin: 0;
  }

  html, body {
    width: 17in;
    margin: 0;
    padding: 0;
    background: #fff;
  }

  body.is-printing > *:not(.rb-print) { display: none !important; }

  body.is-printing .rb-print { display: block; }

  /* The page box IS the sheet of paper, and it is what paginates. A scaled
     sheet reserves only its unscaled space in flow, so the page break can
     never be left to the sheet itself. */
  .rb-print__page {
    width: 17in;
    height: 11in;
    overflow: hidden;
    break-after: page;
    page-break-after: always;
    break-inside: avoid;
    page-break-inside: avoid;
  }

  .rb-print__page:last-child {
    break-after: auto;
    page-break-after: auto;
  }

  /* The finished editor sheet, enlarged to fill the paper. Everything in it
     was laid out, wrapped and fitted at the editing sheet's own size, so the
     paper shows what the editor showed. */
  .rb-print .rb-sheet {
    display: block;
    width: var(--rb-print-sheet-w);
    height: var(--rb-print-sheet-h);
    max-width: none;
    margin: 0;
    border: 0;
    box-shadow: none;
    overflow: hidden;
    transform: scale(var(--rb-print-scale-x), var(--rb-print-scale-y));
    transform-origin: top left;
  }

  /* Editor chrome never prints, whether or not the layout happens to be
     locked. A dashed placement outline on a deliverable is a defect. */
  .rb-floor-toolbar,
  .rb-cover__contents-jump,
  .rb-cover__overview-actions,
  .rb-cover__overview-empty,
  .rb-cover-box__resize,
  .rb-floor-box__resize,
  .rb-floor-empty {
    display: none !important;
  }

  .rb-cover-box,
  .rb-floor-box,
  .rb-cover [data-rb-rich] {
    outline: none !important;
  }

  /* Colour is the report: contour fills, the copper rule, the sage labels. */
  * {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

/* A cover box is mostly text, and text is now editable in place, so the box
   needs its own grab target. Mirrors the resize corner. */
.rb-cover-box__move {
  position: absolute;
  left: 0;
  top: 0;
  display: none;
  width: 14px;
  height: 14px;
  border-left: 2px solid var(--rb-copper);
  border-top: 2px solid var(--rb-copper);
  cursor: move;
}

/* The move corner follows the resize pull exactly: one rule for both, so a
   box either is being worked on or is not. It used to come out on hover,
   which left the two corners of one box obeying different rules. */
.rb-cover:not(.is-locked) .rb-cover-box:focus-within .rb-cover-box__move,
.rb-cover:not(.is-locked) .rb-cover-box.is-active .rb-cover-box__move {
  display: block;
}

.rb-cover.is-locked .rb-cover-box__move { display: none; }

@media print {
  .rb-cover-box__move { display: none !important; }
}

/* ------------------------------------------------------------------ *
 * Discussion page — two text boxes, measured from the shipped decks.
 *
 * All four agree: columns at 1.96% and 51.87%, both 3.03% down and 44.7%
 * wide, 12 pt body, brand mark at 3.59% / 93.49%. Only the column height
 * differs between jobs, which is just the box growing to fit the writing.
 *
 * The columns carry NO border. The only rule on this page is the outer page
 * frame; what looks like a box outline in PowerPoint is its selection chrome.
 * ------------------------------------------------------------------ */

.rb-sheet__margin--discussion {
  overflow: visible;
}

.rb-discussion {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  height: 100%;
  background: #fff;
  color: #1a1a1a;
  font-family: var(--rb-face);
}

/* The writing area as a placed box: where it sits and how big it is belong
   to the investigator, and the white space around it is his. Tim: "if you
   let me adjust the size of the box then I can use the white space that I
   want." It starts where the shipped decks put it. */
.rb-discussion__box {
  position: absolute;
  z-index: 1;
  box-sizing: border-box;
  column-gap: inherit;
}

/* Its edge and its two pulls appear when it is pointed at, not before --
   the rule every other piece on a sheet now follows. */
.rb-discussion:not(.is-locked) .rb-discussion__box:hover,
.rb-discussion:not(.is-locked) .rb-discussion__box:focus-within {
  outline: 1px dashed rgba(139, 94, 60, 0.4);
  outline-offset: 3px;
}

.rb-discussion__move,
.rb-discussion__resize {
  position: absolute;
  display: none;
  z-index: 3;
  width: 14px;
  height: 14px;
}

.rb-discussion__move {
  left: -3px;
  top: -3px;
  border-left: 2px solid var(--rb-copper, #8B5E3C);
  border-top: 2px solid var(--rb-copper, #8B5E3C);
  cursor: move;
}

.rb-discussion__resize {
  right: -3px;
  bottom: -3px;
  border-right: 2px solid var(--rb-copper, #8B5E3C);
  border-bottom: 2px solid var(--rb-copper, #8B5E3C);
  cursor: nwse-resize;
}

/* The writing box follows every other box: its corners come out when it is
   being worked on, not when a pointer passes over it. Clicking into the
   writing counts -- that is focus-within -- so typing is unaffected. */
.rb-discussion:not(.is-locked) .rb-discussion__box.is-picked .rb-discussion__move,
.rb-discussion:not(.is-locked) .rb-discussion__box.is-picked .rb-discussion__resize,
.rb-discussion:not(.is-locked) .rb-discussion__box:focus-within .rb-discussion__move,
.rb-discussion:not(.is-locked) .rb-discussion__box:focus-within .rb-discussion__resize {
  display: block;
}

/* 12 pt on an 11 in page = 1.515cqh. No clamp: a clamped size stops scaling
   and would print smaller than it previews. */
.rb-discussion__body {
  position: absolute;
  inset: 0;
  z-index: 1;
  box-sizing: border-box;
  column-gap: inherit;
  column-count: 2;
  /* Fill the first column, then flow into the second -- what a PowerPoint
     two-column text box does, and what the shipped reports show. Balancing
     was tried and rejected: Chromium split at the seeded header, leaving the
     left column nearly empty and everything pasted in the right. */
  column-fill: auto;
  font-size: 1.515cqh;
  /* Calibri's own line height, as PowerPoint single-spaces. 1.32 was adding
     8% to every line, which is capacity a long narrative needs. */
  line-height: 1.22;
  white-space: pre-wrap;
  word-break: break-word;
  overflow: hidden;
}

/* Paragraphs must be free to split across the column boundary. Forbidding it
   wholesale meant any paragraph taller than the space left simply jumped to
   the next column, and a tall one spilled off the page entirely. */
.rb-discussion__body .rb-rt__p { break-inside: auto; }

/* A heading, though, should not be left stranded at the foot of a column. */
.rb-discussion__body .rb-rt__p:has(> strong:only-child) {
  break-after: avoid;
  break-inside: avoid;
}

.rb-discussion__body:focus {
  outline: 1px solid rgba(139, 94, 60, 0.45);
  outline-offset: 2px;
}



/* The returns are the spacing.
 *
 * Every paragraph carried an automatic three-quarter-line gap, so one return
 * already opened a space and two returns opened two of them plus an empty
 * line -- and the only way to close any of it was a menu whose labels did not
 * say what they did. Tim: "that always jacks up my spacing. It's the bane of
 * my existence ... basically every time you hit return, or hit return twice,
 * it adds one line space in it, I'm fine with that."
 *
 * So nothing is added behind the typing. One return starts a new line; two
 * returns leave a blank one, because an empty paragraph is written as a <br>
 * and stands a line high. What is on the page is what was typed.
 *
 * A paragraph that was given a gap of its own, by this report or an older
 * one, still carries it: that is an inline style and it wins over this. */
.rb-discussion__body .rb-rt__p { margin: 0; }

.rb-discussion__body .rb-rt__list {
  margin: 0;
  padding-left: 1.6em;
}

.rb-discussion__body .rb-rt__p--bullet,
.rb-discussion__body .rb-rt__p--number { margin: 0; }

/* ------------------------------------------------------------------ *
 * The logo — one placement, every page
 *
 * Drawn against the sheet, not inside any one page's layout, so wherever it
 * is put is where every page shows it. Geometry is percentages of the sheet,
 * like everything else placed here, so it holds from preview size to 11 x 17
 * in on paper.
 * ------------------------------------------------------------------ */

.rb-brand {
  position: absolute;
  display: flex;
  align-items: flex-end;
  /* Above every page's own chrome, not under it. At 3 it sat beneath the
     cover's Lock layout bar (4) and the annotation layer (5), so on the cover
     the logo could be seen but never grabbed -- and beneath the discussion
     text box, which swallowed the same grab. It is placed chrome: it has to
     be reachable on whichever page the investigator is looking at. */
  z-index: 7;
  touch-action: none;
}

/* Once locked it is just artwork, so it stops intercepting anything -- text,
   annotations and page controls underneath stay usable. */
.rb-brand.is-locked { pointer-events: none; }

/* The mark is artwork on the page; what tells you it can be moved is ours,
   so it waits until the mark is pointed at. Tim, Oct 17, on the title page:
   "all those corner blocks -- that's one of the things I really dislike." */
.rb-brand:not(.is-locked) {
  outline: none;
  outline-offset: 2px;
  cursor: move;
}

.rb-brand:not(.is-locked):hover {
  outline: 1px dashed var(--rb-copper, #8B5E3C);
}

.rb-brand__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: left center;
}

.rb-brand__resize {
  position: absolute;
  display: none;
  width: 13px;
  height: 13px;
  right: -3px;
  bottom: -3px;
  border-right: 2px solid var(--rb-copper, #8B5E3C);
  border-bottom: 2px solid var(--rb-copper, #8B5E3C);
  cursor: nwse-resize;
}

.rb-brand:not(.is-locked):hover .rb-brand__resize { display: block; }

@media print {
  .rb-brand__resize,
  .rb-discussion__move,
  .rb-discussion__resize { display: none !important; }
  .rb-brand,
  .rb-discussion__box { outline: none !important; }
}

/* Said on screen, never printed: the page cannot show what does not fit. */
.rb-discussion__overflow {
  position: absolute;
  left: 1.96%;
  bottom: 1.2%;
  margin: 0;
  color: #9a3412;
  font-size: 1.3cqh;
  font-weight: 600;
}

.rb-discussion__overflow[hidden] { display: none; }

@media print {
  .rb-discussion__overflow { display: none !important; }
}

.rb-discussion__continue {
  margin-left: 8px;
  padding: 2px 8px;
  border: 1px solid currentColor;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

/* ------------------------------------------------------------------ *
 * Annotations — text box, circle, arrow, picture
 *
 * Free elements on top of any sheet. Geometry is percentages of the sheet,
 * like every other placed element here, so they hold position when the page
 * is scaled from preview size to 11 x 17 on paper.
 * ------------------------------------------------------------------ */

.rb-ov-layer {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
}

/* Drawn ink. One SVG spanning the sheet, under the placed annotation boxes. */
.rb-ov-layer__ink {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}

/* Stroke weight is a fraction of the PAGE, not a count of device pixels.
   1cqh is 1% of sheet height = 7.92pt, the same conversion report-text.js uses
   for type (PT_TO_CQH = 100/792). The old annotations used stroke-width: 3 with
   non-scaling-stroke, which is 3 CSS px -- 0.68% of sheet height in preview but
   0.28% in print, so they drew about 2.4x heavier on screen than on paper.

   non-scaling-stroke stays: it keeps the width out of the stretched SVG user
   space, so caps stay round and nothing is distorted. cqh is what makes that
   width physical instead of a device constant.

   Matched to Distress's three weights at the size a plan actually prints on a
   17in sheet (about 7in across), not to its raw fraction -- its 0.32/0.56/0.88%
   is relative to the plan image, and applying that to the full sheet would be
   2.5x too heavy. */
.rb-ink--t1 { stroke-width: 0.189cqh; }  /* thin   ~1.5pt */
.rb-ink--t2 { stroke-width: 0.316cqh; }  /* medium ~2.5pt */
.rb-ink--t3 { stroke-width: 0.505cqh; }  /* thick  ~4.0pt */

/* The invisible grab copy. Wide enough to catch a thin line without hunting,
   which is what Distress's tolerance hit-test did by hand. */
.rb-ink__hit {
  stroke-width: 1.4cqh;
  vector-effect: non-scaling-stroke;
}

.rb-ov {
  position: absolute;
  box-sizing: border-box;
  pointer-events: auto;
  touch-action: none;
}

.rb-ov:not(.is-locked) { cursor: move; }

.rb-ov:not(.is-locked):hover {
  outline: 1px dashed rgba(139, 94, 60, 0.45);
  outline-offset: 2px;
}

.rb-ov__art {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.rb-ov__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* A text box, as PowerPoint draws one.
 *
 * It has a frame you can see from the moment it is placed -- an empty box with
 * no outline on white paper looked like nothing had happened -- and a border
 * ring you grab to move it, with the writing surface filling everything
 * inside. Clicking the middle of the box used to miss the text entirely,
 * because the field was a thin strip across the top. */
.rb-ov--text {
  display: flex;
  padding: 5px;
  outline: 1px dashed rgba(139, 94, 60, 0.5);
  outline-offset: 0;
}

.rb-ov--text.is-locked {
  padding: 0;
  outline: none;
}

.rb-ov--text:focus-within {
  outline: 1px solid rgba(139, 94, 60, 0.75);
}

.rb-ov__text {
  flex: 1 1 auto;
  width: 100%;
  /* No clipping: the box is as tall as what is written in it. See boxStyle()
     -- a fixed height with overflow:hidden hid everything past the fourth
     line. */
  cursor: text;
  font-size: 1.515cqh;
  line-height: 1.22;
  white-space: pre-wrap;
  word-break: break-word;
}

.rb-ov__text:focus { outline: none; }

/* The box being dragged out on the sheet before it exists. */
.rb-ov-ghost {
  position: absolute;
  z-index: 10;
  border: 1px dashed rgba(139, 94, 60, 0.9);
  background: rgba(139, 94, 60, 0.06);
  pointer-events: none;
}

.rb-ov__hint {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  border: 1px dashed #b9aa98;
  color: #999;
  font-size: 1.3cqh;
}

.rb-ov__resize {
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 13px;
  height: 13px;
  border-right: 2px solid var(--rb-copper, #8B5E3C);
  border-bottom: 2px solid var(--rb-copper, #8B5E3C);
  cursor: nwse-resize;
}

.rb-ov__remove {
  position: absolute;
  right: -9px;
  top: -9px;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 1px solid var(--line, #d7d2c8);
  border-radius: 50%;
  background: #fff;
  color: #777;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
}

.rb-ov:hover .rb-ov__remove { opacity: 1; }

.rb-format__swatch {
  width: 18px;
  height: 18px;
  margin: 0 1px;
  padding: 0;
  border: 1px solid var(--line, #d7d2c8);
  border-radius: 50%;
  cursor: pointer;
}

.rb-format__swatch.is-on {
  box-shadow: 0 0 0 2px var(--accent, #c14a2b);
}

/* Annotations are content and print; their handles are not. */
@media print {
  .rb-ov__resize,
  .rb-ov__remove,
  .rb-ov__hint { display: none !important; }
  .rb-ov,
  .rb-ov--text,
  .rb-ov-ghost,
  .rb-ov__text { outline: none !important; border: 0 !important; }
}

/* Undo stays available even with nothing selected -- it is not a text
   command, and it is the only thing between an autosaved delete and a
   lost paragraph. */
.rb-format:not(.is-ready) .rb-format__group--history .rb-format__btn {
  opacity: 1;
  pointer-events: auto;
}

.rb-format__btn[disabled] {
  opacity: 0.35;
  cursor: default;
}

/* Font colour: PowerPoint's A over a bar of the colour it will paint, with
   the rest of the palette on the chevron beside it. */
.rb-format__menu--color .rb-format__btn--textcolor {
  position: relative;
  padding-bottom: 7px;
}

.rb-format__underbar {
  position: absolute;
  left: 4px;
  right: 4px;
  bottom: 3px;
  height: 3px;
  border-radius: 1px;
  box-shadow: 0 0 0 1px rgba(23, 19, 14, 0.18);
}

.rb-format__btn--caret {
  min-width: 14px;
  padding-left: 0;
  padding-right: 2px;
}

.rb-format__list--color .rb-format__item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.rb-format__chip {
  width: 13px;
  height: 13px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(23, 19, 14, 0.25);
}

.rb-format__sep {
  display: block;
  height: 1px;
  margin: 4px 2px;
  background: var(--line, #d7d2c8);
}

/* A tick on what is already applied, so choosing a value that is already in
   force reads as "already set" rather than "button did nothing". */
.rb-format__item[aria-current="true"]::before {
  content: '\2713\00a0';
  font-weight: 700;
}

/* Report Builder on a small screen.
   A notice, never a lock: the workspace is already mounted and running
   underneath, so dismissing this leaves a live page. Shown once per session,
   below the width where the sheet and the page rail stop fitting together. */
.rb-smallscreen {
  position: absolute;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(17, 17, 17, 0.55);
}

.rb-smallscreen__card {
  max-width: 24rem;
  padding: 20px 22px 18px;
  border-radius: 14px;
  background: var(--panel, #fff);
  box-shadow: 0 18px 50px rgba(8, 32, 54, 0.3);
}

.rb-smallscreen__title {
  margin: 0 0 8px;
  font-size: 17px;
  line-height: 1.25;
  color: var(--ink, #17130e);
}

.rb-smallscreen__body {
  margin: 0 0 16px;
  font-size: 15px;
  line-height: 1.45;
  /* Not --muted: this is the one card that only ever appears on a phone, and
     muted grey on white was too faint to read there. */
  color: #4a4a4a;
}

.rb-smallscreen__row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.rb-smallscreen__go,
.rb-smallscreen__back {
  flex: 1 1 auto;
  min-height: 44px;
  padding: 0 14px;
  border-radius: 10px;
  font-size: 14px;
  cursor: pointer;
}

.rb-smallscreen__go {
  border: 0;
  background: var(--accent, #c14a2b);
  color: #fff;
  font-weight: 600;
}

.rb-smallscreen__back {
  border: 1px solid var(--line, #d9d2c2);
  background: transparent;
  color: var(--ink, #17130e);
}

@media print {
  .rb-smallscreen { display: none !important; }
}

/* ------------------------------------------------------------------ *
 * Right-click a piece of a Floor Survey page: behind, or in front.
 *
 * Tim: "I need to be able to right click and put images behind or in
 * front." Two choices, at the pointer, gone on the next click. It is the
 * only menu Report Builder opens, so it is deliberately plain: the sheet is
 * the thing being looked at.
 * ------------------------------------------------------------------ */

.rb-stackmenu {
  position: fixed;
  z-index: 60;
  display: flex;
  flex-direction: column;
  min-width: 150px;
  padding: 4px;
  border: 1px solid rgba(23, 19, 14, 0.18);
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 10px 28px rgba(23, 19, 14, 0.18);
}

/* The right-click menu in a writing area shares the stack menu's look. Its
   note appears only when the browser refused the clipboard, so it says what
   to press instead rather than leaving the menu looking broken. */
/* Said on the sheet, not in a console. It has to survive the rules that
   strip editor chrome from the printed deck -- it is the opposite of chrome:
   the one thing on a failed sheet that must reach the paper. */
.rb-sheet__failed {
  position: absolute;
  left: 8%;
  right: 8%;
  top: 44%;
  margin: 0;
  padding: 2.2cqh 2.6cqh;
  border: 0.22cqh solid #8c2f1d;
  border-radius: 0.6cqh;
  background: #fff;
  color: #8c2f1d;
  font-size: 2.1cqh;
  line-height: 1.4;
  text-align: center;
  z-index: 9;
}

.rb-stackmenu__note {
  max-width: 24ch;
  margin: 4px 0 0;
  padding: 6px 10px 2px;
  border-top: 1px solid rgba(23, 19, 14, 0.14);
  color: #6b5c4a;
  font-size: 12px;
  line-height: 1.35;
}

.rb-stackmenu__item {
  padding: 7px 10px;
  border: 0;
  border-radius: 6px;
  background: none;
  font: inherit;
  font-size: 14px;
  color: #17130e;
  text-align: left;
  cursor: pointer;
}

.rb-stackmenu__item:hover,
.rb-stackmenu__item:focus-visible {
  background: rgba(139, 94, 60, 0.12);
}

@media print {
  .rb-stackmenu { display: none !important; }
}

/* A folded section in the rail. Used for the locks, which are reached when
   they are wanted rather than standing above the controls all day. */
.rb-fold {
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 6px 8px;
  background: rgba(255, 255, 255, 0.6);
}

.rb-fold__head {
  cursor: pointer;
  list-style: none;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--navy);
  padding: 2px 0;
}

.rb-fold__head::-webkit-details-marker { display: none; }

.rb-fold__head::before {
  content: '\25B8';
  display: inline-block;
  width: 1em;
  color: var(--rb-copper, #8B5E3C);
}

.rb-fold[open] .rb-fold__head::before { content: '\25BE'; }

.rb-fold .btn { width: 100%; margin-top: 6px; }

/* Presentation view is a glyph, not a word. "Present" was the verb; the
   thing it opens is a view, and PowerPoint names its views on icons for the
   same reason -- the row reads as a set of places to be rather than a row of
   commands. The name is still on the button for a screen reader and on the
   tooltip for everyone else, and the waiting state is aria-busy rather than
   a word, which would have thrown the screen away. */
.rb-present-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  padding-left: 0;
  padding-right: 0;
  line-height: 1;
}

.rb-present-btn svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.rb-present-btn[aria-busy='true'] {
  opacity: 0.6;
}

/* Zoom. The page is 11x17 and the stage is whatever is left after the rail
   and the panel, so on a laptop the sheet is drawn at about two-thirds and
   the discussion type is small to work in. Zoom changes the magnification
   only -- never the type on the page, which would change the printed
   report. Tim, Oct 23, 2026: "I don't say font, zoom in, zoom out, so we
   can read it easier." */
.rb-zoom {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
}

.rb-zoom__btn,
.rb-zoom__level {
  border: 0;
  background: transparent;
  color: var(--navy);
  font: inherit;
  cursor: pointer;
  padding: 0 10px;
  line-height: 1;
}

.rb-zoom__btn {
  width: 32px;
  padding: 0;
  font-size: 18px;
  font-weight: 700;
}

.rb-zoom__level {
  min-width: 54px;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.rb-zoom__btn:hover,
.rb-zoom__level:hover { background: #eef2f4; }

/* Zoomed past fit, the page is bigger than the stage, so the stage has to
   scroll. Centring a flex child with justify-content clips the top and left
   of an oversized one -- the part you cannot scroll back to -- so the paper
   centres with margin:auto instead, which does not.
   Tim, Oct 31, 2026 (iPad Mini): once zoomed, need scrollbars on the RIGHT
   and BOTTOM of the canvas viewing window to move around the sheet. */
.rb-stage {
  overflow: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.rb-stage--zoomed {
  /* Always reserve scrollbar gutters so right + bottom bars are findable
     on desktop and iPad (overlay bars were easy to miss). */
  overflow: scroll;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
  scrollbar-color: rgba(7, 40, 61, 0.45) rgba(8, 32, 54, 0.08);
}

.rb-stage--zoomed::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}
.rb-stage--zoomed::-webkit-scrollbar-track {
  background: rgba(8, 32, 54, 0.08);
}
.rb-stage--zoomed::-webkit-scrollbar-thumb {
  background: rgba(7, 40, 61, 0.45);
  border-radius: 6px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
.rb-stage--zoomed::-webkit-scrollbar-thumb:hover {
  background: rgba(7, 40, 61, 0.65);
  background-clip: padding-box;
}
.rb-stage--zoomed::-webkit-scrollbar-corner {
  background: rgba(8, 32, 54, 0.08);
}

/* When zoomed, one-finger pan must reach the stage. Drag grips keep
   touch-action: none; the sheet/boxes themselves allow pan so the
   investigator can move around without finding a pixel of stage chrome. */
.rb-stage--zoomed .rb-sheet,
.rb-stage--zoomed .rb-cover-box,
.rb-stage--zoomed .rb-floor-box,
.rb-stage--zoomed .rb-discussion__frame {
  touch-action: pan-x pan-y;
}
.rb-stage--zoomed [data-rb-brand-resize],
.rb-stage--zoomed [data-rb-cover-resize],
.rb-stage--zoomed [data-rb-cover-move],
.rb-stage--zoomed .rb-cover-box__resize,
.rb-stage--zoomed .rb-cover-box__move,
.rb-stage--zoomed .rb-floor-box__resize,
.rb-stage--zoomed [data-rb-floor-resize],
.rb-stage--zoomed [data-plan-resize],
.rb-stage--zoomed .rb-discussion__move,
.rb-stage--zoomed .rb-discussion__resize,
.rb-stage--zoomed [data-rb-disc-move],
.rb-stage--zoomed [data-rb-disc-resize],
.rb-stage--zoomed [data-rb-penlog-move],
.rb-stage--zoomed [data-rb-penlog-resize] {
  touch-action: none;
}

.rb-stage__paper {
  margin: auto;
}
.rb-rail__select {
  display: block;
  width: 100%;
  margin: 0.35rem 0 0.6rem;
  padding: 0.35rem 0.45rem;
  font: inherit;
  border: 1px solid #c9d0d5;
  border-radius: 6px;
  background: #fff;
}
