/* ============================================================
   Markdown To — the playground  (site/app/index.html)

   The workbench of the same publication. ../styles.css loads
   first and carries the whole system — the typography, the
   vermillion, the tokens, the inked plate — and this file adds
   only the bench: a control rail, two panes, and the status line
   between them.

   Light is the primary design; the dark block at the end is the
   automatic prefers-color-scheme variant, derived from it. Every
   token used here is one ../styles.css already defines, so a
   value tuned there stays tuned here.

   Two rules govern the layout:

     · The page never scrolls sideways. The editor scrolls inside
       its textarea, the rendered document scrolls inside its
       iframe, and the rail wraps.
     · The panes are side by side from 900px and stacked below it,
       where a segmented control chooses which one is on screen —
       two half-width panes on a phone would be two useless panes.

   No arrow glyphs: the subset fonts have none.
   ============================================================ */

/* ------------------------------------------------------------
   0. Bench-only tokens
   ------------------------------------------------------------ */
:root {
  /* The editor's metrics live in variables because the gutter has
     to agree with the textarea to the pixel — one line-height,
     one font-size, one top padding, read by both. */
  --ed-size: 0.8rem;
  --ed-line: 1.75;
  --ed-pad-y: 1rem;
  --ed-gutter: 3.1rem;

  /* The bench runs wider than the publication's --wide (74rem).
     It is not a column of prose: the rendered pane has to clear
     44rem on its own, because that is the width at which the
     renderers lay a board out as columns rather than stacking it —
     and a playground for a board format that cannot show a board
     side by side with its source has missed the point. The topbar
     and the colophon are widened to match so the page still reads
     as one measure. */
  --bench: min(100%, 92rem);

  /* A resolved severity palette, matching specs/specs.css. */
  --sev-ok:    #2f6a3f;
  --sev-warn:  #8a5f0e;
  --sev-err:   var(--acc);
  --tint-ok:   #eef5ef;
  --tint-warn: #faf3e6;
}

/* The bench is a fixed-height application surface, not an
   article: the panes fill what is left of the viewport rather
   than growing a page that scrolls past them. */
.app { min-height: 100dvh; display: flex; flex-direction: column; }
.app .foot { margin-top: auto; padding-top: clamp(1.6rem, 3vw, 2.4rem); }

.app .topbar__in,
.app .foot__rule { max-width: var(--bench); }

.bench {
  width: 100%;
  max-width: var(--bench);
  margin-inline: auto;
  padding: clamp(1.4rem, 3.4vw, 2.6rem) clamp(1rem, 4vw, 2.5rem) clamp(1.6rem, 3vw, 2.4rem);
  display: flex;
  flex-direction: column;
  gap: clamp(.9rem, 1.8vw, 1.25rem);
}

/* ------------------------------------------------------------
   1. Head
   ------------------------------------------------------------ */
.bench__head { max-width: 54rem; }
.bench__title {
  font-size: clamp(2rem, 1.3rem + 2.6vw, 3.1rem);
  line-height: 1.02;
  letter-spacing: -.024em;
  font-weight: 400;
  text-wrap: balance;
}
.bench__lede {
  margin-top: .75rem;
  max-width: 46rem;
  font-size: .98rem;
  line-height: 1.55;
  color: var(--ink-2);
}
.bench__lede em { font-style: italic; color: var(--ink); }

/* ------------------------------------------------------------
   2. Control rail
   ------------------------------------------------------------ */
