/* comment-panel.css

   What the comment panel is drawn from : the layer that dims the gallery, the centred sheet over
   it, the thin header carrying a design's name and the cross, the strip of that design's three
   pictures, the tiles one page of comments is drawn as, the two pagers around them and the writing
   box at the foot of the scrolling column.

   Nothing in this file may be written as a screen-width condition, and that is not a preference of
   this file's : every width rule on this site lives in responsive.css, in the width blocks that
   file already carries, so the phone's overrides for this panel are written there beside every
   other narrow-screen rule rather than here. A second file holding widths is a second place a
   breakpoint has to be changed, and the copy that gets missed contradicts the other at a width
   nobody thinks to look at.

   ONE DECLARATION HAS TO SERVE EVERY WIDTH FROM THE PHONE OVERRIDE UPWARDS, and it is the panel's
   own. This site is designed around three screen widths and each of them opens exactly one block,
   so there is no breakpoint left to spend on a laptop : the sheet is twelve hundred pixels wide or
   the window less a margin, whichever is the smaller, which is the right answer at every width in
   between with no condition anywhere.

   The layer numbers this panel stacks at are not invented here either. They come from the scale
   written at the top of responsive.css, which lists every layer this site has : the dimmed backdrop
   sits on the number that file gives a panel backdrop and the sheet on the one it gives a panel, so
   this panel stacks exactly where the drawer and the filter sheet already do.

   EVERY COLOUR IS THE PALETTE'S AND NOT ONE OF THEM IS NEW. They reach the rules below through six
   properties declared once on the panel and re-pointed once for the light theme, which is the
   arrangement the filter sheet already uses for its own background : a colour two rules must carry
   identically is one colour, and a second copy of it is the copy somebody edits on its own. It also
   means the theme is settled in one rule instead of in a light-mode counterpart to every rule in
   this file - and one theme correct with the other quietly wrong, with nothing on screen saying so,
   is the shape of failure this site has already shipped three times.

   This file is linked before responsive.css, as every stylesheet on this site is, so that the width
   rules keep the last word without needing to shout.
*/

/* --- The two boxes the panel is made of : the layer that dims the page, and the sheet itself --- */

/* Both are drawn by the class the shared panel controller writes onto them and by nothing else, and
   both are declared "not drawn" first.

   THE CLOSED STATE HAS TO BE DECLARED HERE, and that is worth saying because the markup already
   says it a second way. Each of these two boxes used to carry a hidden attribute, which works
   through a rule the browser itself supplies - and any display declared by a stylesheet of ours
   outranks the browser's whatever the selector, so the day those attributes come off, a file that
   had said nothing about the closed state would draw an unstyled panel and a black sheet over the
   whole gallery. The attributes are off now and this pair is what keeps both boxes out of sight. */
.gem-comment-backdrop {
  display: none;
}

/* The same dim as the navigation drawer's own layer, written as the same value rather than as a
   palette entry : it is not a colour anything is drawn in, it is a black sheet at half strength,
   and the site has exactly one of those already. */
.gem-comment-backdrop.is-open {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 1100;
  background-color: rgba(0, 0, 0, 0.5);
}

/* The six colours this panel is drawn from, each one a pair the palette already holds, chosen once
   here and re-pointed once below for the light theme. Read as :

     surface   the sheet's own face, and the band the writing box carries so the tiles do not show
               through it as they scroll underneath
     inset     a box drawn ON that face - a tile, a page number, a button, a field, the frame a
               picture is fitted inside
     edge      every hairline the panel draws
     muted     everything that is not the comment itself : the instant, the edited marker, the
               sentence left where a removed comment was, the counter, the empty line, the gap in a
               pager
     accent    the ring on the page being read, the filled dot, and the focus ring
     refusal   the counter once there is no room left, and nothing else

   Declared on the panel rather than on the open panel so that they are there whatever state it is
   in, and inherited by everything inside it. */
.gem-comment-panel {
  --comment-panel-surface: var(--surface-dark);
  --comment-panel-inset: var(--bg-dark);
  --comment-panel-edge: var(--border-dark);
  --comment-panel-muted: var(--muted-dark);
  --comment-panel-accent: var(--accent);
  --comment-panel-refusal: var(--error-dark);

  display: none;
}

