/* =====================================================================
   review-layer.css — v1.020
   TLC Review Board · Review / Comment / Approve — the LAYER, phase B3.

   WHAT THIS IS
   A cosmetic-when-off overlay for /reviews/board. Comment mode OFF must be
   byte-for-byte the board Craig designed: this file declares NOTHING that
   paints until `body.rvl-on` exists. Every rule below is either scoped to
   `body.rvl-on`, or scoped to an element only this layer creates.

   B3 ADDS the LIGHT reading panel (concept C, chosen 2026-09-04), the
   comment cards, the composer and the pin markers.

   WHY THE PANEL IS LIGHT ON A DARK BOARD — this is not a taste call.
   Craig, 2026-09-04: "it needs to be a big departure, because most of our
   backgrounds are going to be dark or colorful so that white background
   offsets perfectly for review changes." Three directions were drawn on the
   board's own tokens and C was chosen and promoted to Main. The literals
   below ARE that decision, measured off the approved artboard
   (_review-handoff/design-comment-panel/Main.dc.html). They are not
   re-derived here and they are not to be harmonised with the dark rail.

   CONTRAST, so nothing on the light side is a guess:
     body ink   rgba(30,31,35,.81) on #fff  — the board's own dark --ink-2
     secondary  rgba(30,31,35,.64) on #fff  — 4.5:1 text
     control    #b8b8b8 boundary on #fff    — 3:1 non-text
     eyebrow    #9a6b0d on #fff             — the gold that survives on light
     filter on  #8a5f00 ink / #c98f1c line

   WHY body.rvl-on AND NOT A NEW GRID TRACK AT REST
   `.shell{grid-template-columns:var(--rail-w) 1fr}` is the board's own rule.
   Rewriting it to a three-track template with `--rvl-w:0` at rest LOOKS free
   and is not: `getComputedStyle(.shell).gridTemplateColumns` then reports a
   third track at every viewport, which fails the one acceptance test that
   proves this layer changed nothing. The state class costs one selector and
   keeps "off" provably identical.

   TOKENS
   Every var() carries a literal fallback. /reviews/board loads ZERO
   stylesheets and resolves NO brand chain — measured 2026-09-04 07:41 MDT:
   --color1, --font1Family and --fontPrimary are all EMPTY on that page. An
   undeclared custom property makes the whole declaration invalid at
   computed-value time (dropped, not defaulted), so a bare var() here paints
   nothing at all. The board's own tokens (--accent :28, --f-display :39,
   --f-text :40, --u-ink :2513) ARE declared and are used first, with a
   literal behind them.

   THE PAGE'S OWN RESETS THIS FILE IS BUILT AGAINST. Measured: FIVE unscoped
   rules in board.html's 3,903-line inline style can reach a new descendant
   of .shell, and only two carry !important.
     board.html:55   *,*::before,*::after{box-sizing:border-box}
     board.html:69   img,svg{display:block;max-width:100%;user-select:none}
     board.html:77   [hidden]{display:none!important}      author rule, already !important
     board.html:78   button{font:inherit;color:inherit;background:none;border:0;
                            margin:0;padding:0;cursor:pointer}
     board.html:79   :focus-visible{outline:2px solid var(--accent);
                            outline-offset:3px;border-radius:2px}
     board.html:3910 @media (prefers-reduced-motion:reduce){*{transition-duration:.01ms!important}}
   There is NO rule for bare input / textarea / select / ::placeholder / p /
   h1-h6 / a anywhere in that block. So:
   · every control here states its own font — `button{font:inherit}` is a
     SHORTHAND reset and a textarea gets the UA's 13.3px monospace default;
   · every button here restates background, border, padding and radius,
     because :78 stripped all four and there is no .btn on this page;
   · every svg here is SIZED, because `img,svg{max-width:100%}` is the only
     rule a bare <svg> matches and an unsized one paints at 300x150;
   · this file is linked at board.html:11721, AFTER the inline style, so it
     wins every equal-specificity tie by source order — `!important` is
     needed only where board.html already used it.

   Estate rules this file is already obeying, do not "clean them up":
   · the [hidden] blanket is per-SUBTREE, not per-element (bug shipped 3x)
   · no hover-lift and no geometry change on :hover — a target that moves
     under the cursor oscillates, and motion makes Craig ill
   · a control must not resize between mousedown and mouseup or the click is
     thrown away (measured 26px on SweetwaterCreek /v2)
   · headings are never gray
   · a tool surface reads in Open Sans, never Hypatia
   ===================================================================== */