.rail {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .7rem 1.1rem;
  margin-top: clamp(.4rem, 1.4vw, .9rem);
}
.rail__set { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.rail__set--end { margin-left: auto; }
.rail__lbl {
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* the four template buttons, as one segmented control */
.seg {
  display: inline-flex;
  flex-wrap: wrap;
  gap: .25rem;
  background: var(--paper-3);
  border-radius: 100px;
  padding: .26rem;
}
.seg__b {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: -.005em;
  color: var(--ink-2);
  padding: .38rem .85rem;
  border-radius: 100px;
  transition: color .18s, background .18s, box-shadow .18s;
}
.seg__b:hover { color: var(--ink); }
.seg__b[aria-pressed="true"] {
  color: var(--ink);
  background: var(--card);
  font-weight: 500;
  box-shadow: var(--shadow-s), var(--ring);
}

/* Open / Download. `.pill` is `.btn` at the rail's scale — the
   label wraps a hidden file input, which is why it is a label. */
.pill {
  position: relative;          /* holds the visually hidden file input */
  display: inline-block;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .005em;
  padding: .52rem 1.05rem;
  border-radius: 100px;
  background: var(--card);
  color: var(--ink-2);
  box-shadow: var(--shadow-s), var(--ring);
  transition: box-shadow .22s cubic-bezier(.2,.8,.3,1),
              transform .22s cubic-bezier(.2,.8,.3,1), color .2s, background .2s;
}
.pill:hover { color: var(--ink); box-shadow: var(--shadow-m), var(--ring); transform: translateY(-1px); }
.pill:has(input:focus-visible) { outline: 2px solid var(--acc); outline-offset: 3px; }
.pill input[type="file"] {
  position: absolute; width: 1px; height: 1px;
  opacity: 0; overflow: hidden; clip: rect(0 0 0 0);
}
.pill--go { color: var(--acc); background: var(--tint); }
.pill--go:hover { color: var(--acc); }

/* Present carries a mark because it is the one control on the rail
   that changes what the *page* is rather than what the file is.
   Four corner brackets, drawn — the subset fonts have no glyph for
   this and every mark on this site is a path. */
.pill--present { display: inline-flex; align-items: center; gap: .5rem; }
.pill--present[aria-pressed="true"] { color: var(--ink); background: var(--paper-3); }
.pill__i {
  width: .86em;
  height: .86em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ------------------------------------------------------------
   3. Status line — always visible, whatever the file is doing
   ------------------------------------------------------------ */
.status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .5rem .7rem;
  min-height: 2.1rem;
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .01em;
  color: var(--ink-2);
}
.sev {
  font-size: .62rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  padding: .26rem .68rem .22rem;
  border-radius: 100px;
  font-weight: 600;
  white-space: nowrap;
}
.sev--ok    { color: var(--sev-ok);   background: var(--tint-ok); }
.sev--warn  { color: var(--sev-warn); background: var(--tint-warn); }
.sev--error { color: var(--sev-err);  background: var(--tint); }
.status__spec { color: var(--ink); font-weight: 500; }
/* The jump control is a real button: it moves the caret to the
   line and column the diagnostic names. */
.jump {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: .72rem;
  color: var(--acc);
  border-radius: var(--r-xs);
  padding: .1rem .15rem;
  text-decoration: underline;
  text-decoration-color: var(--acc-line);
  text-underline-offset: .2em;
}
.jump:hover { text-decoration-color: var(--acc); }

/* ------------------------------------------------------------
   4. The pane switch (narrow screens only)
   ------------------------------------------------------------ */
.swap {
  display: inline-flex;
  gap: .25rem;
  background: var(--paper-3);
  border-radius: 100px;
  padding: .26rem;
  width: fit-content;
}
.swap__b {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: .72rem;
  color: var(--ink-2);
  padding: .4rem 1.1rem;
  border-radius: 100px;
  transition: color .18s, background .18s, box-shadow .18s;
}
.swap__b[aria-pressed="true"] {
  color: var(--ink);
  background: var(--card);
  font-weight: 500;
  box-shadow: var(--shadow-s), var(--ring);
}
@media (min-width: 900px) { .swap { display: none; } }

/* ------------------------------------------------------------
   5. The two panes
   ------------------------------------------------------------ */
.panes {
  display: grid;
  gap: clamp(.9rem, 2vw, 1.4rem);
  grid-template-columns: minmax(0, 1fr);
  /* Tall enough to work in, short enough that the hint under it
     stays on screen. dvh so a phone's collapsing toolbar does not
     leave the bottom of the board under it. */
  height: clamp(24rem, 62dvh, 44rem);
}
/* The editor column is sized backwards from the rendered pane: it
   takes what is left after the frame has enough room to draw a
   board as columns (44rem inside the renderer's own stylesheet).
   Below that the board stacks, which is the renderer being right
   about a narrow viewport, not this page being wrong. */
@media (min-width: 900px) {
  .panes {
    grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
    height: clamp(26rem, 66dvh, 48rem);
  }
}
@media (min-width: 1200px) { .panes { grid-template-columns: minmax(0, 24rem) minmax(0, 1fr); } }
@media (min-width: 1440px) { .panes { grid-template-columns: minmax(0, 30rem) minmax(0, 1fr); } }

/* Below 900px exactly one pane is on screen at a time. */
@media (max-width: 899px) {
  .panes[data-show="edit"] .pane--view,
  .panes[data-show="view"] .pane--edit { display: none; }
}

.pane {
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--r);
  background: var(--card);
  box-shadow: var(--shadow-m), var(--ring);
}
/* The source pane is inked in both schemes, like every code plate
   on this site: a dark card is what makes a file read as a file. */
.pane--edit { background: var(--plate); box-shadow: var(--shadow-m); }

.pane__bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .62rem .95rem;
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .02em;
  color: var(--ink-3);
  border-bottom: 1px solid var(--rule-soft);
}
.pane__bar--ink { color: var(--plate-dim); border-bottom-color: var(--plate-rule); }
.pane__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--plate-acc); flex: none; }
.pane__name { font-size: .62rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 500; }
.pane__meta,
.pane__tag {
  margin-left: auto;
  font-size: .6rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
}
.pane__tag {
  color: var(--ink-3);
  background: var(--paper-2);
  border-radius: 100px;
  padding: .18rem .58rem .14rem;
}