body.light-mode .gem-comment-panel {
  --comment-panel-surface: var(--surface-light);
  --comment-panel-inset: var(--bg-light);
  --comment-panel-edge: var(--border-light);
  --comment-panel-muted: var(--muted-light);
  --comment-panel-accent: var(--accent-light);
  --comment-panel-refusal: var(--error-light);
}

/* The open sheet : a centred box over the dimmed gallery, and not a drawer.

   THE WIDTH IS THE ONE DECLARATION THIS WHOLE FILE EXISTS TO GET RIGHT. Twelve hundred flat
   overflows a thirteen-hundred-pixel laptop window once the document's scrollbar and any margin
   either side are counted, and the site's three screen widths are each spoken for, so the fix
   cannot be a fourth. Said as "the smaller of twelve hundred and the window less a margin" it needs
   no condition at all : it is twelve hundred on a desktop, it is the window less thirty-two pixels
   on everything between the phone override and there, and it never touches either edge.

   The height is the same idea in the other direction. All four edges are pinned and the margins are
   left automatic, which is what centres the box ; the sheet is then as tall as what is in it and no
   taller, up to the ceiling beside it. A panel holding three comments is three comments tall and a
   panel holding fifty is the window less a margin, with the column inside it scrolling.

   Below the header everything is ONE scrolling column, which is why this box is a column and why
   the two rules under it divide it into a header that never moves and a body that does.

   The clipped overflow is what makes the rounded corners mean anything : without it the first tile
   of a long page is drawn square over the top corners of the sheet it is inside. */
.gem-comment-panel.is-open {
  display: flex;
  flex-direction: column;
  position: fixed;
  inset: 0;
  margin: auto;
  z-index: 1200;
  width: min(1200px, calc(100% - 32px));
  height: fit-content;
  max-height: calc(100% - 32px);
  overflow: hidden;
  border: 1px solid var(--comment-panel-edge);
  border-radius: 12px;
  background-color: var(--comment-panel-surface);
}

/* --- The header : the design's name, and the way out --- */

/* Thin, and outside the scrolling column on purpose : this panel is opened from a gallery of
   near-identical cards, so which design was tapped has to be readable before anything has loaded
   and has to stay readable after somebody has scrolled to the fiftieth comment.

   Its own height is the close cross's, which is the size a finger needs, so nothing here sets one. */
.comment-panel-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 4px 0 12px;
  border-bottom: 1px solid var(--comment-panel-edge);
}

/* A design's name may be long and is cut short rather than wrapped. Wrapping would make the header
   two lines tall on some designs and one on others, so the cross - the way out of a box drawn over
   the whole page - would sit at a different height depending on which stone was tapped.

   The floor on the width is what makes the cut happen at all : a flex item refuses by default to be
   narrower than its own contents, so without it a long name widens this box, pushes the cross off
   the end of the row and is never cut. */
.comment-panel-title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-weight: 600;
}

/* A button inherits none of the sheet around it - the browser puts a face, a border and a text
   colour of its own on it - so the four are written out, exactly as the gallery's own controls do
   it. The floors are on this element and never on a box around it, because the tap is delivered to
   this element's own border box. */
.gem-comment-panel-close {
  flex: 0 0 auto;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  line-height: 1;
  cursor: pointer;
}

/* Every control this panel holds, for the keyboard alone. A panel drawn over the whole page takes
   the focus into itself and holds it there, so somebody travelling it with a keyboard has nothing
   else on screen to orient against and has to be able to see where they are. Held inside each
   control's own box by the negative offset, so two neighbouring rings can never overlap. */
.gem-comment-panel :focus-visible {
  outline: 2px solid var(--comment-panel-accent);
  outline-offset: -2px;
}

/* --- The one scrolling column --- */

/* Everything below the header, and the only thing in this panel that scrolls. The pictures scroll
   away as somebody reads ; once they are reading comments the whole height of the panel is
   comments, which is the arrangement that was asked for.

   Side padding only. Space at the foot would sit between the sheet's edge and the writing box
   pinned to it, and a strip of panel with tiles sliding through it is exactly what that box's own
   background exists to prevent - the same reason the filter sheet pads only its sides.

   The containment is asked for in its physical spelling on purpose : the spelling that follows the
   writing direction is not implemented in the browser this line exists for. Without it a drag
   continued past the last comment scrolls the gallery behind the panel. */
