:root {
  /* Supabase-style dark theme: near-black neutral surfaces, hairline borders,
     one signature green doing all the accent work. */
  --bg:#121212; --card:#1c1c1c; --field:#181818; --ink:#ededed; --muted:#8f8f8f;
  --line:#2e2e2e; --green:#3ecf8e; --yellow:#ffc53d; --red:#f04438; --gray:#707070;
  --link:#3ecf8e; --accent:#3ecf8e; --green-ink:#0a1f16;
}
* { box-sizing:border-box; }
/* `hidden` has to outrank any class that sets `display`, or an element the JS
   hides stays on screen: the browser's own [hidden] rule loses to a single class
   selector. That's how "Show the browser" survived a phone run, the tab bar sat
   on the sign-in screen, and the wizard asked for a bundle ID before iOS was
   even ticked. */
[hidden] { display:none !important; }
body { margin:0; background:var(--bg); color:var(--ink);
  font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif; }

button { font:inherit; cursor:pointer; border:1px solid var(--line);
  background:var(--card); color:var(--ink); padding:7px 14px; border-radius:6px;
  transition:border-color .12s ease, background .12s ease, filter .12s ease; }
button:hover:not(:disabled) { border-color:#3f3f3f; }
button.primary { background:var(--green); border-color:var(--green); color:var(--green-ink); font-weight:600; }
button.primary:hover:not(:disabled) { filter:brightness(1.1); border-color:var(--green); }
button:disabled { opacity:.5; cursor:not-allowed; }

 
 

   

      

label.rundev { display:flex; gap:7px; align-items:center; font-size:14px;
  border:1px solid var(--line); border-radius:7px; padding:6px 11px; cursor:pointer; }
/* What became of each hint sent to a live run: the text, then its state. Sits
   under the hint box and outlives the run, so one that never reached the agent
   stays on screen instead of vanishing with "Sent" as the last word. */
.hint-list { list-style:none; padding:0; margin:-8px 0 16px; font-size:13px; }
.hint-list li { padding:3px 0; }
.hint-list li span { margin-left:8px; font-size:12px; }

.lr-links { font-size:13px; margin-top:8px; display:flex; gap:14px; flex-wrap:wrap; }
 
h2 { font-size:15px; font-weight:600; margin:6px 0 14px; }
.muted { color:var(--muted); } .err { color:var(--red); } .ok { color:var(--green); }

button.link { border:none; background:none; color:var(--link); padding:0; font-size:13px; }
button.cancel-run { border:1px solid var(--red); background:none; color:var(--red);
  border-radius:6px; padding:2px 9px; font-size:12px; cursor:pointer; }
button.cancel-run:disabled { opacity:.5; cursor:default; }

label.fld { display:block; font-size:12px; color:var(--muted); margin:6px 0; }
label.fld textarea { display:block; width:100%; margin-top:3px; background:var(--field);
  color:var(--ink); border:1px solid var(--line); border-radius:6px; padding:7px 9px;
  font:13px/1.45 -apple-system,system-ui,sans-serif; resize:vertical; }
div.fld { font-size:12px; color:var(--muted); margin:6px 0; }

.chip { display:inline-flex; align-items:center; gap:5px; font-size:12px; color:var(--ink);
  background:var(--card); border:1px solid var(--line); border-radius:14px; padding:3px 5px 3px 10px; }
.chip-x { border:none; background:none; color:var(--muted); padding:0 3px; font-size:15px; line-height:1; cursor:pointer; }
.chip-x:hover { color:var(--red); }

.toolbar { display:flex; gap:10px; align-items:center; margin:10px 0 16px; flex-wrap:wrap; }
.notice { padding:10px 14px; border:1px solid var(--line); border-radius:8px;
  background:var(--card); margin:10px 0; }

@media (max-width:760px) { .results-grid, .results-grid.three { grid-template-columns:1fr; } }

.rrow-tests { margin-top:7px; padding-top:7px; border-top:1px solid var(--line); }
.rrow-test { font-size:12px; padding:1px 0; color:var(--ink); }

table { width:100%; border-collapse:collapse; background:var(--card);
  border:1px solid var(--line); border-radius:8px; overflow:hidden; }
th,td { text-align:left; padding:9px 13px; border-bottom:1px solid var(--line); font-size:14px; }
tr:last-child td { border-bottom:none; }
a { color:var(--link); text-decoration:none; } a:hover { text-decoration:underline; }
.switch { display:inline-flex; gap:8px; align-items:center; }
.runcard { background:var(--card); border:1px solid var(--line); border-radius:8px;
  padding:12px 14px; margin-bottom:12px; }
.runcard.active { border-color:var(--yellow); }
/* Optimistic shimmer card shown immediately after dispatch, until the real
   in-flight run appears from the GitHub API. */
.runcard.skeleton { border-style:dashed; border-color:var(--line); }
.sk-line { height:12px; border-radius:6px; margin:8px 0;
  background:linear-gradient(90deg, rgba(160,160,160,.08) 25%, rgba(160,160,160,.22) 37%, rgba(160,160,160,.08) 63%);
  background-size:400% 100%; animation:shimmer 1.4s ease-in-out infinite; }
.sk-line.w40 { width:40%; } .sk-line.w70 { width:70%; } .sk-line.w55 { width:55%; }
@keyframes shimmer { 0% { background-position:100% 0; } 100% { background-position:0 0; } }
@media (prefers-reduced-motion: reduce) { .sk-line { animation:none; } }
.dot { display:inline-block; width:9px; height:9px; border-radius:50%;
  background:var(--yellow); vertical-align:middle; margin-right:4px; }
.dot.pulse { animation:dotpulse 1.3s ease-in-out infinite; }
@keyframes dotpulse {
  0%   { box-shadow:0 0 0 0 rgba(255,197,61,.55); opacity:1; }
  70%  { box-shadow:0 0 0 7px rgba(255,197,61,0); opacity:.7; }
  100% { box-shadow:0 0 0 0 rgba(255,197,61,0); opacity:1; }
}
@media (prefers-reduced-motion: reduce) { .dot.pulse { animation:none; } }

/* A brief highlight after scrolling straight to a row or card that was
   linked to directly (Results, the run page). */
.flash { animation: toc-flash 1.2s ease-out; }
@keyframes toc-flash { from { background: var(--field); } to { background: transparent; } }

.runcard-head { display:flex; justify-content:space-between; align-items:baseline;
  margin-bottom:8px; flex-wrap:wrap; gap:6px; }

 
 

  

/* detail panel: outcome + spec + screenshot (ported from the report pages) */
.outcome { scroll-margin-top:64px; border:1px solid var(--line); border-left-width:3px; border-radius:8px;
  padding:10px 14px; margin:10px 0; background:var(--card); }
.outcome.o-passed { border-left-color:var(--green); }
.outcome.o-inconclusive { border-left-color:var(--yellow); }
.outcome.o-failed { border-left-color:var(--red); }
.outcome.o-skipped { border-left-color:var(--gray); }
/* What the tester wrote into its own notes after this test. */
.o-learned ul { margin:4px 0 0; padding-left:18px; }
.o-learned li { margin:2px 0; }
.outcome.clickable { cursor:pointer; }
.outcome.clickable:hover { border-color:var(--accent); }

.o-head { font-size:15px; margin-bottom:3px; }
.o-line { font-size:14px; margin:5px 0; }
.o-line .lbl { font-weight:600; } .o-line .lbl.err { color:var(--red); }
details.spec { margin:8px 0; } details.spec > summary { cursor:pointer; color:var(--muted); font-size:13px; }
details.transcript { margin:10px 0 4px; }
details.transcript > summary { cursor:pointer; color:var(--muted); font-size:13px; }
details.transcript[open] > summary { margin-bottom:8px; }
.transcript-frame { width:100%; height:520px; border:1px solid var(--line); border-radius:8px; background:var(--bg); display:block; margin-bottom:6px; }

/* ── a result that explains itself (round 6) ─────────────────────────────────
   The card's lead sentence, the plan with a verdict per step, the screenshots
   worth looking at, and the transcript the webapp renders itself from
   transcript.json (js/transcript.js). The .transcript-frame above stays: it is
   still the fallback for a run that saved only transcript.html. */
.o-lead { font-size:14px; margin:2px 0 4px; }
/* The runner writes notes across several lines. Only this class gets pre-wrap —
   the other .o-line templates are wrapped and indented in the source. */
.o-notes { white-space:pre-wrap; }

.steps { list-style:none; margin:8px 0; padding:0; }
.steps .st { display:grid; grid-template-columns:18px 22px minmax(0,1fr); gap:0 8px;
  padding:3px 0; font-size:14px; align-items:baseline; }
.steps .st-note { grid-column:3; font-size:13px; color:var(--muted); }
/* The plan at the top of a card is the test as written: the check after the
   arrow and the document's Note: ride with each step, in a quiet box. */
.outcome > .steps { background:var(--field); border-radius:6px; padding:6px 10px; margin:6px 0 8px; }
.steps .st-check { color:var(--muted); }
.steps .st-hint { grid-column:3; font-size:13px; color:var(--muted); font-style:italic; white-space:pre-wrap; }
.st-glyph.passed { color:var(--green); }
.st-glyph.partial { color:var(--yellow); }
.st-glyph.failed { color:var(--red); }
.st-glyph.skipped, .st-glyph.not_reached { color:var(--muted); }

.shots { display:flex; flex-wrap:wrap; gap:10px; margin:10px 0; }
.shots figure { margin:0; width:200px; max-width:46%; }
.shots img { width:100%; display:block; border:1px solid var(--line); border-radius:8px; }
.shots figure.flag img, .shots figure.error img { border-color:var(--yellow); }
.shots figcaption { font-size:12px; color:var(--muted); margin-top:4px; }
.shots figure button.shot-copy { display:block; margin-top:3px; font-size:12px; }

/* The bug report a Failed card hands to Jira. It sits with the verdict, above
   the steps: filing a bug is what someone does right after reading what went
   wrong, not after scrolling past the evidence. */
.o-actions { display:flex; gap:14px; align-items:baseline; flex-wrap:wrap; margin:8px 0 2px; }
.o-actions [data-bug-msg] { flex:1 1 100%; margin-top:2px; }
.copy-fallback { display:flex; flex-direction:column; gap:4px; margin:6px 0 2px; flex:1 1 100%; }
.copy-fallback label { font-size:12px; color:var(--muted); }
.copy-fallback textarea { width:100%; font:inherit; font-size:12px; line-height:1.5;
  background:var(--field); color:var(--ink); border:1px solid var(--line);
  border-radius:8px; padding:8px 10px; resize:vertical; }

.tr { border-left:2px solid var(--line); padding-left:14px; }
/* The rail follows the reader down a long transcript; 52px clears the topbar. */
.tr-rail { position:sticky; top:52px; z-index:5; background:var(--card); padding:6px 0;
  font-size:13px; color:var(--muted); }
.tr-rail a { cursor:pointer; margin-right:6px; color:var(--ink); }
/* A section head is one line whether or not it carries a glyph — the trailing
   "After the last step" belongs to no step and has none. */
.tr-sec { margin:16px 0 4px; font-weight:600; scroll-margin-top:96px; }
.tr-reason { white-space:pre-wrap; line-height:1.55; margin:8px 0; }
.tr-hint { border-left:3px solid var(--green); padding:4px 10px; font-size:14px; }
.tr-acts { margin:4px 0 6px 10px; font-size:13px; color:var(--muted); }
.tr-row { display:block; padding:1px 0; }
.tr-row.nf { color:var(--yellow); }
.tr-row.err { color:var(--red); }
.tr-row.flag { color:var(--ink); }
.tr-shot img { max-width:220px; display:block; border:1px solid var(--yellow); border-radius:8px; }
.tr-shot.step img { border-color:var(--line); }
details.tr-tech > summary { cursor:pointer; font-size:12px; color:var(--muted); }
.tr-tech code { display:block; white-space:pre-wrap; word-break:break-all; font-size:12px; color:var(--muted); }
 

 

 

code { font-family:ui-monospace,Menlo,monospace; font-size:13px; }

/* Focus + selection polish (Supabase-style green ring) */
textarea:focus, input:focus, select:focus { outline:none; border-color:var(--green) !important;
  box-shadow:0 0 0 3px rgba(62,207,142,.14); }
input, select { background:var(--field); color:var(--ink); border:1px solid var(--line);
  border-radius:6px; padding:5px 8px; font:13px/1.4 inherit; }

::selection { background:rgba(62,207,142,.28); }
input[type=checkbox] { accent-color:var(--green); }
/* Header project picker */
.project-pick { font-size:13px; }
.project-pick select { min-width:130px; }

/* ── webapp additions ── */

.live-log { background:var(--field); border:1px solid var(--line); border-radius:8px;
  padding:10px 12px; max-height:340px; overflow:auto; font:12px/1.5 ui-monospace,Menlo,monospace;
  white-space:pre-wrap; word-break:break-word; }
.log-row { cursor:pointer; } .log-row:hover { color:var(--green); }

/* ── Phase 2: mobile projects, helper pairing, project secrets ── */
.pair-code { font-size:28px; font-weight:700; letter-spacing:.06em;
  font-family:ui-monospace,Menlo,monospace; margin:2px 0 6px; }

/* The onboarding wizard's centred column (pages/onboarding.js). */
.auth-box { max-width:520px; margin:60px auto; }
.auth-box h2 { font-size:20px; }

/* ── the shell: sidebar + page ──────────────────────────────────────────── */
.shell { display: grid; grid-template-columns: 232px minmax(0, 1fr); grid-template-rows: 52px minmax(0, 1fr); min-height: 100vh; }
.topbar { grid-column: 1 / -1; position: sticky; top: 0; z-index: 15; background: var(--bg); display: flex; align-items: center; gap: 14px; padding: 0 20px; border-bottom: 1px solid var(--line); }
.topbar .brand { font-weight: 700; font-size: 17px; display: flex; align-items: center; gap: 8px; color: var(--ink); text-decoration: none; }
.topbar .brand::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--green); }
.topbar .spacer { flex: 1; }
.topbar .who { color: var(--muted); font-size: 13px; }
.topbar a.avatar { width: 28px; height: 28px; border-radius: 50%; border: 1px solid var(--line); display: inline-flex; align-items: center; justify-content: center; color: var(--ink); text-decoration: none; }
.topbar a.avatar.on { border-color: var(--green); }
.topbar button.menu { display: none; }
/* The column is viewport-locked: it sticks under the topbar at exactly the
   viewport's height, so the Account group is always in view no matter how
   tall the page is. It scrolls on its own in the unlikely case it overflows. */