/* the editable file name, drawn as text until you touch it */
.fname {
  flex: 1 1 8rem;
  min-width: 0;
  font: inherit;
  font-weight: 500;
  color: var(--plate-fg);
  background: none;
  border: 0;
  border-radius: var(--r-xs);
  padding: .12rem .3rem;
  margin-left: -.3rem;
  transition: background .18s;
}
.fname:hover { background: var(--plate-2); }
.fname:focus { background: var(--plate-2); outline: 2px solid var(--plate-acc); outline-offset: 1px; }

/* ---------- the editor ---------- */
.ed {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
}
/* The gutter is painted under the textarea and scrolled with it
   by app.js. It is aria-hidden: the line numbers are an aid to
   the eye, and a screen reader reading "1 2 3 4" over a document
   it is already reading is noise. */
.ed__gutter {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--ed-gutter);
  overflow: hidden;
  padding: var(--ed-pad-y) .7rem var(--ed-pad-y) 0;
  font-family: var(--font-mono);
  font-size: var(--ed-size);
  line-height: var(--ed-line);
  font-variant-numeric: lining-nums tabular-nums;
  text-align: right;
  color: var(--plate-dim);
  background: var(--plate-2);
  border-right: 1px solid var(--plate-rule);
  white-space: pre;
  pointer-events: none;
}
.ed__area {
  flex: 1;
  min-width: 0;
  display: block;
  resize: none;
  border: 0;
  background: none;
  color: var(--plate-fg);
  caret-color: var(--plate-acc);
  font-family: var(--font-mono);
  font-size: var(--ed-size);
  line-height: var(--ed-line);
  font-variant-numeric: lining-nums;
  tab-size: 2;
  padding: var(--ed-pad-y) 1.1rem var(--ed-pad-y) calc(var(--ed-gutter) + .8rem);
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--plate-dim) transparent;
}
.ed__area:focus { outline: 0; }
.ed__area::selection { background: var(--plate-acc); color: #fff; }
.ed:focus-within { box-shadow: inset 0 0 0 2px var(--plate-acc); }

/* The one moment the whole page exists for: a card is dragged in
   the frame, the patch engine writes the file, and the text on
   this side changes. Without a cue it happens off the eye's beat. */
.pane--edit.is-patched .ed { animation: patched 1.05s cubic-bezier(.2,.7,.3,1); }
@keyframes patched {
  0%   { box-shadow: inset 0 0 0 2px var(--plate-acc); background: rgba(239, 113, 72, .11); }
  100% { box-shadow: inset 0 0 0 2px transparent; background: transparent; }
}

/* ---------- the rendered stage ---------- */
.stage {
  flex: 1;
  min-height: 0;
  width: 100%;
  border: 0;
  display: block;
  background: var(--paper);
  color-scheme: light dark;
}

/* ------------------------------------------------------------
   6. Present — the rendered view, and the window

   The meeting test: open the page, build a board, share the
   screen. Everything here except the frame is scaffolding for
   *writing* the file — the masthead, the lede, the rail, the
   status line, the gutter, the pane titles — and an audience
   needs none of it, so presenting takes all of it off and gives
   the frame the viewport. What is left is one pair of buttons in
   a corner at a third of full opacity.

   Nothing moves in the DOM and the frame is never re-mounted, so
   a board keeps its scroll and its selection across the switch.
   The editor is *parked*, not hidden: it becomes a drawer that
   starts off the left edge with its layout intact, because a
   `display: none` textarea loses the scrollTop and the selection
   that §6 of app.js exists to protect — and a card dragged while
   presenting still writes into it.

   Every rule below outranks §5's narrow-viewport pane switch on
   specificity, which is the point: presenting shows the document
   whichever pane the switch last chose, and leaves the switch
   set as it was for the way back.
   ------------------------------------------------------------ */
.pres { display: none; }

.is-present { overflow: hidden; }
.is-present .topbar,
.is-present .bench__head,
.is-present .rail,
.is-present .status,
.is-present .swap,
.is-present .hint,
.is-present .foot { display: none; }
.is-present .bench { padding: 0; gap: 0; }

.is-present .panes {
  position: fixed;
  inset: 0;
  z-index: 90;
  height: 100dvh;
  gap: 0;
  grid-template-columns: minmax(0, 1fr);
}
.is-present .panes .pane--view {
  display: flex;
  border-radius: 0;
  box-shadow: none;
}
.is-present .panes .pane--view .pane__bar { display: none; }

.is-present .panes .pane--edit {
  display: flex;
  position: fixed;
  z-index: 95;
  top: clamp(.6rem, 1.4vw, 1rem);
  bottom: clamp(.6rem, 1.4vw, 1rem);
  left: clamp(.6rem, 1.4vw, 1rem);
  width: min(30rem, 86vw);
  border-radius: var(--r);
  box-shadow: var(--shadow-l);
  transform: translateX(calc(-100% - 1.6rem));
  transition: transform .34s cubic-bezier(.2, .8, .3, 1);
}
.is-present.is-drawer .panes .pane--edit { transform: none; }
/* On a phone the drawer is nearly the width of the screen, so it
   stops short of the bottom rather than burying the way out. */
@media (max-width: 899px) {
  .is-present .panes .pane--edit { bottom: 3.6rem; }
}

/* The corner cluster. At rest it is barely there; a pointer over
   it, or a focus ring inside it, brings it up. */
.is-present .pres {
  display: flex;
  gap: .22rem;
  position: fixed;
  z-index: 100;
  right: clamp(.7rem, 1.6vw, 1.15rem);
  bottom: clamp(.7rem, 1.6vw, 1.15rem);
  padding: .26rem;
  border-radius: 100px;
  /* It floats over a document it knows nothing about — a white
     card, an inked plate — so it carries its own ground. */
  background: color-mix(in srgb, var(--card) 86%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: var(--shadow-m), var(--ring);
  opacity: .32;
  transition: opacity .24s;
}
.is-present .pres:hover,
.is-present .pres:focus-within { opacity: 1; }
.pres__b {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .02em;
  color: var(--ink-2);
  padding: .42rem 1rem;
  border-radius: 100px;
  transition: color .18s, background .18s;
}
.pres__b:hover { color: var(--ink); background: var(--paper-2); }
.pres__b[aria-pressed="true"] { color: var(--ink); background: var(--paper-3); font-weight: 500; }
.pres__b--out { color: var(--acc); }
.pres__b--out:hover { color: var(--acc); background: var(--tint); }

/* ------------------------------------------------------------
   7. The spec sheet

   A panel, not a dialog: it never takes the focus and never
   covers the editor's left edge, because it has to be usable
   *while writing* — read the marker set, type the marker. So it
   is a card on the right, the same near-white ground and 14px
   radius as every other lifted surface here, and it is closed
   until asked for.

   It is `display: none` when closed rather than parked
   off-screen. The editor drawer is parked because parking is
   what preserves a textarea's selection and scroll (§6); a
   panel of static text has no such state to lose, and a fixed
   card sitting outside the viewport is a horizontal scrollbar
   waiting for a stylesheet change. Opening animates instead.
   ------------------------------------------------------------ */
.sheet {
  display: none;
  position: fixed;
  /* Over the sticky masthead as well as the panes: the masthead
     is translucent and blurred, and a reference sheet read
     through it is a reference sheet nobody can read. Under the
     drop curtain (200), which outranks everything. */
  z-index: 101;
  top: clamp(.6rem, 1.4vw, 1rem);
  right: clamp(.6rem, 1.4vw, 1rem);
  bottom: clamp(.6rem, 1.4vw, 1rem);
  width: min(31rem, calc(100vw - 1.2rem));
  flex-direction: column;
  overflow: hidden;
  border-radius: var(--r);
  background: var(--card);
  box-shadow: var(--shadow-l), var(--ring);
}
.is-sheet .sheet {
  display: flex;
  animation: sheet-in .26s cubic-bezier(.2, .8, .3, 1);
}
@keyframes sheet-in {
  from { opacity: 0; transform: translateX(1.2rem); }
  to   { opacity: 1; transform: none; }
}
/* Presenting keeps the sheet — a question about the format is
   exactly what gets asked while a board is on screen — but it
   stops above the corner cluster, so the way out is never under
   it. Escape closes the sheet first, then the drawer, then the
   mode. */
.is-present .sheet { bottom: 4.2rem; }

.sheet__bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .62rem .95rem;
  border-bottom: 1px solid var(--rule-soft);
}
.sheet__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--acc); flex: none; }
.sheet__id {
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 500;
  letter-spacing: -.005em;
  color: var(--ink);
}
.sheet__x {
  margin-left: auto;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: .6rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding: .26rem .68rem .22rem;
  border-radius: 100px;
  transition: color .18s, background .18s;
}
.sheet__x:hover { color: var(--acc); background: var(--tint); }