.comment-panel-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  padding: 0 12px;
}

/* --- The two controls above the pictures --- */

/* Centred over the strip with a gap between them, and wrapping rather than overflowing : a row that
   overflowed would put the second control off the side of a phone with nothing to scroll it back.

   The space above and below is the strip's own, which is what makes the row read as belonging to the
   pictures rather than to the header over it. */
.comment-share-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin: 12px 0;
}

/* THE SECOND CONTROL IS AN ANCHOR, AND AN ANCHOR IS A RUN OF TEXT RATHER THAN A BOX. The two floors
   in the rule above - the ones every control in this panel is given because a thumb has to hit it -
   reach no inline element at all, so this is what makes that control a box in the first place. The
   centring puts its words in the middle of the target rather than on its top edge, and the underline
   goes because it is drawn as one of this panel's two controls rather than as a sentence with a link
   in it.

   THE RULE UNDER IT PUTS BACK WHAT THIS ONE OUTRANKS, AND IT IS NOT A TIDYING-UP. The script takes
   this control out of the panel with the browser's own hidden attribute when the catalogue holds no
   address for the design, exactly as it does with a picture - and any display a stylesheet of ours
   declares outranks the browser's rule for that attribute whatever the selector. Said once and left
   there, this control would be drawn anyway, with no address on it and nowhere to go. The gallery's
   own stylesheet answers the same trap the same way for the count on a card. */