.side { border-right: 1px solid var(--line); padding: 14px 12px; display: flex; flex-direction: column; gap: 14px;
  position: sticky; top: 52px; align-self: start; height: calc(100vh - 52px); overflow-y: auto; }
.side[hidden] { display: none; }
/* One rhythm for the whole column: every text line starts 24px in (12px column
   padding + 12px item padding), nav links are 14px in both groups, section
   labels use the table-header idiom (11px caps, muted). */
.side .switch-project select { width: 100%; padding: 7px 11px; font-size: 14px; }
.side nav { display: flex; flex-direction: column; gap: 2px; }
.side nav a { display: flex; align-items: center; gap: 10px; padding: 7px 12px; border-radius: 6px; font-size: 14px; color: var(--ink); text-decoration: none; }
.side nav a .nav-ico { flex: none; color: var(--muted); }
.side nav a.on .nav-ico, .side nav a:hover .nav-ico { color: inherit; }
.side nav a.on { background: var(--card); color: var(--green); font-weight: 600; }
.side nav a:hover { background: var(--card); }
.side .side-head { padding: 0 12px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); }
.side .side-foot { margin-top: auto; display: flex; flex-direction: column; gap: 8px; }
.side .side-foot > span { padding: 0 12px; font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 8px; }
.side .side-status .dot { margin: 0; }
.side .side-status .dot.off { background: var(--gray); }
.side .side-status .dot.on { background: var(--green); }

