/* bench.online — same look as the old inline block, now a cacheable file.
   Served with a far-future cache once fingerprinted; until then it is one
   request instead of 60 lines re-sent inside every HTML response. */

:root { color-scheme: dark; --ink:#ddd; --bg:#111; --dim:#777; --cyan:#40c8d8; }
*, *::before, *::after { box-sizing:border-box; }

body { background:var(--bg); color:var(--ink);
       font:16px/1.5 Monaco,ui-monospace,Menlo,monospace;
       margin:0; min-height:100vh; display:flex; flex-direction:column;
       overflow-x:hidden; }

header { padding:14px 18px; display:flex; justify-content:space-between; }
header a { color:var(--ink); text-decoration:none; }
header a:hover { text-decoration:underline; }
.hl a + a { margin-left:22px; }

main { flex:0 1 auto; padding:0 18px 24px; }

/* ---------------------------------------------------------------- bench */

#benchwrap { display:flex; flex-direction:column; align-items:center; }
#stage { position:relative; width:100%; height:80vh; overflow:hidden;
         touch-action:manipulation;
         /* Spam-clicking used to drag-select the image and flash it blue.
            Scoped to the stage on purpose — /fyi is a reading room and its
            text must stay selectable. */
         user-select:none; -webkit-user-select:none;
         -webkit-touch-callout:none;          /* no iOS long-press sheet */
         -webkit-tap-highlight-color:transparent; }
#stage img { pointer-events:none; }           /* clicks land on the stage */
#stage::selection, #stage ::selection { background:transparent; }
#stage img { position:absolute; top:50%; left:50%;
             max-width:96vw; max-height:78vh;
             transform:translate(calc(-50% + var(--dx,100vw)), -50%);
             will-change:transform; }
#stage img.slide { transition:transform .25s ease; }
.caption { margin-top:8px; color:#999; text-align:center; max-width:80ch;
           min-height:1.5em; }

/* ----------------------------------------------------------------- forms */

form.stack { display:flex; flex-direction:column; gap:12px;
             width:min(90vw,420px); margin:24px auto; }
input, textarea { background:#1c1c1c; color:var(--ink); border:1px solid #333;
                  padding:8px; font:inherit; }
button { background:var(--ink); color:var(--bg); border:0; padding:8px 16px;
         font:inherit; cursor:pointer; }
.muted { color:var(--dim); }

/* ------------------------------------------------------------------- fyi */

.prose { max-width:80ch; padding:24px 0; color:var(--cyan); }
.prose p { margin:0 0 18px; }
.prose b { color:#fff; }
.prose a { color:inherit; text-decoration:none; }
#fyiwrap { display:flex; width:100%; align-items:flex-start; }
#fyiwrap .prose { margin:0 auto; transition:all .4s ease; }
#reader { flex:0 0 0px; max-width:0; opacity:0; overflow:hidden;
          transition:all .4s ease; color:var(--ink); padding-top:24px; }
#fyiwrap.split .prose { margin:0; flex:0 0 47%; max-width:47%; }
#fyiwrap.split #reader { flex:0 0 53%; max-width:53%; opacity:1;
          padding-left:24px; border-left:1px solid #2a2a2a; overflow:visible; }
#reader img { max-width:100%; max-height:70vh; width:auto; height:auto;
              display:block; margin:12px 0; }
.srcbar { color:var(--dim); word-break:break-all; margin-bottom:12px; }
#authbox { margin-top:24px; border-top:1px solid #2a2a2a; padding-top:12px; }
.disc { margin-top:24px; border-top:1px solid #2a2a2a; padding-top:12px;
        color:var(--dim); font-size:13px; }

/* ----------------------------------------------------------------- admin */

/* Amendment 8A (1 of 3). Was `width:min(96vw,760px)`, which over-constrained
   the row: main is padded 0 18px with border-box, so at a viewport V the
   containing block is V-36 px while the row demanded min(0.96V,760). The
   auto margins on an over-constrained block resolve to 0 rather than
   centring, so the row started flush at x=18 and ran 18-0.04V px past the
   viewport for every V < 450 — 2.0 px at 400, 5.2 px at 320, measured and
   reproduced. width:100% fills the content box exactly; #adminwrap already
   caps the column at 760 px and max-width keeps that cap if .row is ever
   used outside it. */
.row { display:flex; gap:16px; align-items:flex-start;
       border-top:1px solid #2a2a2a; padding:14px 0;
       width:100%; max-width:760px; margin:0 auto; }
.row img { max-width:200px; max-height:150px; }
/* Amendment 8A (2 of 3). The Amendment 7(a) card label is a 32-hex token
   with no break opportunity in it. The card's text column is only ~91 px
   wide at a 320 px viewport while the token's intrinsic width is 307.25 px
   at 16 px Monaco, so without this the label alone overflows by ~221 px
   (measured) and Amendment 7(a) is unshippable. `anywhere`, not
   `break-word`: only `anywhere` also lets the token shrink the flex item's
   min-content contribution, which is what stops the row itself from being
   pushed wide. */
.pid { overflow-wrap:anywhere; }
.row form { display:inline; }
#adminwrap { max-width:760px; margin:0 auto; }
.pager { margin:12px 0; color:var(--dim); }
.pager a { color:var(--ink); margin:0 6px; }
.pager b { color:var(--cyan); margin:0 6px; }

#editor { display:none; position:fixed; inset:0; z-index:50;
          background:rgba(0,0,0,.88); padding:2vh 2vw;
          flex-direction:column; align-items:center; }
#editor.show { display:flex; }
#editor .tools { display:flex; gap:10px; flex-wrap:wrap; margin-bottom:10px; }
#editor .tools button.on { outline:2px solid var(--cyan); }
#ecanvas { max-width:96vw; max-height:82vh; width:auto; height:auto;
           display:block; cursor:crosshair; touch-action:none; }

/* ------------------------------------------------------------- utilities */

/* Amendment 8A (3 of 3). Lets bench.html carry its one h1 without putting a
   heading on top of a full-bleed image stage. NOT display:none and NOT
   visibility:hidden — both remove the element from the accessibility tree,
   which is the opposite of the point. clip-path:inset(50%) rather than the
   legacy clip:rect(): clip is deprecated and its interaction with
   position:absolute is what made the old recipe fragile. white-space:nowrap
   stops a 1px box from wrapping the text into a tall invisible column that
   some engines still expose to the caret. */
.visually-hidden { position:absolute; width:1px; height:1px; margin:-1px;
                   padding:0; border:0; overflow:hidden; white-space:nowrap;
                   clip-path:inset(50%); }

@media (prefers-reduced-motion: reduce) {
  #stage img.slide { transition:none; }
  #fyiwrap .prose, #reader { transition:none; }
}