.comment-share-open {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

.comment-share-open[hidden] {
  display: none;
}

/* --- The design's three pictures --- */

/* Side by side and centred, in the order the markup lists them : the diagram, the Gem Cut Studio
   render, the graph. On a phone this same strip becomes one picture at a time under the thumb, and
   that is written in the width block of the shared stylesheet rather than here.

   They shrink together rather than overflowing on a window between the phone override and a
   desktop : three three-hundred-pixel boxes and their gaps come to nine hundred and thirty-two, so
   below about a thousand-pixel window they are drawn a little smaller than three hundred and stay
   square, which is the same answer the panel's own width gives and needs no condition either. */
.comment-picture-strip {
  display: flex;
  justify-content: center;
  gap: 16px;
  margin: 12px 0;
}

/* Each picture in a square box, fitted WHOLE and never cropped. A diagram is cutting instructions
   and the ones on the site are not square yet, so a box that filled itself would cut the
   instructions off at the sides ; fitted whole it is drawn at its true proportions with empty bands
   above and below, which stop appearing the day the pictures themselves are square.

   The height stays automatic and the ratio is written bare beside it, both for the reason the
   gallery's own picture records : a ratio is ignored outright when both sizes are fixed, and pairing
   the ratio with the keyword that means "the file's own shape" would let the box snap to the
   picture's proportions the instant it arrives, which is the jump a declared ratio exists to
   prevent. So the box is three hundred by three hundred before a single byte of it has been
   fetched.

   No display is declared on these and that is deliberate : the script takes a picture out of the
   strip with the browser's own hidden attribute when the catalogue holds no address for it, and any
   display declared here would outrank that and draw an empty frame instead. */
.comment-picture {
  width: 300px;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  border: 1px solid var(--comment-panel-edge);
  border-radius: 8px;
  background-color: var(--comment-panel-inset);
}

/* The box the line below is drawn against, and it carries nothing else : no padding, no border, no
   colour, no size. It exists because the strip itself cannot be what that line is positioned against -
   at the phone width the strip is the box the three pictures scroll inside, and a box out of the flow
   inside a scrolling box travels with the content, so the line would sit one screen off to the left
   after a swipe to the third picture. Carrying nothing, it lets the strip's own margins pass through
   it and changes not one pixel of what is drawn. */
.comment-picture-box {
  position: relative;
}

/* THE LINE SAYING THE LINK WAS COPIED, DRAWN OVER THE PICTURE AND OUT OF THE DOCUMENT'S FLOW. Out of
   the flow is the whole rule rather than one way of drawing it : a line put into this column makes the
   column taller for as long as it is there, so the pictures, the count, the pager and the first
   comment all move down when it appears and back up three seconds later. This site has measured
   exactly that on its own gallery - two rows of cards moved 41 pixels each way under a hand already
   reaching for one of them - and here it would be worse, because what a phone shows on opening this
   panel has been tuned to the pixel and the first comment would leave the screen and come back.

   The colour is the message class the element wears in the markup, which the script swaps for the
   refusal one when a copy did not happen. The surface behind it is this panel's own, and it is what
   makes the sentence readable : words on their own over a rendered gem are not something a person can
   read, which is the same reason the notice on a card carries a surface.

   Both margins are set to nothing because this is a paragraph, and a paragraph arrives with a margin
   of its own that would sit the line below where it was asked to be. The bottom half of that
   declaration is inert here and is written for the pair.

   Centred over the picture rather than pinned to its top, in a box whose height is the picture's. NO
   DISPLAY IS DECLARED : the script holds this line back with the browser's own hidden attribute, and
   any display declared here would outrank the browser's rule for it and leave the line on screen for
   ever - the same trap the two notes above already record. It is given no layer number either, being
   the only positioned box inside its wrapper, and a positioned box is painted after the ones that are
   not. */
.comment-picture-notice {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  margin: 0;
  padding: 10px;
  border-radius: 5px;
  background-color: var(--comment-panel-surface);
  text-align: center;
}

/* The three dots under the strip belong to the phone, where one picture is drawn at a time and they
   are the only thing saying which of the three it is. On a screen showing all three at once they
   would be saying nothing, so they are not drawn - the width block turns them back on. */
.comment-picture-dots {
  display: none;
}

/* One dot : a small round mark inside a box a thumb can actually hit.

   The two sizes are a deliberate pair. The element's own border box is the forty-four pixels a
   finger needs, because that is the box the tap is delivered to, and the padding then holds the
   painted part down to eight pixels by confining the background to the content box. The mark is
   small and the target is not, and the element itself is what grew - which matters, because the
   other way of reaching forty-four is an invisible shape stretched past the control's edges, and
   that one is invisible to every tool that measures a box, so the control goes on reporting the size
   it always had.

   The filled one is the accent, and it is a shape rather than a sentence : nothing is ever drawn on
   top of either of these. */
.comment-picture-dot {
  width: 44px;
  height: 44px;
  padding: 18px;
  border: none;
  border-radius: 50%;
  background-color: var(--comment-panel-muted);
  background-clip: content-box;
  cursor: pointer;
}

.comment-picture-dot[aria-current="true"] {
  background-color: var(--comment-panel-accent);
}

/* --- How many comments there are, and the two pagers --- */

/* The word is fixed and the number is the server's. */
.comment-count-line {
  margin: 8px 0;
  font-weight: 600;
}

/* One row of page numbers, drawn above the tiles and again below them. The two are the same rules ;
   that there are two of them is the markup's business and not this file's.

   It wraps because it has to : the widest window this pager ever offers is seven numbers, and seven
   targets a finger can hit come to more than a narrow phone's column. Wrapped, the second line is
   centred under the first ; unwrapped, the last page number would be off the side of the screen.

   A pager with nothing in it is not drawn at all. A design with a single page is given no numbers -
   one button that is already the page you are on says nothing to anybody - and an empty box with
   space above and below it would leave a gap where a reader would look for something. */
.comment-pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px;
  margin: 8px 0;
}

.comment-pager:empty {
  display: none;
}

/* Every button this panel draws, in one rule, because they are one kind of thing : a box on the
   sheet's face that a finger can hit. A button inherits none of the panel around it - the browser
   gives it a face, a border, a text colour and a font of its own - so all of those are written out.

   The floors are on the buttons themselves and never on a box around them, for the reason this site
   has written down once already : the tap is delivered to the button's own border box, and a roomy
   parent buys nothing at all. */
.comment-page-button,
.comment-share-copy,
.comment-share-open,
.comment-edit,
.comment-delete,
.comment-edit-save,
.comment-edit-cancel,
.comment-confirm-delete,
.comment-confirm-cancel,
.comment-post {
  min-width: 44px;
  min-height: 44px;
  padding: 0 10px;
  border: 1px solid var(--comment-panel-edge);
  border-radius: 6px;
  background-color: var(--comment-panel-inset);
  color: inherit;
  font: inherit;
  cursor: pointer;
}