.sheet__body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
  padding: .9rem clamp(.9rem, 2.2vw, 1.15rem) 1.5rem;
  scrollbar-width: thin;
  scrollbar-color: var(--ink-3) transparent;
}
.sheet__body:focus-visible { outline-offset: -3px; }

/* the spec's own first sentence */
.sheet__lede {
  font-size: .86rem;
  line-height: 1.5;
  color: var(--ink-2);
  text-wrap: pretty;
}

/* One group per section of the spec, titled with that section's
   own heading. Open by default — a sheet of shut drawers is a
   worse reference than a long one — and collapsible for the way
   back up. The chevron is drawn from two borders; the subset
   fonts have no glyph for it. */
.sheet__g { margin-top: .55rem; border-top: 1px solid var(--rule-soft); }
.sheet__g > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .6rem 0 .35rem;
  font-family: var(--font-mono);
  font-size: .62rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-3);
  transition: color .18s;
}
.sheet__g > summary:hover { color: var(--ink); }
.sheet__g > summary::-webkit-details-marker { display: none; }
.sheet__g > summary::after {
  content: "";
  margin-left: auto;
  flex: none;
  width: .38rem;
  height: .38rem;
  border-right: 1.4px solid currentColor;
  border-bottom: 1.4px solid currentColor;
  transform: translateY(-.1rem) rotate(45deg);
  transition: transform .2s;
}
.sheet__g[open] > summary::after { transform: translateY(.06rem) rotate(225deg); }
.sheet__gb { padding-bottom: .5rem; }