.shell.bare { grid-template-columns: minmax(0, 1fr); }
.shell.bare .side { display: none; }
.banner { margin: 10px 20px 0; }

/* ── page anatomy ───────────────────────────────────────────────────────── */
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.page-head h1 { margin: 0; font-size: 22px; }
.page-head .sub { color: var(--muted); font-size: 13px; margin-top: 2px; }
.page-head .actions { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.page-head .actions .row { display: flex; gap: 8px; }
.crumbs { color: var(--muted); font-size: 13px; margin-bottom: 8px; }
.crumbs a { color: var(--muted); }
.card { border: 1px solid var(--line); background: var(--card); border-radius: 8px; padding: 14px 16px; }
.card + .card, .card + h2, .table + h2, .grid2 + h2, .grid3 + h2 { margin-top: 14px; }
.card h3 { margin: 0 0 8px; font-size: 15px; }
.card.dashed { border-style: dashed; background: transparent; }
.grid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.grid3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.table { display: grid; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--card); }
.table > div { padding: 9px 12px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 8px; min-height: 40px; min-width: 0; }
.table > .th { background: var(--field); color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .4px; min-height: 30px; }
.table > .last { border-bottom: none; }
.table a { color: var(--ink); }
.verdict { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line); padding: 0 8px; height: 22px; font-size: 12px; border-radius: 4px; white-space: nowrap; }
.verdict.pass { border-color: var(--green); color: var(--green); }
.verdict.fail { border-color: var(--red); color: var(--red); }
.verdict.part { border-color: var(--yellow); color: var(--yellow); }
.verdict.block { border-style: dashed; color: var(--muted); }
.verdict.bugsent { border-color: var(--muted); color: var(--muted); }
/* Nothing was proven wrong — outlined, not solid, so it reads as an open
   question rather than a result. */