/* Numbers of the same width whatever the digits, so a pager does not shuffle sideways as the window
   of numbers slides. Written after the rule above rather than inside it, because the shorthand there
   resets exactly this. */
.comment-page-button {
  font-variant-numeric: tabular-nums;
}

/* THE PAGE BEING READ IS MARKED BY THE ATTRIBUTE THAT ANNOUNCES IT, and that is the point of this
   rule rather than a detail of it : one mark is at once what a screen reader says and what the eye
   is shown, so there is no second class to keep in step with it. It is the decision the vote arrows
   already carry.

   Marked by a ring in the accent and by the sheet's own face rather than by a fill, and the reason
   is worth knowing before somebody tries to improve it : there is no colour in this palette that a
   number can be read on except the two surfaces it already names. The accent is a fine colour for a
   shape and an unreadable one behind a digit. So the button being read wears the panel's own face -
   it stops looking pressable, which is exactly what it is - with the accent as its edge, which is
   the same mark this site's topbar puts under the page you are on. */
.comment-page-button[aria-current="page"] {
  border-color: var(--comment-panel-accent);
  border-width: 2px;
  background-color: var(--comment-panel-surface);
  font-weight: 700;
}

/* The gap standing for the numbers between two pages. It is a page button that cannot be pressed
   and is not announced, so what is left is to stop it looking pressable : no edge, no face, and the
   muted colour everything that is not a comment is drawn in. It keeps the size of a target it is
   not, because it sits in a row of them and a hole in that row would be worse than a wide dot. */
.comment-page-button.comment-page-gap {
  border-color: transparent;
  background-color: transparent;
  color: var(--comment-panel-muted);
  cursor: default;
}

/* --- One comment --- */

/* A tile, and not a row in a list : its own face on the sheet's, its own edge around it. Fifty of
   these are drawn one under the other, and what makes them readable in a column that long is that
   each is plainly a block of its own rather than a paragraph separated from the next by space.

   The face is the one a box drawn ON the panel wears, which is a step away from the panel's own -
   so a tile reads as sitting on the sheet rather than being part of it, on both themes, with no
   second colour anywhere. */
.comment-tile {
  display: flex;
  gap: 12px;
  margin-bottom: 10px;
  padding: 10px;
  border: 1px solid var(--comment-panel-edge);
  border-radius: 8px;
  background-color: var(--comment-panel-inset);
}

/* The author's picture, in the tile's left gutter, drawn as the square it is stored as. The rounding
   that used to draw it as a circle came off on 2026-08-12, because the owner asked to see the
   picture he uploaded : every stored copy is square, and this was the only place on this site that
   drew a face as a circle at all.

   NO SIZE IS WRITTEN HERE ON PURPOSE. The page renders the width and the height onto each of these
   as attributes, out of the one constant that says how big the small stored copy is, so a size
   declared here would be a second copy of that number and the two would disagree the day it moved.

   What this rule does add is the refusal to shrink : the picture is a flex item, and a flex item
   gives up width by default, so a long comment beside it would squeeze the picture out of square -
   which is the same fault the rounding was taken off to remove, reached from the other side.

   The fit stays as well, and while every stored copy is square it does nothing whatever : it is the
   guard for the day one is not, where a picture cropped to its box is a better answer than one
   stretched out of its proportions. */
.comment-avatar {
  flex: 0 0 auto;
  object-fit: cover;
}