/* the shared base, one drawer holding the rest */
.sheet__g--shared { margin-top: 1rem; }
.sheet__g--shared > summary { color: var(--acc); }
.sheet__g--shared .sheet__g:first-of-type { border-top: 0; margin-top: 0; }

.sheet__lead,
.sheet__note {
  font-size: .8rem;
  line-height: 1.48;
  color: var(--ink-2);
  margin: .45rem 0 .1rem;
  text-wrap: pretty;
}
.sheet__note { color: var(--ink-3); }

.sheet__l { display: grid; gap: .34rem; margin: .45rem 0 .2rem; }
.sheet__l li {
  position: relative;
  padding-left: .85rem;
  font-size: .8rem;
  line-height: 1.48;
  color: var(--ink-2);
  text-wrap: pretty;
}
.sheet__l li::before {
  content: "";
  position: absolute;
  left: .12rem;
  top: .62em;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--acc-line);
}

.sheet__t {
  width: 100%;
  border-collapse: collapse;
  margin: .45rem 0 .25rem;
  font-size: .78rem;
}
.sheet__t th {
  text-align: left;
  font-family: var(--font-mono);
  font-size: .56rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--ink-3);
  padding: .28rem .55rem .28rem 0;
  border-bottom: 1px solid var(--rule);
}
.sheet__t td {
  vertical-align: top;
  padding: .36rem .55rem .36rem 0;
  border-bottom: 1px solid var(--rule-soft);
  color: var(--ink-2);
  line-height: 1.42;
}
.sheet__t td:first-child { color: var(--ink); }
.sheet__t th:last-child, .sheet__t td:last-child { padding-right: 0; }

/* Source is source: the same inked plate the rest of the site
   draws a file on. */