.verdict.inconclusive { border-color: var(--yellow); color: var(--yellow); border-style: dashed; }
.verdict.live { border-color: var(--yellow); color: var(--yellow); }
/* Solid, not outlined like .live — a paused run isn't progressing on its own
   and can wait indefinitely, so it needs to stand out from a run that is. */
.verdict.paused { background: var(--yellow); border-color: var(--yellow); color: var(--green-ink); font-weight: 600; }
.checklist .row { display: grid; grid-template-columns: 24px 150px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 8px 0; border-top: 1px solid var(--line); }
.checklist .row:first-of-type { border-top: none; }
.checklist .tick { width: 16px; height: 16px; border: 1px solid var(--ink); border-radius: 3px; display: inline-block; }
.checklist .tick.on { background: var(--green); border-color: var(--green); }
.reason { color: var(--muted); font-size: 12px; }
button.primary:disabled { opacity: .5; cursor: not-allowed; }
.small { font-size: 12px; }
.empty { color: var(--muted); padding: 18px 0; }
.attach { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border: 1px dashed var(--line); border-radius: 8px; margin-bottom: 12px; }
.attach .row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.attach code { font-size: 12px; }
.paused { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border: 1px solid var(--yellow); border-radius: 8px; margin-bottom: 12px; }
.paused .row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; }
.fields label.fld { display: flex; flex-direction: column; gap: 4px; margin: 0; }
.fields .wide { grid-column: 1 / -1; }