/* WHAT FIFTY ANIMATED AUTHOR PICTURES COST IN ONE OPEN PANEL : NOTHING MEASURABLE. Measured on
   2026-08-12 in a browser, against this panel drawn and holding a full page of fifty tiles, so what
   stands here is the answer rather than the question. It was worth measuring because both stored
   copies of an account's picture animate when the picture somebody uploaded animated, and nowhere
   else on this site is more than one of them drawn at a time.

   Fifty different animated pictures, twelve frames apiece at 100ms a frame, made by this site's own
   encoder, one per tile, sampled for four seconds at each of two widths - each against a control
   taken on the same page a moment earlier with the panel shut and nothing animating. Median
   interval between the frames the browser actually managed :

     360 wide    nothing animating 17.80ms    fifty animated 17.70ms    worst 18.20 / 18.50ms
     1280 wide   nothing animating 17.80ms    fifty animated 17.70ms    worst 18.10 / 18.30ms

   Ten samples over the whole reading, 225 to 227 intervals apiece, and NOT ONE FRAME MISSED
   anywhere - nothing above 18.5ms against a threshold of 25. A panel with fifty animated pictures
   in it is indistinguishable from the same page with none.

   Taken again deliberately unfairly, with the deferring hint stripped off and the tiles packed so
   that every one of the fifty was loaded and in view at once - which this panel never does, since a
   tile carrying a name, a date and a paragraph cannot fit fifty into a screen - fifty simultaneous
   animations read 17.80ms against the same 17.80ms control at the wide width, and twenty of them
   17.70ms at the narrow one. Still not one frame missed.

   SO NOTHING WAS CHANGED FOR IT, and neither lever was reached for. The first is already in place
   and was measured effective : the tile's picture carries the two attributes that decode it off the
   main path and defer the ones off screen, and with a picture written onto all fifty elements only
   8 of them at the narrow width and 16 at the wide one ever loaded at all. The second - stopping
   off-screen tiles being rendered at all, with a placeholder size so the scrollbar does not jump -
   is what to reach for first if a later reading ever disagrees with this one. A third stored copy
   holding a still frame comes only after that and is a change of scope rather than a fix.

   An earlier reading of the same question, taken before this panel existed and against a stand-in
   built under these same names, came back the same way. Its three qualifications are answered here:
   the panel is the real one now, the fifty-in-view sample is the one it said it could not take, and
   the pictures are still made rather than uploaded because no account in this checkout has ever
   uploaded one that moves. */

/* An account with no picture of its own is drawn with the default, and the page carries one of
   those per theme because a theme is settled here by a class and no script running. Both arrive in
   the tile revealed and this pair is what draws whichever belongs.

   Written as "the other theme's is not drawn" twice, each half weighing nothing beyond the class it
   names, so that neither of them can outrank the browser's own rule for a hidden element. Said the
   ordinary way round - one hidden, the other put back - the rule putting one back would be the
   heavier of the two and would reveal a picture the script had taken out of the tile. */
:where(body:not(.light-mode)) .comment-avatar-on-light {
  display: none;
}

:where(body.light-mode) .comment-avatar-on-dark {
  display: none;
}

/* Everything that is not the picture. The floor on the width is the load-bearing half : without it
   this box refuses to be narrower than its own contents, and one long comment would push the tile,
   and with it the panel, wider than the screen. */
.comment-tile-body {
  flex: 1 1 auto;
  min-width: 0;
}

.comment-author {
  font-weight: 600;
}

/* The instant, and the note saying the words above it have been changed since. Both are drawn in
   the colour everything secondary on this panel is drawn in and at a size below the name's, so the
   line reads as "who, and when" with the name first.

   The marker's two wordings are drawn identically and only the words differ - and the words are the
   page's, not this file's. */
.comment-date,
.comment-edited {
  margin-left: 8px;
  color: var(--comment-panel-muted);
  font-size: 0.8rem;
}

.comment-edited {
  font-style: italic;
}

/* A COMMENT'S OWN WORDS, AND THE TWO DECLARATIONS THAT ARE THE WHOLE REASON THIS RULE EXISTS.

   The first keeps the line breaks somebody typed, without a single substitution : the text arrives
   as the characters it was written as and nothing anywhere turns a line break into markup, so this
   is the only thing that makes a comment written in paragraphs read as paragraphs.

   The second breaks a word longer than the panel, and it is NOT either of the two values everybody
   reaches for first. Both of those look like they mean the same thing and do something different :
   they let a long word be broken while still working out this box's smallest possible width as
   though nothing were broken - so inside a flexible or gridded box, and a tile is one, the box
   refuses to shrink and one two-thousand-character word with no space in it pushes the tile, the
   panel and the document itself wider than the screen. This value is the one that also lets the
   box's smallest width be small.

   The floor beside them is the belt to that brace : a flexible child's own minimum is its content
   by default, and the two above are only free to work once it is not. */