.sheet__pre {
  background: var(--plate);
  color: var(--plate-fg);
  border-radius: var(--r-sm);
  padding: .7rem .85rem .75rem;
  margin: .5rem 0 .3rem;
  font-size: .7rem;
  line-height: 1.66;
  white-space: pre;
  overflow-x: auto;
  tab-size: 2;
  font-variant-numeric: lining-nums;
  scrollbar-width: thin;
  scrollbar-color: var(--plate-dim) transparent;
}
/* `code` is a nowrap chip everywhere else on this site; inside a
   plate it is the file, and the plate's own wrapping rule wins. */
.sheet__pre code { background: none; padding: 0; font-size: 1em; white-space: inherit; }

/* one verb: what it is called, what it takes, what it edits */
.sheet__v { padding: .5rem 0 .55rem; border-bottom: 1px solid var(--rule-soft); }
.sheet__v:last-child { border-bottom: 0; }
.sheet__vn {
  font-family: var(--font-mono);
  font-size: .74rem;
  font-weight: 600;
  color: var(--ink);
}
.sheet__vs {
  margin: .3rem 0 .3rem;
  padding: .34rem .5rem;
  border-radius: var(--r-xs);
  background: var(--paper-2);
  font-family: var(--font-mono);
  font-size: .66rem;
  line-height: 1.55;
  color: var(--ink-2);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.sheet__vd { font-size: .78rem; line-height: 1.45; color: var(--ink-2); }

/* one spec, offered to a file that names none */
.sheet__pick { margin-top: .7rem; padding-top: .2rem; }
.sheet__pick .sheet__pre { margin-top: .35rem; }

.sheet__doc {
  margin-top: 1.1rem;
  padding-top: .75rem;
  border-top: 1px solid var(--rule-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .3rem .7rem;
  font-family: var(--font-mono);
  font-size: .66rem;
  color: var(--ink-3);
}
.sheet__pick .sheet__doc { margin-top: .4rem; padding-top: 0; border-top: 0; }
.sheet__doc a { color: var(--acc); text-decoration-color: var(--acc-line); }
.sheet__doc code { font-size: 1em; }

@media (max-width: 560px) {
  .sheet__pre { font-size: .66rem; }
  .sheet__body { padding-inline: .8rem; }
}

/* ------------------------------------------------------------
   8. Hint + drop curtain
   ------------------------------------------------------------ */
.hint {
  font-size: .88rem;
  line-height: 1.55;
  color: var(--ink-3);
  max-width: 58rem;
}
.hint b { color: var(--ink-2); }
.hint--warn {
  background: var(--tint-warn);
  border-radius: var(--r);
  padding: 1rem 1.2rem;
  color: var(--ink-2);
}

.drop {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  place-items: center;
  background: color-mix(in srgb, var(--paper) 82%, transparent);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.dropping .drop { display: grid; }
.drop span {
  font-family: var(--font-mono);
  font-size: .84rem;
  letter-spacing: .04em;
  color: var(--ink);
  background: var(--card);
  border-radius: var(--r);
  padding: 1.5rem 2.2rem;
  box-shadow: var(--shadow-l), inset 0 0 0 2px var(--acc-line);
}
.drop code { background: none; color: var(--acc); }

/* ------------------------------------------------------------
   9. Footer, trimmed for a tool page
   ------------------------------------------------------------ */
.app .foot__rule { border-top: 1px solid var(--rule-soft); }
.app .foot__rule a { color: inherit; text-decoration: none; }
.app .foot__rule a:hover { color: var(--acc); }

/* ------------------------------------------------------------
   10. Dark — derived from the light design above
   ------------------------------------------------------------ */
@media (prefers-color-scheme: dark) {
  :root {
    --sev-ok:    #8fbf9c;
    --sev-warn:  #d9b063;
    --tint-ok:   #16211a;
    --tint-warn: #241d10;
  }
  /* On near-black the inked pane needs its hairline back: a
     shadow separates nothing there. */
  .pane--edit { box-shadow: var(--shadow-m), inset 0 0 0 1px var(--plate-rule); }
  .is-present .panes .pane--edit { box-shadow: var(--shadow-l), inset 0 0 0 1px var(--plate-rule); }
  /* On near-black a third of an opacity is nearly nothing; the
     cluster has to stay findable without being lit. */
  .is-present .pres { opacity: .42; }
  .drop { background: color-mix(in srgb, var(--paper) 78%, transparent); }
}

/* ------------------------------------------------------------
   11. Reduced motion
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  /* The patch cue still has to land — it is information, not
     decoration — so it becomes a static hold rather than a fade. */
  .pane--edit.is-patched .ed { animation: none; box-shadow: inset 0 0 0 2px var(--plate-acc); }
}