@media (max-width: 720px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .side { display: none; position: fixed; top: 52px; left: 0; bottom: 0; width: 260px; background: var(--bg); z-index: 20; }
  .side.open { display: flex; }
  .topbar button.menu { display: inline-flex; }
  .topbar .who { display: none; }
  main#page { padding: 16px; }
  .grid2, .grid3, .fields { grid-template-columns: minmax(0, 1fr); }
  .table { grid-template-columns: minmax(0, 1fr) !important; }
  .table > .th { display: none; }
  .checklist .row { grid-template-columns: 24px minmax(0, 1fr); }
  .page-head { flex-direction: column; }
  .page-head .actions { align-items: flex-start; }
}

/* ── the run page ──────────────────────────────────────────────────────── */
.run-head .where { color: var(--muted); margin: 4px 0 14px; }
.run-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; align-items: start; }
.hint-row { display: flex; gap: 8px; margin-top: 10px; }
.hint-row input { flex: 1; }
.result .outcome { margin-top: 10px; }
@media (max-width: 720px) { .run-cols { grid-template-columns: minmax(0, 1fr); } }

/* ── the run recipe ─────────────────────────────────────────────────────── */
dialog.recipe { background: var(--card); color: var(--ink); border: 1px solid var(--line); border-radius: 10px; padding: 20px 24px; width: min(720px, 92vw); max-height: 90vh; overflow: auto; }
dialog.recipe::backdrop { background: rgba(0, 0, 0, .6); }
dialog.recipe h2 { margin: 0 0 14px; }
.recipe-grid { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 12px 16px; align-items: start; }
.recipe-grid > .lbl { font-weight: 600; padding-top: 8px; }
.choices { display: flex; flex-direction: column; gap: 6px; }
.choice { display: flex; gap: 12px; align-items: flex-start; border: 1px solid var(--line); border-radius: 8px; padding: 9px 12px; cursor: pointer; background: var(--field); }
.choice.sel { border-color: var(--green); }
.choice.off { border-style: dashed; opacity: .75; cursor: not-allowed; }
.choice .detail { color: var(--muted); font-size: 12px; }
.summary { background: var(--field); border-radius: 8px; padding: 10px 14px; margin-top: 14px; }
.recipe-foot { display: flex; justify-content: flex-end; align-items: center; gap: 10px; margin-top: 14px; }
dialog.import-review { width: min(760px, 94vw); }
.ir-list { display: flex; flex-direction: column; }
.ir-row { display: flex; justify-content: space-between; gap: 12px; align-items: baseline;
  padding: 8px 2px; border-bottom: 1px solid var(--line); }