.comment-text {
  margin: 6px 0 0;
  min-width: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* What is left where a comment was taken down. THE FACE, THE NAME AND THE INSTANT ARE DELIBERATELY
   KEPT, and the alternative - a bare grey line in place of the whole tile - was considered and
   turned down : a conversation read a week later is mostly about who was answering whom, and a
   thread with three of its tiles replaced by anonymous rules is a thread nobody can follow. What
   changes is the sentence, drawn muted and italic so that it reads as a note ABOUT the comment
   rather than as the comment. The sentence itself is the page's. */
.comment-tile.is-removed .comment-text {
  color: var(--comment-panel-muted);
  font-style: italic;
}

/* The two controls somebody who may change a comment is offered, and the question that replaces
   them when the bin is pressed. Both sit at the foot of the tile and against its right edge, which
   is where a control belonging to the block above it belongs and where it is furthest from the next
   tile's own.

   Both are drawn by one rule because they are one row in two states, and neither of them is drawn
   over anything : the question takes the controls' place inside the tile it was asked in. */
.comment-controls,
.comment-confirm {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 8px;
}

/* The question is drawn in the colour this panel refuses in, and centred over the space its two
   answers leave. Asked in the same colour as everything around it and sitting hard against the left
   of a row whose answers are both at the right, it read as a label stuck to the first button rather
   than as a question about destroying something, which is what the owner saw on 2026-08-12 reading
   the finished panel.

   The colour is the panel's own refusal property rather than a colour of its own, so it is the red
   of whichever theme is in force and this rule needs no light-theme counterpart : the property is
   re-pointed once, at the panel, and every rule in this file reads it. It is the same red the
   counter takes when there is no room left to type.

   WHAT IS CENTRED IS THE QUESTION INSIDE THE SPACE THE BUTTONS LEAVE, NOT INSIDE THE WHOLE ROW, and
   that is the decision rather than an oversight. Centring it on the row itself needs either the two
   answers moved or the question taken out of the flow, and both were turned down : a question drawn
   over its own two answers on a narrow screen is worse than one sitting a little left of true
   centre. Taking the space left over is what the auto margin that stood here did by another route,
   so neither answer moved when this was written - read at 1280 and at 360 on both themes, Delete
   and Cancel keep the left edges they had. */
.comment-confirm-question {
  flex: 1 1 auto;
  text-align: center;
  color: var(--comment-panel-refusal);
}

/* Rewriting a comment happens where the comment is : this box takes the width the words had, inside
   the tile, with the row under it taking the place the controls had. Nothing here is drawn over the
   panel, which is what lets the escape key keep one meaning. */
.comment-edit-box {
  margin-top: 6px;
}

/* --- The writing box at the foot of the column --- */

/* STICKY, AND NEVER FIXED, and this is the single most important declaration in the file after the
   panel's own width. When a phone raises its on-screen keyboard it shrinks only the part of the page
   the visitor is looking through and leaves the page itself the height it was, on the browser that
   matters most here - so a box pinned to the bottom of the page ends up underneath the keyboard,
   and the visitor types a comment they cannot see into a box they cannot reach. A sticky box is part
   of the column : it gives up its pin at the end of the content it belongs to, and the browser pans
   it into view with everything else when it scrolls the focused field into sight.

   It carries the sheet's own face for the reason the filter sheet's pinned rows do : a transparent
   pinned band shows fifty tiles sliding underneath it. The hairline above it is what says the band
   is a band : with the face alone, the tile passing behind it is cut off in mid-sentence at a line
   nothing draws, which reads as a comment that has been clipped rather than as a box sitting over
   it.

   READ ON A REAL HANDSET ON 2026-08-12, WITH THE KEYBOARD UP, AND IT HELD : tapping the box raised
   the keyboard and the box stayed on the screen with its counter and its Post button ; the comments
   were then scrolled above it with the keyboard still raised and the box stayed where it was ;
   posting made nothing jump ; and dismissing the keyboard left nothing misaligned. No probe on a
   desktop can take that reading, because the property that makes a browser shrink its layout
   viewport for the keyboard is not implemented in the browser it was read in, and no headless run
   reproduces a real keyboard. An unpinned version of this box, sitting at the end of the column at
   the phone width, was written and ready to be applied if that reading had come back badly, and it
   was deliberately not applied. So the answer is here rather than the question, and there is
   nothing left to find out by replacing this with a fixed position. */
.comment-composer {
  position: sticky;
  bottom: 0;
  padding: 10px 0;
  border-top: 1px solid var(--comment-panel-edge);
  background-color: var(--comment-panel-surface);
}

/* The box somebody types into, and the one that replaces a tile's words while they rewrite it. One
   rule, because they are the same box in two places, counted by the same counter and refused by the
   same server.

   The inherited font is doing two jobs. A field is given a font of the browser's own choosing at
   about thirteen pixels, which is small to type two thousand characters into ; and below sixteen a
   phone zooms the page in the moment the field takes focus and leaves it zoomed, with the layout
   the visitor was reading now wider than the screen. Inheriting the page's own font answers both,
   at every width, which is why no width-conditional rule is needed for this one - the fields that
   do need one are the toolbar's, which carry a fixed height this box does not have. */
.comment-composer-field,
.comment-edit-field {
  width: 100%;
  min-height: 44px;
  padding: 8px;
  border: 1px solid var(--comment-panel-edge);
  border-radius: 6px;
  background-color: var(--comment-panel-inset);
  color: inherit;
  font: inherit;
  resize: vertical;
}

/* The counter at one end and the button at the other, in both places a comment is written. */
.comment-composer-foot,
.comment-edit-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 6px;
}