/* ===== TOKENS ======================================================== */
:root{
  /* `--rvl-w` retired 2026-09-25 with the grid track it sized. The window is a
     fixed overlay at every width now; its width is on `.rvl-panel`. */

  /* --- the DARK side: pins, and the toggle, which live over the board --- */
  --rvl-accent:  var(--accent, #e3a52a);
  --rvl-on-acc:  #181206;                       /* ink ON the gold dot */
  --rvl-done:    rgba(3,147,3,1);               /* review-bar.css:64 --tlcrb-done */
  --rvl-pending: #d0d4d9;                       /* review-bar.css:63 --tlcrb-pending */
  --rvl-bad:     #b3261e;
  --rvl-pin-sh:  0 2px 10px rgba(0,0,0,.5);
  --rvl-pin-vl:  rgba(15,16,18,.55);            /* the draft dot's own ground */
  /* The floating comment window's lift. It is the one element in this layer
     that has to read as ABOVE both the board and the panel, on a ground that
     may be any color a client picked. */
  --rvl-m-sh:    0 18px 50px rgba(0,0,0,.45), 0 2px 8px rgba(0,0,0,.28);

  /* --- the LIGHT side: the reading panel, concept C ------------------- */
  --rvl-p-bg:    #fcfcfc;
  --rvl-p-card:  #fff;
  --rvl-p-rest:  #f4f4f4;                       /* a resolved card */
  --rvl-p-line:  #e6e6e6;                       /* hairline between parts */
  --rvl-p-edge:  #d8d8d8;                       /* the panel's own left edge */
  --rvl-p-ctl:   #b8b8b8;                       /* a control's boundary */
  --rvl-p-quote: #ececec;                       /* the reply rule */
  --rvl-p-ink:   #1e1f23;
  --rvl-p-ink2:  rgba(30,31,35,.81);
  --rvl-p-ink3:  rgba(30,31,35,.64);
  --rvl-p-gold:  #9a6b0d;                       /* the panel eyebrow */
  --rvl-p-gon:   #c98f1c;                       /* an ON filter's line */
  --rvl-p-goni:  #8a5f00;                       /* an ON filter's ink, and the panel focus ring */

  /* THE FOUR STATE COLORS, NAMED BY CRAIG 2026-09-24: "Open color: gold,
     yellow · Resolved color: success green · Late color: danger red". The
     `-h` twin is the same ground one step deeper, for hover. LATE has no
     filter yet — the color is decided and reserved, not in use. */
  --rvl-f-open:  #fdf2d7;  --rvl-f-open-h: #f8e6b4;
  --rvl-f-done:  #d9f5db;  --rvl-f-done-h: #c2edc8;
  --rvl-f-mine:  #fff7bd;  --rvl-f-mine-h: #fdef8e;
  --rvl-f-late:  #fbdedc;  --rvl-f-late-h: #f6c8c4;
  /* The bright yellow a comment wears in the panel while its window is open. */
  --rvl-f-live:  #ffe94f;
  /* Success, and the portal's EDIT gold — the two primary hover grounds. */
  --rvl-ok:      #198754;
  --rvl-edit:    var(--rvl-accent, #e3a52a);
  /* The estate's own semantics, measured on /ops/style-guide 2026-09-24.
     --rvl-chip-h is "slightly darker gray than the hover is now", which is
     what the resting ground used to be. */
  --rvl-warn:    #ffd700;  --rvl-warn-h: #ffe14d;
  --rvl-succ:    #00b52b;
  --rvl-chip-na: #3f4145;
  --rvl-chip-h:  #e2e2e2;

  --rvl-disp:    var(--f-display, 'Nexa','Helvetica Neue',Helvetica,Arial,sans-serif);
  /* READING TEXT IS OPEN SANS, NOT --f-text.
     --f-text is Hypatia (board.html:40) and Craig's standing rule is that a
     TOOL surface he has to read is Open Sans — Hypatia is unreadable to him
     there. The approved artboard rendered its body copy in Source Sans 3 as
     a stand-in "at close metrics", which is a humanist sans far nearer Open
     Sans than Hypatia, so this is also the closer match to what he saw. */
  --rvl-read:    'Open Sans','Segoe UI',system-ui,-apple-system,Helvetica,Arial,sans-serif;
  --rvl-radius:  6px;

  /* Z LADDER — spec §5.5, and it is NOT the older plan's 5001/5100/5050.
     Measured ladder on THIS page: .prog 7 · #conceptCue 55 · .zoom 60 ·
     .sectionpage 60 · .pager-mob 60 · .navsheet 8000 · .mg-over 9000 ·
     .mg-na 99999. The last three are how the board says "the deck is open",
     "the artwork changed" and "I cannot show you the artwork", and each must
     always win. Pins sit at 55, just under .zoom. */
  --rvl-z-pin:    55;
  --rvl-z-panel:  70;

  /* ---- THE BADGE, AND THE WINDOW DERIVED FROM IT --------------------
     Every offset in this file that has to agree with the badge is a calc off
     these four, because the badge has now moved twice and each move silently
     broke a number written somewhere else.

     104, NOT 80. Craig, 2026-09-25: "move the comments icon slightly down, so
     it does not overlay 'full screen'." Measured at 1600x1000: `.utils` (the
     01/04 counter and FULL SCREEN) ends at y 58 on the board and `.zoom-close`
     ends at y 60 in the detail view, and the badge's word sat at y 60-72 —
     touching both. At 104 the word sits at 84 and clears them by 26 and 24.

     THE WINDOW STOPS SHORT OF BOTH EDGES. Craig, same message: "since it
     doesn't have a header and footer it doesn't need to go all the way to the
     top and all the way to the bottom." 70 is the badge's word minus 14 of
     air, so the disc AND the word are inside the window — which is the thing
     he asked for by name. Symmetric at the bottom, which also clears the
     detail view's swatch row (measured top 942 of 1000). */
  --rvl-fab-top:  104px;
  --rvl-fab-size: 52px;
  --rvl-fab-lab:  20px;   /* the word's 12px line + the 8px it floats by */
  --rvl-win-top:  calc(var(--rvl-fab-top) - var(--rvl-fab-lab) - 14px);
  --rvl-win-bot:  70px;
  --rvl-z-bar:    7000;
  --rvl-z-back:   7050;
  --rvl-z-modal:  7100;
}

/* ===== THE [hidden] BLANKET ==========================================
   board.html:77 already ships `[hidden]{display:none!important}` as an
   AUTHOR rule, so on this page the attribute works. This blanket stays
   anyway: these two files are meant to be liftable onto a page that does NOT
   carry that reset, and there `[hidden]{display:none}` lives only in the UA
   sheet — which any author `display:` beats at any specificity. That has
   shipped as a bug three times in this estate. One blanket over the whole
   subtree, at the top, covers the parts nobody has written yet. */
.rvl [hidden],
.rvl[hidden],
[class^="rvl-"][hidden],
[class*=" rvl-"][hidden]{ display:none !important }

/* ===== THE TOGGLE ====================================================
   A GOLD BADGE IN THE TOP RIGHT, ALWAYS VISIBLE. Craig, 2026-09-24: "We need
   to have an icon in the upper right instead of the COMMENTS pill. it could be
   bright yellow with the icon, click to expand the side column ... i like the
   recaptcha because it could always be visible with the css gold/warning bg
   color."

   THE ANCHORING IS `.tlce-toggle`'s, ported from shared/editor/v1/editor.css:
   `position:fixed`, appended to <body> so no ancestor's overflow or stacking
   context can bury it, a 7px gutter, and an offset that is ANCHORED rather
   than derived from whatever the page pins to an edge. Mirrored to the TOP
   because the bottom corner is already reCAPTCHA 14-74 / SiteEdit 80-140 /
   ToTop 146-206 and that stack is locked.

   z 95 puts it over the Detail view (60) and the panel (70, 90 while zoomed)
   and under the comment window (7100) and `.mg-na` (99999) — a badge that
   covered the window you opened from it would be the one control that must
   never win. */
.rvl-fab{
  position:fixed; right:7px; top:var(--rvl-fab-top, 104px); z-index:var(--rvl-z-fab, 95);
  width:var(--rvl-fab-size, 52px); height:var(--rvl-fab-size, 52px); border-radius:50%;
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--rvl-warn, #ffd700); color:var(--rvl-on-acc, #181206);
  border:0; padding:0; margin:0; cursor:pointer;
  box-shadow:0 6px 20px rgba(0,0,0,.42);
}
/* CRAIG'S OWN FILE, MASKED so it takes the badge's ink in both states —
   `img/review_board/comment-regular.svg`, which is the `far fa-comment` glyph
   he asked for. FontAwesome is not loaded on this board and one glyph does not
   justify a font. */
.rvl-fab-ico{
  width:24px; height:24px; flex:0 0 auto;
  background:currentColor;
  -webkit-mask:url("https://turnerlee.com/img/review_board/comment-regular.svg") center / contain no-repeat;
  mask:url("https://turnerlee.com/img/review_board/comment-regular.svg") center / contain no-repeat;
}
/* PRESSED IS A WHITE GROUND, NOT A DARK ONE. Craig, 2026-09-25: "I want the
   close icon for COMMENTS to be white bg not black." The ink stays the same
   near-black the gold state uses, so only the ground changes between the two
   states — a disc that swapped both would read as two different controls. */
.rvl-fab[aria-pressed="true"]{
  background:var(--rvl-p-card, #fff); color:var(--rvl-on-acc, #181206);
}
/* IT DOES NOT MOVE, AND IT NEVER STANDS DOWN. Craig, 2026-09-25: "Leave the
   open and close comments icon in the exact same place you want to be able to
   toggle it on and off without having to move your mouse."

   THE TWO BRANCHES THAT USED TO LIVE HERE ARE DELETED. At 1440+ the badge
   stepped left by the panel's width; below 1440 it hid itself and the panel's
   own CLOSE was the way back. Both were answers to "do not cover the panel",
   and both cost the thing a toggle is for — the second click landing where the
   first one did. The panel reserves the badge's band instead; see
   `.rvl-filters`. z 95 already puts the badge over the panel (70, 90 zoomed),
   so nothing else is needed to keep it on top of what it opened. */
.rvl-fab:hover{ background:var(--rvl-warn-h, #ffe14d) }
.rvl-fab[aria-pressed="true"]:hover{ background:#f0f0f0 }
/* The count is its own disc on the corner, so the badge's own box never
   changes size when the number appears — a control that grows under the press
   loses the press. */
.rvl-fab .rvl-count{
  position:absolute; top:-3px; left:-3px;
  min-width:22px; height:22px; padding:0 5px; border-radius:999px;
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--rvl-p-ink, #1e1f23); color:#fff;
  font-family:var(--rvl-disp, sans-serif); font-weight:900; font-size:11px;
  font-variant-numeric:tabular-nums; line-height:1;
  box-shadow:0 2px 8px rgba(0,0,0,.4);
}
/* The count keeps the gold it wears on the pressed disc; on white that is the
   same figure-on-ground pair the unpressed badge uses, inverted once instead
   of twice. */
.rvl-fab[aria-pressed="true"] .rvl-count{
  background:var(--rvl-warn, #ffd700); color:var(--rvl-p-ink, #1e1f23);
}

/* THE FLOATING WORD, AND IT IS THE PANEL'S CLOSE. Craig, 2026-09-25: "I don't
   think we really need the close button in the top right, instead maybe it
   could be a floating word 'COMMENTS/CLOSE' just above the icon (partially
   transparent but always showing - depending on the background) since the
   yellow comment icon opens/closes."

   RIGHT-ALIGNED TO THE DISC, NOT CENTERED ON IT. "COMMENTS" sets ~95px at this
   face and the disc is 52 — centered, its right edge lands at x 1614 on a
   1600px window and the word is cut off by the viewport. Aligning the right
   edges puts it inside the same 7px gutter the disc already respects, at
   every width.

   THE FACE IS THE PANEL'S OWN GOLD EYEBROW, restated here because the head
   that used to carry it was deleted 2026-09-25. 9.5px / .34em / 400 caps is
   the same decision the rail's eyebrow makes at board.html:138; this word is
   a label for the same thing, not a second small-caps decision.

   TWO INKS, BECAUSE THE GROUND IS KNOWN IN BOTH STATES AND IT FLIPS. Closed,
   the word sits on the board's dark chrome or on client artwork, so it is
   white with a shadow that carries it over a light picture too. Open, it sits
   on the panel's own glass, which is white at .5 over whatever is behind —
   always the lighter of the two — so it flips to the panel's ink. That is his
   "depending on the background", answered from state rather than from a
   luminance read of a surface the badge is not inside. */
/* THE WORD IS CLICKABLE, AND SO IS THE AIR BETWEEN IT AND THE DISC. Craig,
   2026-09-26: "the area above the icon around the Close needs to be clickable
   to toggle the open/close". It was `pointer-events:none` sitting OUTSIDE the
   button's box, so a click on it fell through to whatever was behind. Now it
   is a hit box: `bottom:100%` + an 8px pad puts the glyph exactly where the
   old `bottom:calc(100% + 8px)` did, and the pad fills the gap down to the
   disc; `min-width:100%` makes it at least the disc's width. A click on it
   bubbles to the button's own handler — it is the button's child. */
.rvl-fab-label{
  position:absolute; right:0; bottom:100%;
  padding:8px 0 8px 10px; min-width:100%; text-align:right;
  white-space:nowrap; pointer-events:auto; cursor:pointer;
  font-family:var(--rvl-disp, sans-serif); font-weight:400;
  font-size:9.5px; letter-spacing:.34em; text-transform:uppercase;
  color:#fff; opacity:.72;
  text-shadow:0 1px 3px rgba(0,0,0,.55), 0 0 10px rgba(0,0,0,.35);
}
/* OPEN IS WHITE AT .8. Craig, 2026-09-26: ""CLOSE" needs to be white font
   (0.8 opacity) when open". The white keeps the closed state's shadow.
   ...UNLESS THE GROUND IS LIGHT. Same message: "the color of COMMENTS/CLOSE
   need to detect the bg its on just like the 'Full screen' button." The JS
   reads the ink the board already computed for the surface under the word
   (--z-ink in the detail view, --u-ink on the stage — the exact value FULL
   SCREEN is painted with) and sets `rvl-fab-onlight` when that ink is dark.
   Declared difference: on a light ground the word drops its dark shadow, as
   FULL SCREEN has none — a dark halo under dark ink reads as a smudge. */
.rvl-fab[aria-pressed="true"] .rvl-fab-label{ opacity:.8 }
.rvl-fab.rvl-fab-onlight .rvl-fab-label{
  color:#1e1f23; opacity:.81; text-shadow:none;
}

/* ===== THE PANEL =====================================================
   TWO BRANCHES, AND THE FIXED SHEET IS THE UNMEDIATED DEFAULT.
   A pair of adjacent queries (min-width:1001px / max-width:1000px) leaves a
   hole at any fractional width between them — browser zoom, a scaled
   display, a non-integer window — and at 1000.5px the panel would be a
   static grid item in a two-track grid, auto-placed into an implicit row and
   clipped away by `.shell{height:100dvh;overflow:hidden}`. No throw, no log:
   the toggle turns on and nothing appears. So the sheet is the default and
   the track is the override, and every width lands in exactly one of them.

   WHY THE TRACK ONLY AT 1440 AND NOT AT 1001.
   The board already spends its stage on a right column: --right-w is
   clamp(300px,27vw,560px) at :root and clamp(260px,26vw,420px) below 1240,
   and --rail-w is 300/340/425. At 1001px a third track leaves the primary
   pane 1001 - 300 - 320 - 260 = 121px, which reads as "the board is broken
   on my laptop" rather than "the panel does not fit". Measured primary-pane
   width WITH the panel: 1440 -> 391px · 1600 -> 476px · 1920 -> 662px.
   Below 1440 the panel is the right-edge sheet instead. */
/* IT IS A WINDOW NOW, NOT A FULL-HEIGHT SHEET. Craig, 2026-09-25: "since it
   doesn't have a header and footer it doesn't need to go all the way to the
   top and all the way to the bottom ... round the top left and bottom left
   corner of the new window", and "we need to make sure the comments icon and
   the word CLOSE above it is clearly within the comments window."
   The insets come off `--rvl-fab-top` so the disc and its word are inside the
   window by construction, and standing back from both edges is what leaves the
   detail view's own close (top 20-60) and swatch row (top 942) reachable —
   which is the reason he gave for dropping the head and the foot.

   AND IT BLURS WHAT IS BEHIND IT IN EVERY STATE. Craig, same message: "We need
   to slightly blur the items behind the comments window. It's a little bit too
   distracting with this very subtle transparent background." The blur used to
   be `body.rvl-zoomed` only; measured 2026-09-25, the resting panel is
   rgba(255,255,255,.5) with `backdrop-filter:none`, which is the surface he is
   describing. His .5 is untouched — the blur is what settles it. */
.rvl-panel{
  position:fixed; top:var(--rvl-win-top, 70px); right:0; bottom:var(--rvl-win-bot, 70px); left:auto;
  width:min(92vw, 440px);
  border-radius:18px 0 0 18px;
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  z-index:var(--rvl-z-panel, 70);
  display:flex; flex-direction:column; min-width:0; min-height:0;
  /* CRAIG'S OWN LINE, 2026-09-24: "i tried something like this, i think it
     works well ... .rvl-panel { background: rgba(255,255,255,0.5); }". Shipped
     as he wrote it. The cards keep more of their own paper so a comment is
     still readable over artwork; the glass is the PANEL, not the reading. */
  background:var(--rvl-p-glass, rgba(255,255,255,0.5));
  /* NO EDGE. Craig, 2026-09-25: "remove the white stroke that appears to be
     around the entire comments window." It was `border-left:1px solid #d8d8d8`,
     drawn when the panel was a full-height sheet whose left edge was a seam
     against the board. On a rounded floating window that one border tapers
     around both left corners and reads as a light outline on all four sides.
     Deleted; the shadow is what separates the window from what is behind it. */
  box-shadow:-14px 0 34px rgba(0,0,0,.42);
  color:var(--rvl-p-ink, #1e1f23);
  /* Stated, not inherited: body is Hypatia 300 with antialiased smoothing,
     which was tuned for white on #0f1012. The same values on #1e1f23 over
     #fcfcfc thin every stroke and read a weight lighter than they measure. */
  font-family:var(--rvl-read, system-ui, sans-serif); font-weight:400;
  -webkit-font-smoothing:auto; -moz-osx-font-smoothing:auto;
  overflow:hidden;                  /* the LIST scrolls, never the panel */
}
/* THE GRID TRACK IS DELETED. Craig, 2026-09-25: "The panel is not showing
   properly on the overview, it's pushing the entire background to the left and
   stealing the space, it should overlay just like it does in detail view, so I
   should still see the background colors below it, and we should still see the
   full screen icon above it not to the side."

   Above 1440 this file used to add a third column to `.shell` and hand the
   panel a track of its own, which is exactly the squeeze he is describing: the
   stage lost `--rvl-w` and every control in its header row slid left with it.
   One branch now, at every width — a fixed window over the board, the same
   object the detail view already shows him. `.shell` is left alone, so "off"
   and "on" are provably the same grid. `--rvl-w` has no reader left and is
   retired with it. */

/* An unsized <svg> matches only `img,svg{max-width:100%}` on this page and
   paints at the replaced-element default 300x150. board.html sizes its icons
   per component (.util svg :2524, .pg svg :2669) and has no generic rule, so
   this one is stated before any icon is authored. */
.rvl-panel svg{
  width:16px; height:16px; flex:0 0 auto;
  fill:none; stroke:currentColor; stroke-width:1.5;
}

/* ---- head: DELETED, 2026-09-25 -------------------------------------
   Craig: "I actually don't think we need a header and footer at all for the
   comments ... If the header isn't there, the user could still close the
   detail view quickly." Measured: the head band ran y 0-54 across the panel
   and `.zoom-close` sits at 1540,20-1580,60 — the head was on top of the one
   control that gets you out of the detail view. The version it used to name
   is carried by `.rvl-now-head` instead, above this version's own comments,
   which is where he asked for it.
   `.rvl-fab-label` above still borrows `.rvl-panel-title`'s face; that face is
   restated there rather than left as a dangling reference. */
/* ---- filters ------------------------------------------------------- */
/* THE PILL IS CRAIG'S OWN BLOCK, PASTED 2026-09-24, and it is a SPEC — the
   34 / 14 / 10 / 600 / 12 / .08em below are his numbers, not a reading of
   them. The 2x pass that preceded it took the row to 52px and had to let it
   wrap; at 34px the three pills fit one line again, and `flex-wrap` stays as
   the belt for a fourth filter (LATE) or a three-digit count. */
/* THE ROW SITS ON THE BADGE'S OWN LINE. Craig, 2026-09-25: "slide the open,
   resolved mine and previous comments up in line with the newly placed
   comments icon." The pad is what centres a 34px pill on the 52px disc,
   measured from the window's top rather than from the viewport: the disc is at
   `--rvl-fab-top` and the window starts at `--rvl-win-top`, so the whole
   expression moves with either. It replaces the 88px landing zone the deleted
   head needed.

   THE RIGHT PAD IS THE DISC'S COLUMN, AND IT IS EXACT. The disc reaches
   `--rvl-fab-size` + its 7px gutter in from the panel's right edge, so a pad
   of exactly that leaves the pills the whole line they can actually have:
   measured 2026-09-25 the three set 86.4 + 118.5 + 82.9 with two 7px gaps =
   302.2, and the pad leaves 305 at 1600 and 361 at 1280-768 — one line, the
   way Craig drew it — and 267 at 1440 and 280 at 390, where the row wraps
   rather than letting the disc sit on MINE.

   A FLEX SPACER CANNOT DO THIS, MEASURED. An inert `::after` of the disc's
   intrusion is the LAST item on the line, so `flex-wrap` wraps IT and leaves
   the pills exactly where they were — row 84px tall, all three pills still at
   y113 under the disc. Wrapping moves the overflowing item, and the
   overflowing item is never the one you are trying to protect. */
.rvl-filters{ flex:0 0 auto; display:flex; flex-wrap:wrap; gap:7px;
  padding:calc(var(--rvl-fab-top, 104px) + (var(--rvl-fab-size, 52px) - 34px) / 2 - var(--rvl-win-top, 70px))
          calc(var(--rvl-fab-size, 52px) + 7px) 0 20px }
.rvl-filter {
  height: 34px;
  padding: 0 14px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--rvl-p-ctl, #b8b8b8);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--rvl-disp, sans-serif);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--rvl-p-ink3, rgba(30,31,35,.64));
  background: none;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
/* EACH FILTER CARRIES ITS OWN GROUND. Craig, 2026-09-24: "Open color: gold,
   yellow · Resolved color: success green · Late color: danger red" and "OPEN .
   bg should be the soft yellow-gold color used when selected · RESOLVED . bg
   should be the soft bright green color like the checkmark · MINE . can bg be
   light bright yellow". Keyed on `data-rvl-filter`, which the JS stamps, so a
   filter added later declares its ground in one place and cannot inherit the
   wrong one by position. --rvl-f-late is DECLARED AND UNUSED on purpose:
   there is no Late filter yet and the color is his, decided now. */
.rvl-filter[data-rvl-filter="open"]{     background:var(--rvl-f-open, #fdf2d7) }
.rvl-filter[data-rvl-filter="resolved"]{ background:var(--rvl-f-done, #d9f5db) }
.rvl-filter[data-rvl-filter="mine"]{     background:var(--rvl-f-mine, #fff7bd) }
.rvl-filter[data-rvl-filter="late"]{     background:var(--rvl-f-late, #fbdedc) }
.rvl-filter[aria-pressed="true"]{
  box-shadow:inset 0 0 0 1px var(--rvl-p-gon, #c98f1c);
  color:var(--rvl-p-goni, #8a5f00);
}
/* A PILL DOES NOT POP. Craig: "ALL buttons should hvr-pop on hover, and change
   bg color. PILLS do not need to hvr-pop." So hover deepens the ground and
   darkens the ink, and NOTHING here may change the BOX — a boundary that moves
   under a resting cursor oscillates on and off at frame rate. */
.rvl-filter:hover{ color:var(--rvl-p-ink, #1e1f23) }
.rvl-filter[aria-pressed="true"]:hover{ color:var(--rvl-p-goni, #8a5f00) }
.rvl-filter[data-rvl-filter="open"]:hover{     background:var(--rvl-f-open-h, #f8e6b4) }
.rvl-filter[data-rvl-filter="resolved"]:hover{ background:var(--rvl-f-done-h, #c2edc8) }
.rvl-filter[data-rvl-filter="mine"]:hover{     background:var(--rvl-f-mine-h, #fdef8e) }
.rvl-filter[data-rvl-filter="late"]:hover{     background:var(--rvl-f-late-h, #f6c8c4) }

/* ---- the list ------------------------------------------------------ */
/* A VISIBLE SCROLLBAR, DELIBERATELY. The rail hides its own
   (board.html:97-98) because it is short chrome; a thread list is a reading
   surface of unknown length and hiding the only signal of how much is below
   is a loss, not a match. */
.rvl-panel-body{
  flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain;
  display:flex; flex-direction:column; gap:12px;
  padding:16px 20px 8px;
  scrollbar-width:thin;
}

/* HONEST EMPTY STATE. No invented rows, no placeholder thread, no "N/A".
   Empty says empty — a cosmetic fallback that invents data is worse than a
   blank slot, because a plausible wrong value never gets reported. */
.rvl-empty{
  margin:0; font-size:14px; line-height:1.55;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
}

/* ---- a comment card ------------------------------------------------ */
.rvl-card{
  display:flex; flex-direction:column; gap:9px;
  padding:15px 16px 13px;
  background:var(--rvl-p-card, #fff);
  border:1px solid var(--rvl-p-line, #e6e6e6);
  border-radius:var(--rvl-radius, 6px);
  box-shadow:0 1px 2px rgba(0,0,0,.04);
  scroll-margin:12px;
}
.rvl-card.is-resolved{
  padding:13px 16px;
  background:var(--rvl-p-rest, #f4f4f4);
  box-shadow:none;
}
/* SELECTED IS A BORDER COLOR, NOT A SIZE. The card must not change its own
   height when it is picked, or the list reflows under the pointer. */
.rvl-card.is-sel{ border-color:var(--rvl-p-gon, #c98f1c) }
/* THE ONE THE WINDOW IS OPEN ON. Craig, 2026-09-24: "when Comment modal open,
   highlight item in Comments panel bright yellow bg." It is a LOUDER signal
   than `.is-sel` on purpose — selection is a highlight, this is "the floating
   window in front of you belongs to THIS row", and the list may be scrolled
   far away from it. It beats `.is-resolved`'s gray ground, which is declared
   above it at equal specificity, by carrying its own `.is-resolved` twin. */
.rvl-card.is-live, .rvl-card.is-resolved.is-live{
  background:var(--rvl-f-live, #ffe94f);
  border-color:var(--rvl-p-goni, #8a5f00);
  box-shadow:0 1px 2px rgba(0,0,0,.10);
}

.rvl-card-head{ display:flex; align-items:center; gap:10px }

.rvl-badge{
  flex:0 0 auto; width:21px; height:21px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--rvl-disp, sans-serif); font-weight:900; font-size:11px;
  font-variant-numeric:tabular-nums; line-height:1;
}
.rvl-badge.is-sent{ background:var(--rvl-accent, #e3a52a); color:var(--rvl-on-acc, #181206) }
.rvl-badge.is-draft{
  background:var(--rvl-p-card, #fff);
  box-shadow:inset 0 0 0 1.5px var(--rvl-accent, #e3a52a);
  color:var(--rvl-p-goni, #8a5f00);
}
.rvl-badge.is-resolved{ background:var(--rvl-done, rgba(3,147,3,1)); color:#fff }
.rvl-badge svg{ width:12px; height:12px; stroke-width:2.6;
  stroke-linecap:round; stroke-linejoin:round }

.rvl-who{
  font-family:var(--rvl-disp, sans-serif); font-weight:400;
  font-size:9px; letter-spacing:.18em; text-transform:uppercase;
  color:var(--rvl-p-ink, #1e1f23);
  min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.rvl-card.is-resolved .rvl-who{ color:var(--rvl-p-ink3, rgba(30,31,35,.64)) }

.rvl-tag{
  flex:0 0 auto;
  font-family:var(--rvl-disp, sans-serif); font-weight:400;
  font-size:7.5px; letter-spacing:.2em; text-transform:uppercase;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
  box-shadow:inset 0 0 0 1px var(--rvl-p-ctl, #b8b8b8);
  border-radius:999px; padding:2px 7px;
}
.rvl-when{
  margin-left:auto; flex:0 0 auto;
  font-family:var(--rvl-read, sans-serif); font-size:11.5px;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
}

.rvl-body{
  margin:0; font-size:15px; line-height:1.55;
  color:var(--rvl-p-ink2, rgba(30,31,35,.81));
  text-wrap:pretty; overflow-wrap:anywhere; white-space:pre-wrap;
}
.rvl-card.is-resolved .rvl-body{
  font-size:14.5px; color:var(--rvl-p-ink3, rgba(30,31,35,.64));
}

/* ---- replies ------------------------------------------------------- */
.rvl-replies{
  display:flex; flex-direction:column; gap:5px;
  margin-top:3px; margin-left:16px;
  padding-left:13px; border-left:2px solid var(--rvl-p-quote, #ececec);
}
.rvl-reply{ display:flex; flex-direction:column; gap:5px }
.rvl-reply-head{ display:flex; align-items:center; gap:9px }
.rvl-reply-body{
  margin:0; font-size:14.5px; line-height:1.55;
  color:var(--rvl-p-ink2, rgba(30,31,35,.81));
  overflow-wrap:anywhere; white-space:pre-wrap;
}

/* ---- card actions --------------------------------------------------- */
.rvl-actions{ display:flex; gap:8px; margin-top:6px; flex-wrap:wrap }
/* Sized off the pill Craig pasted, so the panel's two control families read as
   one: same 12px / 600 / .08em label, same 34px box.

   A GROUND AT REST, NOT FLOATING TEXT. Craig, 2026-09-24: "make sure all of
   the buttons have at least that soft gray bg behind like EDIT here. i don't
   like them looking just like floating text." So `--rvl-p-rest` moves from
   being the HOVER to being the resting ground, and hover becomes the button's
   own meaning. Applied to the class, so the panel card's chips and the
   window's row stay one control rather than two that look alike. */
.rvl-chip{
  height:34px; padding:0 14px; border-radius:4px;
  box-shadow:inset 0 0 0 1px var(--rvl-p-ctl, #b8b8b8);
  display:inline-flex; align-items:center; justify-content:center;
  font-family:var(--rvl-disp, sans-serif); font-weight:600;
  font-size:12px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--rvl-p-ink2, rgba(30,31,35,.81));
  background:var(--rvl-p-rest, #f4f4f4); cursor:pointer;
}
/* THE HOVER SAYS WHICH BUTTON IT IS, and the two named colors are the estate's
   own — measured on turnerlee.com/ops/style-guide 2026-09-24, `btn-warning`
   rgb(255,215,0) and `btn-success` rgb(0,181,43), both on white ink. Craig:
   "EDIT: btn-warning white text · RESOLVE: btn-success white text · N/A:
   something dark gray white text · CLOSE unsure maybe just slightly drker gray
   than the hover is now."
   Keyed on `data-rvl-act`, which the JS stamps — a label match would break the
   moment RESOLVE reads "Reopen" and N/A reads "Applicable", which they both do. */
.rvl-chip:hover{ color:var(--rvl-p-ink, #1e1f23); background:var(--rvl-chip-h, #e2e2e2) }
/* REPLY IS THE RAIL'S GOLD. Craig, 2026-09-24: "REPLY button on hover in
   Comments window should be bg gold (same color as the 'V4' image2)" —
   measured on the live rail, `.rail-v.is-active` is rgb(227,165,42), which is
   the board's own `--accent` and this layer's `--rvl-accent`. The ink is the
   layer's on-accent, the same pairing every other gold surface here uses. */
.rvl-chip[data-rvl-act="reply"]:hover{   background:var(--rvl-accent, #e3a52a); color:var(--rvl-on-acc, #181206) }
.rvl-chip[data-rvl-act="edit"]:hover{    background:var(--rvl-warn, #ffd700); color:#fff }
.rvl-chip[data-rvl-act="resolve"]:hover{ background:var(--rvl-succ, #00b52b); color:#fff }
.rvl-chip[data-rvl-act="na"]:hover{      background:var(--rvl-chip-na, #3f4145); color:#fff }
.rvl-chip[data-rvl-act="close"]:hover{   background:var(--rvl-chip-h, #e2e2e2); color:var(--rvl-p-ink, #1e1f23) }
.rvl-chip[disabled]{ opacity:.45; cursor:default }
.rvl-chip[disabled]:hover{ color:var(--rvl-p-ink2, rgba(30,31,35,.81)); background:var(--rvl-p-rest, #f4f4f4) }

/* ---- the foot ------------------------------------------------------
   THE INSTRUCTIONS ARE GONE. Craig, 2026-09-24: "remove the bottom footer ...
   I don't think we need those instructions at all in the footer." The hint
   line is deleted from the markup.

   WHAT IS LEFT IS THE STATUS LINE, AND IT HAS TO STAY: `say()` writes every
   refusal there — "NOT SAVED — …" — and a failed write with nowhere to report
   is the one thing this layer may never do. He pre-answered that case: "can
   that be in white text if it must stay." So it stays, in white, on a band
   that is only as tall as the line it holds. */
/* ---- foot: THE BAND IS DELETED, THE STATUS LINE IS NOT ---------------
   Craig, 2026-09-25: "I actually don't think we need a header and footer at
   all for the comments ... If the footer wasn't there, the user could still
   switch background colors quickly." Measured: the band ran y 931-1000 and the
   detail view's swatch row sits at 1397,942-1560,976 — the foot was lying on
   top of the background switcher, exactly as he says.

   THE LINE ITSELF STILL HAS NOWHERE ELSE TO GO. `say()` writes every refusal
   into it — "NOT SAVED — …" — and a failed write with nothing to report it is
   the one thing this layer may never do. So the BAND goes and the line becomes
   what it already looked like: a chip, floating in the window's bottom-left,
   present only when it has something to say. `:not(:empty)` is what makes that
   true without a second piece of state. */
.rvl-panel > .rvl-note{
  position:absolute; left:20px; bottom:14px; z-index:2;
  max-width:calc(100% - 40px);
}
/* THE RESTING LINE IS A LINE, NOT A DISABLED INPUT. Concept C draws the
   composer at rest as a plain instruction: there is nothing to type into
   until a pin exists, and a focusable empty box that refuses text is worse
   than a sentence that says why. */
.rvl-hint{
  min-height:64px; padding:12px 13px;
  background:var(--rvl-p-card, #fff);
  border:1px solid var(--rvl-p-ctl, #b8b8b8);
  border-radius:var(--rvl-radius, 6px);
  font-family:var(--rvl-read, sans-serif); font-size:15px; line-height:1.55;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
}
/* There is NO textarea rule anywhere in board.html, so every declaration
   here is load-bearing: without them the composer renders in the UA's
   monospace default at 13.3px with a 2px inset border. */
.rvl-ta{
  display:block; width:100%; min-height:64px; max-height:34vh; resize:vertical;
  padding:12px 13px; margin:0;
  background:var(--rvl-p-card, #fff);
  border:1px solid var(--rvl-p-ctl, #b8b8b8);
  border-radius:var(--rvl-radius, 6px);
  font-family:var(--rvl-read, sans-serif); font-weight:400;
  font-size:15px; line-height:1.55;
  color:var(--rvl-p-ink2, rgba(30,31,35,.81));
}
.rvl-ta::placeholder{ color:var(--rvl-p-ink3, rgba(30,31,35,.64)); opacity:1 }
.rvl-ta:focus{ border-color:var(--rvl-p-gon, #c98f1c) }

.rvl-note{
  font-family:var(--rvl-disp, sans-serif); font-weight:600;
  font-size:9.5px; letter-spacing:.18em; text-transform:uppercase;
  color:#fff;
  min-width:0; overflow-wrap:anywhere;
}
/* White on glass is unreadable, so the line carries its own ground — the same
   near-black the panel's ink comes from. */
.rvl-panel > .rvl-note:not(:empty){
  display:inline-flex; align-items:center;
  padding:5px 10px; border-radius:4px;
  background:var(--rvl-p-ink, #1e1f23);
}
/* A FAILED WRITE SAYS SO, IN THE PANEL, AND THE DRAFT STAYS. It never reads
   as saved and it never silently disappears. */
.rvl-note.is-bad{ color:var(--rvl-bad, #b3261e); letter-spacing:.12em }

.rvl-btns{ display:flex; align-items:center; gap:8px; flex:0 0 auto }
/* THE LARGER BUTTON, KEPT LARGER. Craig, 2026-09-24: "keep SAVE CHANGES
   larger button, 100% width". Its WIDTH is set where it is used (the window's
   own row), not here, so the same class can sit in a panel foot later. */
.rvl-primary{
  height:52px; min-width:0; justify-content:center;
  padding:0 24px; border-radius:var(--rvl-radius, 6px);
  background:var(--rvl-p-ink, #1e1f23); color:#fff;
  display:inline-flex; align-items:center;
  font-family:var(--rvl-disp, sans-serif); font-weight:700;
  font-size:15px; letter-spacing:.14em; text-transform:uppercase;
  cursor:pointer;
}
.rvl-primary[disabled]{ opacity:.42; cursor:default }

/* ===== THE PIN OVERLAY ===============================================
   THE HOST IS THE DRAWN RECT, NOT THE ELEMENT BOX.
   On five of the six surfaces the <img> is width:100%;height:100% with
   object-fit:contain (board.html:358, :1243, :2092), so its element box is
   the padded container and the artwork is letterboxed inside it. Sizing the
   host to the DRAWN rect means (a) a stored coordinate is a straight
   fraction of this box in both directions, and (b) a click in the letterbox
   is not a click on the artwork and passes straight through to the board's
   own zoom. JS computes that rect from naturalWidth/naturalHeight and writes
   it inline; this file only makes the host inert until it is placed. */
.rvl-pins{
  position:absolute; z-index:var(--rvl-z-pin, 55);
  pointer-events:none;
  inset:auto; margin:0; padding:0; border:0; background:none;
}
body.rvl-on .rvl-pins{ pointer-events:auto; cursor:crosshair }
/* A REFUSED SURFACE IS INERT, NOT INVISIBLE-BUT-CLICKABLE. Brand Application
   tiles are object-fit:cover with object-position:50% 15%
   (board.html:2377-2379, restated at :3591-3593 below 1000px, and NEITHER is
   behind a min-width guard): the mark is cropped, so a contain projection is
   wrong there and a stored coordinate rots in silence. JS builds no overlay
   for those at all — this rule is the belt for anything that slips past. */
.rvl-pins.is-refused{ pointer-events:none !important; cursor:default }

/* The anchor is the 53 hit box; the dot inside it is 31.2 and never grows to
   make the target bigger. Guide §23: pad the anchor, do not grow the icon.

   +20%, EXACTLY. Craig, 2026-09-24: "Comment icon with number should be 20%
   larger". 26 -> 31.2, 34 -> 40.8, 12 -> 14.4, 15 -> 18, and the anchor with
   them (44 -> 52.8) so the padding round the dot is unchanged — growing the
   dot inside a fixed anchor would have eaten the 9px of slop that keeps a pin
   clickable at the edge of a mark. */
.rvl-pin{
  position:absolute; width:52.8px; height:52.8px; margin:-26.4px 0 0 -26.4px;
  display:flex; align-items:center; justify-content:center;
  background:none; border:0; padding:0; cursor:pointer;
  /* The pin must not move as a result of being hovered or selected: the hit
     box is stated once, unconditionally, and only paint changes. */
}
.rvl-dot{
  width:31.2px; height:31.2px; border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--rvl-disp, sans-serif); font-weight:900; font-size:14.4px;
  font-variant-numeric:tabular-nums; line-height:1;
  box-shadow:var(--rvl-pin-sh, 0 2px 10px rgba(0,0,0,.5));
}
.rvl-dot.is-sent{ background:var(--rvl-accent, #e3a52a); color:var(--rvl-on-acc, #181206) }
.rvl-dot.is-draft{
  background:var(--rvl-pin-vl, rgba(15,16,18,.55));
  color:var(--rvl-accent, #e3a52a);
  box-shadow:inset 0 0 0 1.5px var(--rvl-accent, #e3a52a), var(--rvl-pin-sh, 0 2px 10px rgba(0,0,0,.5));
}
.rvl-dot.is-resolved{ background:var(--rvl-done, rgba(3,147,3,1)); color:#fff }
.rvl-dot svg{ width:16.8px; height:16.8px; flex:0 0 auto;
  fill:none; stroke:currentColor; stroke-width:2.6;
  stroke-linecap:round; stroke-linejoin:round }
/* SELECTED grows the DOT inside the fixed 44 anchor and adds a halo. The
   anchor does not move and does not resize, so the pin cannot walk out from
   under the cursor that just picked it. */
/* 1.027: the grown dot + halo is now the NEW-COMMENT pin's only (is-draft).
   A selected existing comment takes the gold ring below — Craig, 2026-10-02:
   "make sure selecting it in the comments uses this gold large check. there is
   no reason for this partially larger with green glow version." The green-glow
   resolved variant is gone with it. */
.rvl-pin.is-sel .rvl-dot.is-draft{
  width:40.8px; height:40.8px; font-size:18px;
  box-shadow:0 0 0 4px rgba(227,165,42,.22), var(--rvl-pin-sh, 0 2px 10px rgba(0,0,0,.5));
}
/* THE PANEL'S REPLY BOX (1.021) — the window's reply box, drawn under the
   message in its card. Its own hover ground is the window's: "success". */
.rvl-inline-reply{ margin-top:10px }
.rvl-inline-reply .rvl-modal-btns{ margin-top:8px }
.rvl-inline-reply .rvl-primary{ width:100%; min-width:0 }
.rvl-inline-reply .rvl-primary:hover:not([disabled]){ background:var(--rvl-ok, #198754); color:#fff }

/* THE TRASH (1.019). Craig, 2026-10-02: "a small trash can icon in gray in
   the bottom right corner, on hover turn red". margin-left:auto takes it to
   the right end of the action row; centered on the row like every item in a
   row. No ground, no lift, no scale: the color is the whole hover. */
.rvl-trash{
  margin-left:auto; align-self:center; flex:0 0 auto;
  width:28px; height:28px; padding:0; border:0; background:none;
  display:inline-flex; align-items:center; justify-content:center;
  font-size:14px; line-height:1; cursor:pointer;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
  /* "very subtle like 0.2 opacity prior to hover" — Craig, 2026-10-02. */
  opacity:.2;
  transition:color .15s ease, opacity .15s ease;
}
.rvl-trash:hover, .rvl-trash:focus-visible{ color:var(--rvl-bad, #b3261e); opacity:1 }

/* THE PIN THE WINDOW IS FOR (1.018). Craig, 2026-10-02: "The icon on the
   location of the comment needs to enlarge x3 and have a gold border so we can
   tell which comment the window is for." 31.2 -> 93.6, its number and tick 3x
   with it. A real border, never an inset shadow (sloppy uneven edges), and
   border-box so the border sits inside the 93.6. The anchor stays 52.8, so the
   hit box does not move; the dot overflows it centered. No transition: a
   growing pin is motion, and this is a state, not an animation. Above the
   other pins so a neighbor never sits on top of it. */
.rvl-pin.is-open, .rvl-pin.is-sel{ z-index:3 }
/* 2026-10-02 later: "reduce size of selected comment by 25%. make gold border
   1px thicker. remove drop shadow" -> 93.6 -> 70.2 (number 32.4, tick 37.8),
   border 3 -> 4px, no shadow. */
/* SELECTED IN THE COMMENTS = THE SAME RING (1.027), so a card click shows
   the very pin the popup would — never the new-comment pin (is-draft). */
.rvl-pin.is-open .rvl-dot,
.rvl-pin.is-open.is-sel .rvl-dot,
.rvl-pin.is-open:hover .rvl-dot,
.rvl-pin.is-sel .rvl-dot:not(.is-draft),
.rvl-pin.is-sel:hover .rvl-dot:not(.is-draft){
  width:70.2px; height:70.2px; font-size:32.4px; flex:0 0 auto;
  box-sizing:border-box; border:4px solid gold; transition:none;
  box-shadow:none;
}
.rvl-pin.is-open .rvl-dot svg,
.rvl-pin.is-sel .rvl-dot:not(.is-draft) svg{ width:37.8px; height:37.8px }
/* Hover changes the ring and nothing else — no lift, no scale, no move. */
.rvl-pin:hover .rvl-dot{ box-shadow:0 0 0 3px rgba(227,165,42,.28), var(--rvl-pin-sh, 0 2px 10px rgba(0,0,0,.5)) }

/* ===== LOCKED ON A PREVIOUS VERSION ==================================
   Craig, 2026-09-24: "PREVIOUS VERSIONS / You can view Comments, but you
   cannot ADD/EDIT comments - Comments Locked once new version is published."
   The overlay stops OFFERING what it will refuse: no crosshair, no grab
   cursor on a pin. The pins themselves stay clickable, because reading a
   comment is exactly what this state is for. */
body.rvl-locked .rvl-pins{ cursor:default }
body.rvl-locked .rvl-pin{ cursor:pointer }
.rvl-locked{
  font-family:var(--rvl-disp, sans-serif); font-weight:600;
  font-size:11px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
}

/* ===== CARRIED FORWARD — PREVIOUS VERSIONS' COMMENTS =================
   Craig, 2026-09-24: "on Next Version, any previous Comments should be
   included at the top (expand to view status) Resolved should show the small
   circle-check we use on the TLC5.0 update page".

   THE TICK IS PORTED, NOT DRAWN. `Content/Snippets/sst-ops-tlc5-body.html`
   (md5 ec493a7b2a225c50fd29d7a88ee5bec9) lines 80-98 — itself a byte-for-byte
   copy of `shared/pbs/v1/pbs.css` 4513-4556 — is the source. Rule BODIES are
   verbatim: 20px, 1.5px #C7C8CA ring, 50% radius, white ground, the
   border-color hover, and on done `border:0` plus `--s-donefill` under
   `/img/schedule/circle-check-custom.svg` at `center / 100% 100%`.

   TWO DECLARED DIFFERENCES, and no others:
     · the class prefix is `rvl-`, not `pbx-`, so this layer owns its own
       nodes — everything it appends carries `data-rvl` and is stripped out of
       the Detail view's clone of the artwork host.
     · there is a THIRD state. The source has done / not-done; Craig asked for
       "checkmark or not applicable or incomplete", so `.is-na` is added — the
       same ring, filled flat gray with a dash, because "does not apply" is
       neither an open item nor an achievement.
   The two `--s-*` tokens the source reads are declared here with the board's
   own literals, exactly as the tlc5 port declares them on `.tlc5`. */
/* `flex:0 0 auto` IS LOAD-BEARING. `.rvl-panel-body` is a column flex
   SCROLLER, so every child defaults to `flex-shrink:1` and is squeezed to fit
   rather than scrolling — measured 2026-09-24: this block rendered 343 x 2px,
   its border and nothing else, while every assertion about it passed because
   it was in the DOM, first, visible and opacity 1. `.rvl-card` never showed
   this because a card is `display:flex` with its own content floor; a section
   whose children are also flex items has none. */
.rvl-past{
  flex:0 0 auto;
  display:flex; flex-direction:column;
  /* NO BORDER, IN EITHER STATE. Craig, 2026-09-26: "remove the white border
     from the previous comments header." The collapsed `1px solid transparent`
     let this section's own #fff background paint through the border box — a
     white ring round the #bbbbbb bar — and `.is-open` turned it #d3d3d3. */
  border:0;
  border-radius:var(--rvl-radius, 6px);
  background:var(--rvl-p-card, #fff);
  overflow:hidden;
  --s-done:#00C137; --s-donefill:#D8FFC6;
  /* The expanded block's own three grays — quiet paper, a darker rule, and the
     board's own #3f4145 for the header, which is the deck's Dark Gray swatch. */
  --rvl-past-bg:#f2f2f2; --rvl-past-edge:#d3d3d3; --rvl-past-head:#3f4145;
}
/* COLLAPSED, IT IS BARELY THERE. Craig, 2026-09-25: "old comments is not quite
   working ... it needs to be something more like #bbbbbb bg with gray text, so
   it stays subtle and is not called out in any way ... We basically want those
   old comments there, but barely visualized because they are not important
   any more. We just need to be able to go back to them if needed."
   #bbbbbb ground, the panel's secondary ink on top of it. EXPANDED is not
   touched — the dark head with white type is the state he asked for on
   2026-09-24 and said he wanted kept. */
.rvl-past-head{
  flex:0 0 auto;
  display:flex; align-items:center; gap:9px;
  padding:11px 14px; width:100%;
  background:var(--rvl-past-rest, #bbbbbb); border:0; cursor:pointer;
  font-family:var(--rvl-disp, sans-serif); font-weight:600;
  font-size:12px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
  text-align:left;
}
.rvl-past-head:hover{ background:#b2b2b2; color:var(--rvl-p-ink2, rgba(30,31,35,.81)) }
.rvl-past-count{ font-variant-numeric:tabular-nums; color:var(--rvl-p-ink3, rgba(30,31,35,.64)) }

/* OPEN IT AND IT GOES DARK, AND OLD. Craig, 2026-09-24: "give the previous
   versions a very subtle gray bg when expanded (representing it's old/done-ish).
   i like how it's gray and changes on hover until it's expanded. When it's
   expanded let's give it a dark gray bg header with white text so we really
   know for sure we're viewing a PREVIOUS VERSION COMMENTS."
   Collapsed is untouched — that is the state he said he likes. */
.rvl-past.is-open{ background:var(--rvl-past-bg, #f2f2f2) }
.rvl-past.is-open .rvl-past-head{
  background:var(--rvl-past-head, #3f4145); color:#fff;
}
.rvl-past.is-open .rvl-past-head:hover{ background:#4a4c50; color:#fff }
.rvl-past.is-open .rvl-past-count{ color:rgba(255,255,255,.66) }
.rvl-past.is-open .rvl-past-todo{ background:var(--rvl-accent, #e3a52a); color:var(--rvl-on-acc, #181206) }
/* HOW MANY ARE STILL UNMARKED — the reason to open the block, so it is the one
   thing in the head that is not quiet. */
.rvl-past-todo{
  padding:2px 8px; border-radius:999px;
  background:var(--rvl-f-open, #fdf2d7); color:var(--rvl-p-goni, #8a5f00);
  font-size:11px; letter-spacing:.06em;
}
/* THE +/- IS A TAB FILLING THE HEAD'S RIGHT END. Craig, 2026-09-26: "make
   sure the right side + icon has a bg behind it filling the right edge like
   TLC PBS headers". Ported geometry of /ops/schedule `.pb2-sec-head-actions`
   (measured 2026-09-26 at 1600: 65px wide, the head's full height, flush right,
   white 19px glyph on a fill one step off the head's own). The head drops its
   right pad and the tab cancels the 11px vertical pad so it is edge to edge.
   Declared: the fills are grays, not PBS blue — #a8a8a8 on the #bbbbbb rest
   head, #4a4c50 (the open head's existing hover) on the #3f4145 open head. */
.rvl-past-head{ padding-right:0 }
.rvl-past-caret{
  margin:-11px 0 -11px auto; align-self:stretch; width:65px; flex:0 0 65px;
  display:flex; align-items:center; justify-content:center;
  background:#a8a8a8; color:#fff; font-size:19px; line-height:1;
}
.rvl-past.is-open .rvl-past-caret{ background:#4a4c50 }

/* ---- THIS VERSION'S OWN HEADER -------------------------------------
   Craig, 2026-09-25: "V4 COMMENTS needs to simply be text only floating in the
   space above the first comment and below the V3 comments header. you can
   reduce the space by half above that 'V4 COMMENTS'."

   TEXT, NOT A BAR. The first pass built it out of `.rvl-past` + `.rvl-past-head`
   so that "just like V3 comments" held by construction; he has corrected that
   — the carried block is a CONTROL you open and this is a LABEL, so giving
   them the same card was making two different things look alike. What it keeps
   is the head's type, which is what "just like" was about. 9px above, half the
   18 the bar carried. */
/* CRAIG'S OWN BLOCK, PASTED 2026-09-25, AND IT IS A SPEC — the 300 / 15px /
   15px / .08em / white below are his values, not a reading of them. The four
   lines around them are the layout the label still needs inside a column
   flex scroller: `flex:0 0 auto` or it is squeezed to nothing, the 9px he
   asked for above it, and the row that holds the label beside its count. */
.rvl-now{
  flex:0 0 auto;
  margin:9px 0 0; padding-bottom:6px;
  display:flex; align-items:center; gap:9px;
  font-family: var(--rvl-disp, sans-serif);
  font-weight: 300;
  font-size: 15px;
  padding-left: 15px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: white;
}
.rvl-now:first-child{ margin-top:0 }
.rvl-now .rvl-past-count {
  color: rgba(255,255,255,.64);
}
/* IT OPENS AS FAR AS IT CAN, THEN SCROLLS. Craig, 2026-09-24: "Expand is also
   not displaying all of the items fully, the window isn't tall enough. the
   window should open as far as it can and should be scrollable when space is
   limited and all can't be viewed. scroll down then at bottom pause for fulll
   1.0 second before further scrolling outside the expanded window if needed."

   That second sentence is SCROLL HOLD-AND-RELEASE, and it is not written here:
   `overscroll-behavior:contain` is half of it and
   `shared/core/v1/scroll-hold-release.js` is the other half, loaded by the
   layer at 1000ms. `contain` ALONE TRAPS HIM — both halves or neither.

   `max-height` is written INLINE by the JS from the panel body's own height,
   because "as far as it can" is a measurement, not a number. This rule is the
   floor for the case where that measurement has not landed yet. */
.rvl-past-body{
  flex:0 0 auto;
  display:flex; flex-direction:column; gap:10px;
  padding:12px 14px 14px;
  border-top:1px solid var(--rvl-past-edge, #d3d3d3);
  max-height:52vh;
  overflow-y:auto;
  overscroll-behavior:contain;
  scrollbar-width:thin;
}
.rvl-past-ver{
  font-family:var(--rvl-disp, sans-serif); font-weight:700;
  font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--rvl-p-gold, #9a6b0d);
}
.rvl-past-ver:not(:first-child){ margin-top:6px }
.rvl-past-item{ display:flex; align-items:flex-start; gap:9px }

/* ---- the ported tick ------------------------------------------------- */
.rvl-sub-check {
  flex:0 0 auto;
  width:20px; height:20px;
  margin-top:1px;
  padding:0;
  border:1.5px solid #C7C8CA;
  border-radius:50%;
  background:#fff;
  cursor:pointer;
  transition:border-color .12s;
}
button.rvl-sub-check:hover { border-color:var(--s-done); }
span.rvl-sub-check{ cursor:default }
.rvl-past-item.is-resolved .rvl-sub-check {
  border:0;
  background:var(--s-donefill) url("https://turnerlee.com/img/schedule/circle-check-custom.svg") center / 100% 100% no-repeat;
}
.rvl-past-item.is-resolved .rvl-sub-text { color:#999; }
/* THE THIRD STATE, which the source does not have. Flat gray with a dash: it
   is closed, and it is not an achievement. */
.rvl-past-item.is-na .rvl-sub-check{
  border:0; background:#D9DADB;
  position:relative;
}
.rvl-past-item.is-na .rvl-sub-check::after{
  content:""; position:absolute; left:4px; right:4px; top:50%;
  height:1.5px; margin-top:-.75px; border-radius:1px; background:#8B8D8F;
}
.rvl-past-item.is-na .rvl-sub-text{ color:#999 }
.rvl-sub-text {
  flex:1 1 auto; min-width:0;
  white-space:normal; overflow-wrap:anywhere;
  padding:1px 4px; margin:-1px -4px;
  border-radius:3px;
  outline:0;
  cursor:pointer;
  font-family:var(--rvl-read, sans-serif); font-size:14px; line-height:1.5;
  color:var(--rvl-p-ink2, rgba(30,31,35,.81));
}
.rvl-past-meta{
  display:block; margin-top:2px;
  font-family:var(--rvl-disp, sans-serif); font-weight:600;
  font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
}

/* ---- the third state, on a pin and on a card badge -------------------- */
.rvl-dot.is-na{ background:#D9DADB; color:#5f6163 }
.rvl-badge.is-na{ background:#D9DADB; color:#5f6163 }

/* ===== hvr-pop — COPIED VERBATIM FROM THE SST =========================
   Craig, 2026-09-24: "ALL buttons should hvr-pop on hover, and change bg
   color. PILLS do not need to hvr-pop."

   `shared/core/v1/sst-styles.css:5949` owns this utility estate-wide, and
   `/reviews/board` DOES NOT LOAD THAT SHEET — measured 2026-09-24, zero
   `sst-styles` references in board.html. So the keyframes and the class are
   copied here BYTE FOR BYTE rather than reimplemented, and the `[disabled]`
   guard comes with them: the pop is a claim that the click will do something,
   and a gated ADD REPLY must not jump under the cursor.

   ⚠ If board.html ever starts loading sst-styles.css, DELETE this block
   rather than leaving two definitions of one animation. */
@keyframes hvr-pop{50%{transform:scale(1.1)}}
.hvr-pop{position:relative;vertical-align:middle;transform:perspective(1px) translateZ(0);
  box-shadow:0 0 1px rgba(0,0,0,0)}
.hvr-pop:hover,.hvr-pop:focus-visible,.hvr-pop:active{z-index:1000}
.hvr-pop:hover,.hvr-pop:focus,.hvr-pop:active{
  animation-name:hvr-pop;animation-duration:.3s;
  animation-timing-function:linear;animation-iteration-count:1}
.rvl-chip.hvr-pop[disabled]:hover,.rvl-chip.hvr-pop:disabled:hover,
.rvl-primary.hvr-pop[disabled]:hover,.rvl-primary.hvr-pop:disabled:hover,
.rvl-chip.hvr-pop[disabled]:focus,.rvl-primary.hvr-pop[disabled]:focus{animation:none}
@media (prefers-reduced-motion:reduce){ .hvr-pop:hover,.hvr-pop:focus,.hvr-pop:active{animation:none} }
/* `.hvr-pop` SETS `position:relative`, AND IT COMES LATER IN THIS SHEET.
   Both selectors are (0,1,0), so source order decides and the pop wins — which
   silently unpins anything positioned that also wants to pop. Measured
   2026-09-24: the corner badge computed `position:relative` and landed at
   -7,1080 instead of fixed in the top right, and the ONLY symptom was a
   control in the wrong corner. The pin guard below was written for this and
   the badge was added without one. Any future positioned `.hvr-pop` needs a
   line here. */
.rvl-pin.hvr-pop{ position:absolute }
.rvl-fab.hvr-pop{ position:fixed }

/* ===== THE FLOATING COMMENT WINDOW ===================================
   Craig, 2026-09-24: "NEW Comment should popup a floating modal window (drag
   to move - Just like the SAVE modal window in SiteEdit). This allows user to
   pinpoint their comment, drag the window where they can use it best and it
   floats by default directly to the right or below their comment."

   IT IS THE SITEEDIT SAVE PANEL'S GESTURE, PORTED, NOT A SECOND ONE.
   editor.css:1702-1721 draws that panel's grip and text-edit.js:1471-1531
   drives it; both are copied here. Three declared differences, and only
   three:
     · ANCHORED left/top, not right/bottom. SiteEdit's panel docks
       bottom-centre, so right/bottom is the axis it rests on; this one is
       anchored to a PIN that can be anywhere on screen, so a right/bottom
       store would move the window every time the stage resized under it.
     · THE "DRAG TO MOVE" LABEL SITS IN THE HEAD, not above the panel.
       editor.css:1790-1801 hangs it off `bottom:100%`, which on a window
       floating beside a pin near the top of the artwork would put the label
       off screen — the one place a hint may never be.
     · THE TEXTAREA IS EXCLUDED FROM THE PANEL-WIDE HANDLE alongside the
       buttons. SiteEdit's panel has no text input, so `.swcE-barBtns` was the
       whole exclusion there; a drag that started on this one would eat the
       selection gesture the box exists for.

   The palette is concept C's, unchanged — this window and the reading panel
   are the same surface and must not be two whites.

   NO TRANSITION AND NO ANIMATION. Craig gets motion sick, and a window that
   eases into place under a pointer that is already moving toward it is the
   exact failure the no-hover-lift rule exists for. */
.rvl-modal{
  position:fixed; left:0; top:0; z-index:var(--rvl-z-modal, 7100);
  width:min(440px, calc(100vw - 24px));
  box-sizing:border-box;
  padding:26px 20px 18px;
  background:var(--rvl-p-card, #fff);
  border:1px solid var(--rvl-p-ctl, #b8b8b8);
  border-radius:var(--rvl-radius, 6px);
  box-shadow:var(--rvl-m-sh, 0 18px 50px rgba(0,0,0,.45), 0 2px 8px rgba(0,0,0,.28));
  font-family:var(--rvl-read, sans-serif);
  color:var(--rvl-p-ink, #1e1f23);
  /* THE WHOLE WINDOW IS A HANDLE (text-edit.js:1450-1474), so the press must
     not also start a text selection on the chrome it lands on. The textarea
     re-enables its own. */
  -webkit-user-select:none; user-select:none;
  touch-action:none;
  cursor:grab;
}
.rvl-modal.is-drag{ cursor:grabbing }
.rvl-modal-grip{
  display:block; position:absolute; left:0; right:0; top:0;
  height:18px; z-index:3; cursor:grab; touch-action:none;
}
.rvl-modal-grip::before{
  content:""; position:absolute; left:50%; top:50%;
  width:34px; height:4px; transform:translate(-50%,-50%);
  border-radius:2px; background:var(--rvl-p-ctl, #b8b8b8);
}
.rvl-modal-grip:hover::before{ background:var(--rvl-p-ink3, rgba(30,31,35,.64)) }
.rvl-modal-grip:active{ cursor:grabbing }

.rvl-modal-head{
  display:flex; align-items:center; gap:9px; flex-wrap:wrap;
  margin:0 0 10px;
}
/* WHITE, CENTERED, FLOATING ABOVE THE WINDOW — `.swcE-barDrag` from
   shared/editor/v1/editor.css:1790-1824, ported. Craig, 2026-09-24: "DRAG TO
   MOVE should be white floating centered above the window, exactly like we do
   it on the SiteEdit Save window."

   Every value below is that rule's: `bottom:100%` with `padding-bottom:20px`
   so the 20px band above the panel is part of the HANDLE and not dead air
   (Craig, 2026-08-25, on exactly that gap), `left:50%` + `translateX(-50%)`,
   11px / 600 / .18em / uppercase / nowrap, `opacity:0` rising to `.5` on
   panel hover, and `pointer-events:auto` + `cursor:grab` + `touch-action:none`
   because it IS a handle. Two declared differences: the ink is white, which is
   what he asked for and what this window needs over artwork rather than over
   SiteEdit's white paper; and the font token is this layer's. */
.rvl-modal-drag{
  position:absolute;
  left:50%;
  bottom:100%;
  padding-bottom:20px;
  transform:translateX(-50%);
  font-family:var(--rvl-disp, sans-serif);
  font-size:11px;
  font-weight:600;
  letter-spacing:.18em;
  text-transform:uppercase;
  white-space:nowrap;
  color:#fff;
  opacity:0;
  transition:opacity .18s ease;
  pointer-events:auto;
  cursor:grab;
  touch-action:none;
}
.rvl-modal-drag:active{ cursor:grabbing }
.rvl-modal:hover .rvl-modal-drag{ opacity:.5 }
@media (prefers-reduced-motion:reduce){ .rvl-modal-drag{ transition:none } }
/* The badge is the panel card's badge at the pin's own size, so the number in
   the window and the number on the artwork read as one thing. */
.rvl-modal-badge{
  width:31.2px; height:31.2px; border-radius:50%; flex:0 0 auto;
  display:flex; align-items:center; justify-content:center;
  font-family:var(--rvl-disp, sans-serif); font-weight:900; font-size:14.4px;
  font-variant-numeric:tabular-nums; line-height:1;
}
.rvl-modal-badge.is-sent{ background:var(--rvl-accent, #e3a52a); color:var(--rvl-on-acc, #181206) }
.rvl-modal-badge.is-draft{ background:var(--rvl-p-ink, #1e1f23); color:var(--rvl-accent, #e3a52a) }
.rvl-modal-badge.is-resolved{ background:var(--rvl-done, rgba(3,147,3,1)); color:#fff }
.rvl-modal-badge svg{ width:16.8px; height:16.8px; flex:0 0 auto;
  fill:none; stroke:currentColor; stroke-width:2.6;
  stroke-linecap:round; stroke-linejoin:round }
.rvl-modal-who{
  font-family:var(--rvl-read, sans-serif); font-weight:600; font-size:15px;
  color:var(--rvl-p-ink, #1e1f23);
}
.rvl-modal-when{
  font-family:var(--rvl-disp, sans-serif); font-weight:400;
  font-size:8.5px; letter-spacing:.22em; text-transform:uppercase;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
}
/* The read-back of the thread this window is open on: the body, then every
   reply, exactly as the card renders them. Capped, because a long thread must
   not push the composer off the bottom of the screen. */
.rvl-modal-thread{
  max-height:34vh; overflow:auto; margin:0 0 11px;
  -webkit-user-select:text; user-select:text; cursor:auto;
}
.rvl-modal-thread .rvl-body{ margin:0 0 9px }
.rvl-modal-ta{ -webkit-user-select:text; user-select:text; cursor:auto }
/* A REPLY BOX OPENS SHORT AND GROWS WHEN YOU GO INTO IT. Craig, 2026-09-24:
   "The reply text area height should be short upon opening of the modal
   (img3). UPON clicking inside to reply, should expand it down slightly
   (img4)." Only the REPLY box — a new comment and an edit both open on an
   empty or full box that is the whole point of the window, and starting those
   short would make you resize before you could read what you were writing.

   IT GROWS DOWNWARD AND THE WINDOW DOES NOT MOVE — the window is placed by
   `left`/`top`, so its origin is fixed and only its bottom edge travels. The
   pointer that opened the box is inside the box and stays inside it; nothing
   the press could land on moves out from under it. That is the same
   resize-on-press trap the foot row's `min-height` exists for, avoided by
   geometry rather than by a timer. */
.rvl-modal-ta.is-reply{ min-height:74px; transition:min-height .14s var(--ease, ease) }
.rvl-modal-ta.is-reply:focus{ min-height:150px }
@media (prefers-reduced-motion:reduce){ .rvl-modal-ta.is-reply{ transition:none } }
.rvl-modal-foot{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  flex-wrap:wrap; margin-top:12px; min-height:64px;
}
/* THE FOOT IS THREE STACKED BANDS, and the order is Craig's, 2026-09-24:
   "keep SAVE CHANGES larger button, 100% width" · "EDIT RESOLVE CLOSE same
   size buttons inline across bottom of Comment modal" · "move CANCEL to text
   button below SAVE CHANGES".
     1  the primary, full width
     2  the inline row — equal-width, `flex:1 1 0` so two buttons and three
        both divide the width rather than sizing to their labels
     3  CANCEL, a text button, LAST in DOM order per his standing rule */
.rvl-modal-btns{ display:flex; flex-direction:column; align-items:stretch; gap:8px }
.rvl-modal .rvl-primary{ width:100%; min-width:0 }
.rvl-modal-row{ display:flex; align-items:stretch; gap:8px }
.rvl-modal-row > *{ flex:1 1 0; min-width:0 }
/* A TEXT BUTTON, not a bordered one — it is the way out, not an action. */
/* CANCEL IS THE ONE THAT STAYS TEXT. It is the way out, not an action, and
   Craig asked for it as "a text button below SAVE CHANGES" — the resting
   ground the other chips just gained would make it look like a fifth action. */
.rvl-modal-cancel.rvl-chip{
  box-shadow:none; background:none; align-self:center;
  color:var(--rvl-p-ink3, rgba(30,31,35,.64));
}
.rvl-modal-cancel.rvl-chip:hover{ background:none; color:var(--rvl-p-ink, #1e1f23) }

/* THE PRIMARY'S HOVER GROUND SAYS WHICH WINDOW IT IS IN. Craig: the comment
   window's larger button gets "hover bg 'success'"; the EDIT window's gets
   "hover bg gold with white text (thats our EDIT colors on portal)". */
.rvl-modal .rvl-primary:hover:not([disabled]){ background:var(--rvl-ok, #198754); color:#fff }
.rvl-modal[data-rvl-kind="edit"] .rvl-primary:hover:not([disabled]){
  background:var(--rvl-edit, #e3a52a); color:#fff;
}

/* ---- the pin, while it is being dragged ------------------------------
   Craig, 2026-09-24: "Need to be able to move my own comment, click on
   comment circle to drag it to move it." Only a pin this member wrote: a
   `grab` cursor on one nobody may move is a promise the page cannot keep. */
.rvl-pin.is-mine{ cursor:grab; touch-action:none }
.rvl-pin.is-mine:active{ cursor:grabbing }
/* While a pin is in flight nothing else on the overlay may take the pointer,
   or a fast drag hands the capture to whatever slid under it. */
.rvl-pins.is-dragpin .rvl-pin:not(.is-drag){ pointer-events:none }

/* ---- THE PANEL STAYS ON TOP OF THE DETAIL VIEW, AND LETS IT THROUGH ----
   Craig, 2026-09-24: "When zooming, the common panel should maintain on top,
   would love it to have partial transparency 0.9-ish with blur of items going
   behind it."

   ON TOP is already true by the ladder — the panel is 70 and `.zoom` is 60,
   and `.shell` is `position:static` so it creates no stacking context to trap
   the panel inside. It is RESTATED here because that is an invariant two
   unrelated files have to keep, and because what actually broke it was not
   z-order at all: the magnified image escaped its frame and painted over
   everything. That is fixed where it happens, in board.html's `.zoom-art`.

   THE GLASS IS THE PANEL'S OWN, IN EVERY STATE NOW — see `.rvl-panel`. This
   block used to declare a SECOND `body.rvl-zoomed .rvl-panel` a few rules above
   the one that ends this section, both writing `background`, and it named its
   value `--rvl-p-glass` — the same token the resting panel uses, so declaring
   that token anywhere would have set the resting alpha and the detail-view
   alpha to one value. Deleted 2026-09-25: one rule, one token, one place to
   change it. */

/* ---- THE DETAIL VIEW RUNS FULL WIDTH, AND THE PANEL IS GLASS OVER IT ----
   Craig, 2026-09-24: "When zooming, the common panel should maintain on top,
   would love it to have partial transparency 0.9-ish with blur of items going
   behind it."

   THAT REPLACES THE INSET THIS FILE SHIPPED AN HOUR EARLIER. That version
   pushed `.zoom` left by the panel's width so the panel could never cover the
   artwork — my call, not his, and he has now made the opposite one: the
   artwork goes BEHIND the panel and you read it through the glass. So the
   inset is gone, `.zoom` keeps its own `inset:0`, and the panel earns its
   place by being see-through rather than by being moved around.

   `backdrop-filter` needs a see-through background to have anything to work
   on, so the alpha and the blur are one decision, not two. */
/* .6, NOT .9. Craig, 2026-09-25: "I told you to add blur to the background
   window, and you change the opacity instead. I don't mind it being slightly
   more opaque, but you changed it significantly." The .9 predates this round
   and it is what buried the artwork in the detail view; the blur is what he
   asked for and it is already on the base rule, in every state. .5 is his own
   pasted value and stays the resting one — this is the one step up. */
body.rvl-zoomed .rvl-panel{
  z-index:var(--rvl-z-panel-zoom, 90);
  background:var(--rvl-p-glass-z, rgba(255,255,255,.6));
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
}
/* A card still has to be READ over artwork, so it keeps more of its paper than
   the panel behind it. */
body.rvl-zoomed .rvl-card{ background:rgba(255,255,255,.94) }
body.rvl-zoomed .rvl-card.is-resolved{ background:rgba(244,244,244,.94) }

/* ---- the overlay inside the DETAIL view -------------------------------
   Craig, 2026-09-24: "Comments need to display on Detail view (ZOOMED IN
   version) as well." The pins ride INSIDE `#zoomPan`, which is what carries
   the pan translate and the residual scale (board.html applyZoom), so they
   move with the artwork for free instead of being re-placed on every
   pointermove of a drag.

   THE ZOOM SURFACE IS NOT A CROSSHAIR. A left click there pans the picture
   (Craig: "Mouse click moves zoomed in view, so RIGHT-MOUSE click to add
   comment"), so the cursor must keep saying "grab", not "place a comment". */
body.rvl-on #zoomPan .rvl-pins{ cursor:default }
.zoom.is-zoomed #zoomPan .rvl-pins{ cursor:inherit }

/* ===== FOCUS — guide §23, and never removed ==========================
   board.html:79 ships a global :focus-visible at (0,1,0) that sets outline,
   offset AND border-radius:2px. Overriding only the outline leaves the
   radius behind, so every rounded control in this panel squares off on Tab
   and rounds again on blur. The radius is restated here, at (0,2,0), rather
   than merely left unmentioned. The panel's ring is the dark gold: the
   board's --accent (#e3a52a) is sub-AA on a #fcfcfc ground. */
.rvl-panel :focus-visible,
.rvl-modal :focus-visible{
  outline:2px solid var(--rvl-p-goni, #8a5f00);
  outline-offset:2px;
  border-radius:var(--rvl-radius, 6px);
}
/* NEVER A DOUBLE BORDER. Craig, 2026-09-24, of the floating window: "never do
   double border." The textarea already states focus with its own 1px gold
   edge (`.rvl-ta:focus`), so the ring above landed a SECOND gold line 2px
   outside it — two borders on one box. The box keeps its own; the ring is
   suppressed on it and nowhere else, so every other control in the window
   keeps a visible focus state. */
.rvl-ta:focus-visible{ outline:none }
.rvl-filter:focus-visible{ border-radius:999px }
.rvl-pins :focus-visible,
.rvl-fab:focus-visible{
  outline:2px solid var(--rvl-accent, #e3a52a);
  outline-offset:2px;
}
.rvl-pin:focus-visible{ border-radius:50% }

/* ===== REDUCED MOTION ================================================
   Craig gets motion sick. There is no transform and no animation anywhere in
   this file and there never will be; this block exists so anything added
   later inherits the answer instead of re-deciding it. board.html:3910
   already carries a universal !important version of the same rule. */
@media (prefers-reduced-motion: reduce){
  .rvl-panel, .rvl-pins, .rvl-pin, .rvl-dot, .rvl-fab, .rvl-modal{
    transition:none !important; animation:none !important;
  }
}