.ir-row:last-child { border-bottom: none; }

/* ── the build-upload dropzone ── */
.dropzone { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 22px 16px;
  border: 1.5px dashed var(--line); border-radius: 10px; background: var(--field); cursor: pointer;
  text-align: center; margin: 10px 0; }
.dropzone:hover, .dropzone:focus-visible, .dropzone.over { border-color: var(--green); outline: none; }
.dropzone.over { background: rgba(62, 207, 142, .06); }
.up-pct { margin-left: 8px; color: var(--ink); font-variant-numeric: tabular-nums; }
.upbar { display: inline-block; vertical-align: middle; width: 160px; height: 6px; margin-left: 8px;
  border-radius: 3px; background: var(--line); overflow: hidden; }
.upbar > span { display: block; height: 100%; width: 0; background: var(--green); transition: width .15s ease; }

/* The run bar (Results) and the two-column test/detail layout (Knowledge). */
.runbar { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); z-index: 10;
  display: flex; gap: 12px; align-items: center; background: var(--card); border: 1px solid var(--line);
  border-radius: 10px; padding: 10px 14px; box-shadow: 0 6px 24px rgba(0, 0, 0, .45); }
.test-cols { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 20px; align-items: start; }
@media (max-width: 720px) { .test-cols { grid-template-columns: minmax(0, 1fr); } }