/* How much room is left, always shown and starting at the whole allowance. Digits of one width, so
   the button beside it does not shuffle sideways as the number shortens.

   THE COLOUR AT NOTHING LEFT IS DECLARED HERE AND THE SCRIPT SETS ONLY THE CLASS. What red is
   belongs to the palette, and a colour written onto an element from a script outranks every rule a
   stylesheet could aim at it. */
.comment-counter {
  margin-right: auto;
  color: var(--comment-panel-muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}

.comment-counter.is-nothing-left {
  color: var(--comment-panel-refusal);
}

/* THE REFUSAL LINE HAS NO RULE IN THIS FILE, AND THAT IS THE DECISION RATHER THAN AN OMISSION. Both
   places one is drawn already wear this site's own refusal class, which gives them the red of
   whichever theme is on, centres the sentence and puts space under it. That class won a specificity
   argument once already, recorded in the file that defines it, and a third selector aimed at the
   same element from here is exactly how that argument gets re-opened by somebody who has not read
   it. A refusal inside this panel reads like every other refusal on this site, which is the point. */

/* --- The two states the whole panel can be in --- */

/* A page of comments is on its way. The part of the panel that is about to be replaced goes pale :
   the count, the two pagers and the tiles. It is visible on the very first opening, when there are
   no tiles yet, because the count above them is written before a single request leaves.

   The writing box is deliberately left alone. Nothing about fetching a page stops somebody
   finishing the sentence they were typing. */
.gem-comment-panel.is-loading .comment-count-line,
.gem-comment-panel.is-loading .comment-pager,
.gem-comment-panel.is-loading .comment-tile-list {
  opacity: 0.45;
}

/* One of the three changing requests is open. The button that started it goes pale and says so
   under the pointer, and it is NOT disabled - the mark is an attribute on the panel for exactly
   that reason : a disabled button loses the focus, so somebody who pressed Post with a keyboard
   would be thrown back to the top of the panel. */
.gem-comment-panel[data-comment-in-flight] .comment-post,
.gem-comment-panel[data-comment-in-flight] .comment-edit-save,
.gem-comment-panel[data-comment-in-flight] .comment-confirm-delete {
  opacity: 0.6;
  cursor: progress;
}

/* --- The three sentences that stand where something else would be --- */

/* What a design nobody has commented on says, the invitation somebody with no session is given, and
   the sentence for an account whose address is not confirmed. All three are one line of secondary
   text where a page of tiles or a writing box would otherwise be, so all three are drawn the same
   way. Every one of the sentences is the page's own value ; not one of them is written here.

   No display is declared on any of them : exactly one of the three is revealed at a time and the
   other two are held back by the browser's own rule for a hidden element, which anything written
   here would outrank. */
.comment-empty,
.comment-sign-in-invitation,
.comment-confirm-address {
  padding: 12px 0;
  color: var(--comment-panel-muted);
  text-align: center;
}