/* The page area itself — kept apart from the sidebar by its own padding. */
main#page { padding: 22px 28px; min-width: 0; }
@media (max-width: 720px) { main#page { padding: 16px; } }

/* The flow-name input (Results) combines this with .fname below. */
.tname { font: inherit; font-size: 16px; font-weight: 600; background: transparent; border: none;
  border-bottom: 1px dashed transparent; color: inherit; padding: 0; min-width: 220px; flex: 1; }
.tname:hover, .tname:focus { border-bottom-color: var(--line); }

/* ── flows: named ordered sequences run in one session (round 4) ────────── */
.flows { margin-top: 34px; padding-top: 16px; border-top: 1px solid var(--line); }
.flows .fhead { font-size: 18px; font-weight: 700; }
.fblock { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0 6px; }
.fblock > input[type=checkbox] { margin-top: 9px; }
.fblock .body { flex: 1; min-width: 0; }
.fblock .chain { color: var(--muted); }
.fblock .tmeta { display: flex; gap: 10px; align-items: center; }
.fname { font: inherit; font-weight: 600; background: transparent; border: none;
  border-bottom: 1px dashed transparent; color: var(--ink); min-width: 220px; }
.fname:hover, .fname:focus { border-bottom-color: var(--line); outline: none; }
.fmember { display: flex; gap: 8px; align-items: center; padding: 3px 0 3px 24px; }
.fmember .fnum { color: var(--muted); font-weight: 600; min-width: 16px; }
.fmember .drag { color: var(--muted); cursor: grab; }
.fmember.drop-target { box-shadow: 0 -2px 0 var(--ink); }

/* ── the Results table (round 5): sections, flows and verdicts per platform ── */
.rtable-wrap { overflow-x: auto; }
.rtable { display: grid; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; background: var(--card); }
.rtable > div { padding: 8px 12px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 8px; min-height: 38px; min-width: 0; }
.rtable > .th { background: var(--field); color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .4px; min-height: 30px; }
.rtable > [data-last] { border-bottom: none; }
.rtable a { color: var(--ink); }
.rtable > .rsec { grid-column: 1 / -1; background: var(--field); font-weight: 700; min-height: 34px; }
.rtable > .rsec .muted { font-weight: 400; }
.rtable .chain { color: var(--muted); }
.rtable .fname { min-width: 140px; }
.rtable > .rmember, .rtable > .rname.rmember { padding-left: 34px; }
.rtable .fnum { color: var(--muted); font-weight: 600; min-width: 16px; }
.rtable .rowctl { display: inline-flex; gap: 6px; margin-left: auto; }
/* Phones: the grid keeps its columns and the wrapper scrolls sideways —
   .table's one-column collapse would orphan the checkboxes here. */
@media (max-width: 720px) { .rtable { min-width: 660px; } }

/* A step that was judged against a design names the reference, with a small
   preview where the picture could be signed. */
.st-design { display: inline-flex; align-items: center; gap: 6px; margin-left: 8px; }
.st-dthumb { max-height: 40px; max-width: 60px; border-radius: 3px; border: 1px solid var(--line, #ddd); vertical-align: middle; }

/* ── the Tests document (round 6d): one column of text, a margin per test ── */
.page-head .actions .row { position: relative; }
.page-head .menu { position: absolute; right: 0; top: calc(100% + 4px); z-index: 10; display: flex; flex-direction: column;
  min-width: 190px; padding: 4px; background: var(--card); border: 1px solid var(--line); border-radius: 8px; }
.page-head .menu[hidden] { display: none; }
.page-head .menu button { border: none; background: transparent; text-align: left; }
.page-head .menu button:hover { background: var(--field); }
.card.how p { margin: 4px 0; }

/* The contents block above the document, once a heading and a test have names. */
.toc { margin: 4px 0 14px; padding: 12px 16px; border: 1px solid var(--line); border-radius: 10px;
  columns: 3 200px; column-gap: 28px; font-size: 13px; }
.toc-cap { display: block; column-span: all; color: var(--muted); font-size: 12px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .4px; margin-bottom: 8px; }
.toc-sec { break-inside: avoid; margin-bottom: 10px; }
.toc-sec a { display: block; color: var(--muted); text-decoration: none; padding: 1px 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.toc-sec > a:first-child { color: var(--ink); font-weight: 600; }
.toc-sec a:hover { color: var(--ink); text-decoration: underline; }
#doc-toc { max-width: 700px; box-sizing: border-box; }   /* as wide as the editor column */

.doc-wrap { position: relative; display: grid; grid-template-columns: minmax(0, 700px) 230px; gap: 22px; margin-top: 12px; }
.doc-editor { outline: none; min-height: 200px; line-height: 1.55; padding-bottom: 40px; font-size: 14px; caret-color: var(--ink); }
.doc-editor .ln { padding: 2px 0; white-space: pre-wrap; }
.doc-editor .ln[data-kind=section] { font-size: 20px; font-weight: 700; margin-top: 22px; }
.doc-editor .ln[data-kind=title] { font-weight: 700; margin-top: 12px; }
.doc-editor .ln[data-kind=note] { color: var(--muted); font-style: italic; padding-left: 18px; }
.doc-editor .ln.removed { text-decoration: line-through; color: var(--muted); }
.doc-editor .ln[data-warn] { border-bottom: 2px dotted var(--muted); }
.doc-editor .ln[data-warn]::after { content: attr(data-warn); display: block; font-size: 12px; color: var(--muted); border-left: 2px dotted var(--muted); padding-left: 8px; margin: 2px 0 4px; }
.doc-editor .drop-target { box-shadow: 0 -2px 0 var(--green); }
/* The ghost line's own placeholder — the line carries a <br>, not empty text,
   so this keys off the is-empty class the editor paints rather than :empty. */
.doc-editor .ln[data-kind=ghost].is-empty::before { content: attr(data-placeholder); color: var(--muted); pointer-events: none; }

/* A step's picture: a 48px thumbnail, its filename, the tolerance note and a
   remove button, all on one line — wrapping only if a narrow screen forces it. */
.doc-editor .ln[data-kind=pic] { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; color: var(--muted); font-size: 13px; }
.doc-editor .ln[data-kind=pic] img.dthumb { flex: none; width: 48px; height: 48px; object-fit: cover; border-radius: 4px; border: 1px solid var(--line); }
.doc-editor .ln[data-kind=pic] .dthumb-missing { font-style: italic; }
.doc-editor .ln[data-kind=pic] .dname { flex: 1 1 120px; min-width: 0; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.doc-editor .ln[data-kind=pic] .dtol-l { white-space: nowrap; }
.doc-editor .ln[data-kind=pic] input.tol { flex: 1 1 80px; min-width: 60px; }
.doc-editor .ln[data-kind=pic] .dremove { border: none; background: none; color: var(--muted); padding: 0 2px; font-size: 15px; line-height: 1; cursor: pointer; }
.doc-editor .ln[data-kind=pic] .dremove:hover { color: var(--ink); }

/* The drag handle lives outside the editable text (dragging out of a
   contenteditable is unreliable) and only shows once the pointer is over
   the gutter, so the column stays quiet the rest of the time. */
.doc-gutter { position: absolute; left: -18px; top: 0; width: 18px; }
.doc-gutter .handle { position: absolute; left: 0; color: var(--muted); cursor: grab; font-size: 11px; user-select: none; opacity: 0; transition: opacity .12s ease; }
.doc-gutter:hover .handle { opacity: 1; }

/* The margin: one entry beside every saved test, mostly muted so the column
   stays quiet — a link (see the run, split, notes) is the one thing in ink. */
.doc-margin { position: relative; }
.doc-margin .mg { position: absolute; left: 0; right: 0; font-size: 12px; color: var(--muted); line-height: 1.4; }
.doc-margin .mg a { color: var(--ink); }
.doc-margin .mg > div { margin-top: 3px; }
.doc-margin .mg-why { color: var(--muted); }
.doc-margin textarea.mg-notes { display: block; width: 100%; box-sizing: border-box; margin-top: 6px;
  background: var(--field); color: var(--ink); border: 1px solid var(--line); border-radius: 6px;
  padding: 6px 8px; font: inherit; font-size: 12px; line-height: 1.4; resize: vertical; }

/* The format bar sits above the caret's line, right-aligned to the editor
   column so it never drifts over the margin. */
.fbar { position: absolute; z-index: 5; display: flex; gap: 2px; padding: 3px; background: var(--card);
  border: 1px solid var(--line); border-radius: 7px; box-shadow: 0 6px 24px rgba(0, 0, 0, .35); }
.fbar[hidden] { display: none; }
.fbar button { padding: 3px 8px; font-size: 12px; border: none; }
.fbar button.on { background: var(--field); color: var(--accent); }

/* The selection bar: a selection touching one or more tests offers to move
   or remove them. */
.selbar { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); z-index: 10;
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap; justify-content: center; max-width: calc(100vw - 24px);
  background: var(--card); border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px; box-shadow: 0 6px 24px rgba(0, 0, 0, .45); }
.selbar[hidden] { display: none; }
.selbar select, .selbar input { font-size: 13px; }

@media (max-width: 720px) {
  .doc-wrap { grid-template-columns: minmax(0, 1fr); }
  .doc-margin { display: none; }
  .toc { columns: 1; }
}

/* ── Tester's notes: every note is a row that opens in place ─────────────── */
.notes-h { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .4px; color: var(--muted); margin: 20px 0 6px; }
.notes > .notes-h:first-child { margin-top: 0; }
.notes-h .muted { text-transform: none; letter-spacing: 0; font-weight: 400; }
details.note { border: 1px solid var(--line); border-radius: 8px; background: var(--card); margin-bottom: 6px; }
details.note > summary { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; padding: 9px 12px; cursor: pointer; list-style: none; border-radius: 8px; }
details.note > summary::-webkit-details-marker { display: none; }
details.note > summary::before { content: "▸"; color: var(--muted); font-size: 11px; }
details.note[open] > summary::before { content: "▾"; }
details.note > summary:hover { background: var(--field); }
details.note .note-title { font-weight: 600; }
details.note .note-meta { margin-left: auto; }
details.note .note-body { padding: 0 12px 10px; border-top: 1px solid var(--line); }
details.note .note-body > .muted { margin-top: 8px; }
details.note textarea { display: block; width: 100%; box-sizing: border-box; margin-top: 8px; background: var(--field); color: var(--ink);
  border: 1px solid var(--line); border-radius: 6px; padding: 8px 10px; font: inherit; font-size: 13px; line-height: 1.45; resize: vertical; }
details.note .note-foot { display: flex; gap: 10px; margin-top: 6px; min-height: 18px; }
details.note .note-foot a { margin-left: auto; }
/* The history beside the notes: a group per run, a box per change. */
.kc-run + .kc-run { margin-top: 14px; }
.kc-head { margin-bottom: 2px; }
#recent-changes .notice { margin: 6px 0; }

