/* Dragonfly's look: a precision instrument (operator, 2026-10-05; proposal
   "Dragonfly UI Direction"). Graphite neutrals biased toward the accent, one
   accent from the insect's thorax for what you can act on, and color spent
   only on state. Every rule below names a role variable, never a hex.
   WCAG AA is checked for each text/background pair the app uses; ratios are
   noted beside the roles. Light only for now: a dark theme is a second
   variable block, nothing else. */

/* IBM Plex, served by the service itself (font-src 'self', ADR-0013 CSP):
   Sans for reading, Sans Condensed for page titles, Mono for ids, keys and
   source. Each directory is version-named like every other static asset. */
@font-face { font-family: "IBM Plex Sans"; font-weight: 400; font-style: normal; font-display: swap; src: url("/static/ibm-plex-sans-1.1.0/IBMPlexSans-Regular.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-weight: 400; font-style: italic; font-display: swap; src: url("/static/ibm-plex-sans-1.1.0/IBMPlexSans-Italic.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-weight: 500; font-style: normal; font-display: swap; src: url("/static/ibm-plex-sans-1.1.0/IBMPlexSans-Medium.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans"; font-weight: 600; font-style: normal; font-display: swap; src: url("/static/ibm-plex-sans-1.1.0/IBMPlexSans-SemiBold.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Sans Condensed"; font-weight: 600; font-style: normal; font-display: swap; src: url("/static/ibm-plex-sans-condensed-2.0.0/IBMPlexSansCondensed-SemiBold.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 400; font-style: normal; font-display: swap; src: url("/static/ibm-plex-mono-2.5.0/IBMPlexMono-Regular.woff2") format("woff2"); }
@font-face { font-family: "IBM Plex Mono"; font-weight: 500; font-style: normal; font-display: swap; src: url("/static/ibm-plex-mono-2.5.0/IBMPlexMono-Medium.woff2") format("woff2"); }

:root {
  /* Surfaces: graphite with a slight teal bias. */
  --canvas: #F5F7F7;          /* the page behind the cards */
  --surface: #FFFFFF;         /* cards, tables, inputs, the sidebar */
  --sunken: #EEF2F2;          /* table heads, code, quiet fills */
  --border: #DDE4E4;          /* hairlines between things */
  --control-edge: #7D8E90;    /* inputs and outlined buttons: 3.4:1 on white (WCAG 1.4.11) */

  /* Text. */
  --ink: #142022;             /* 16.7:1 on white, 15.5:1 on canvas */
  --muted: #5C6B6D;           /* 5.6:1 on white, 4.9:1 on sunken */

  /* The accent: thorax teal. Primary buttons, links, the current page, focus. */
  --accent: #0F6B73;          /* 6.2:1 on white; white on it 6.2:1 */
  --accent-hover: #0B5862;    /* white on it 8.1:1 */
  --accent-soft: #E3F1F2;     /* the current page's fill; accent on it 5.4:1 */
  --on-accent: #FFFFFF;

  /* State, and nothing else: each text color on its own fill and on white. */
  --pass: #18794E;      --pass-bg: #E6F4EC;      /* 4.8:1 on its fill, 5.4:1 on white */
  --fail: #B3261E;      --fail-bg: #FCE9E7;      /* 5.6:1, 6.5:1 */
  --errored: #A15C07;   --errored-bg: #FDF0E1;   /* infrastructure, not an assertion: 4.6:1, 5.2:1 */
  --running: #1F5FBF;   --running-bg: #E8F0FC;   /* in flight, information: 5.3:1 */
  --idle-bg: var(--sunken);                      /* pending, skipped, cancelled: muted on it 4.9:1 */

  --font-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-title: "IBM Plex Sans Condensed", "IBM Plex Sans", "Arial Narrow", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  font-family: var(--font-sans); font-size: 14px; line-height: 1.5; color: var(--ink); background: var(--canvas);
}
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; background: var(--canvas); }
strong, b { font-weight: 600; }
code, pre, kbd { font-family: var(--font-mono); font-size: .92em; }
h1, h2, h3 { line-height: 1.25; text-wrap: balance; }
h1 { font-family: var(--font-title); font-weight: 600; font-size: 1.75rem; margin: 0 0 .5rem; letter-spacing: -.005em; }
h1 code { font-family: var(--font-mono); font-weight: 500; font-size: 1.35rem; overflow-wrap: anywhere; }
h2 { font-size: 1.05rem; font-weight: 600; margin: 1.25rem 0 .5rem; }
h3 { font-size: .95rem; font-weight: 600; margin: 1rem 0 .4rem; }
.card > h2:first-child, .card > h3:first-child { margin-top: 0; }
p { margin: .5rem 0; }

/* ── The shell ───────────────────────────────────────────────────────────
   Signed out: the brand alone above a centered sign-in card. Signed in
   (shell.js sets body.signed-in when it shows the nav): a grouped sidebar
   beside the page, folding into a top bar on narrow screens. */
.bar { display: flex; align-items: center; padding: 1rem 1.5rem; }
.brand { display: inline-flex; align-items: center; gap: .55rem; font-weight: 600; font-size: 1rem; color: var(--ink); text-decoration: none; }
.brand:hover { color: var(--ink); }
.brand .mark { width: 2.4rem; height: 2.4rem; flex: none; }
#nav { display: flex; flex-direction: column; gap: .1rem; }
#nav a, #nav button { display: block; width: 100%; text-align: left; padding: .38rem .6rem; border: 0; border-radius: 6px; background: none;
  color: var(--ink); text-decoration: none; font: inherit; font-size: .93rem; cursor: pointer; }
#nav a:hover, #nav button:hover { background: var(--sunken); color: var(--ink); }
#nav a[aria-current="page"] { background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.nav-group { margin: 1rem .6rem .3rem; font-size: .72rem; font-weight: 500; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.nav-foot { margin-top: auto; padding-top: .75rem; border-top: 1px solid var(--border); display: grid; gap: .1rem; }

body.signed-in { display: grid; grid-template-columns: 15rem minmax(0, 1fr); align-items: start; }
body.signed-in > .bar { grid-column: 1; grid-row: 1; }
body.signed-in > main { grid-column: 2; grid-row: 1; }
body.signed-in .bar { position: sticky; top: 0; height: 100vh; flex-direction: column; align-items: stretch; gap: .75rem;
  padding: 1rem .75rem; background: var(--surface); border-right: 1px solid var(--border); overflow-y: auto; }
body.signed-in .brand { padding: .25rem .6rem .5rem; }
body.signed-in #nav { flex: 1; }

main { padding: 1.5rem 2rem 3rem; max-width: 80rem; width: 100%; margin: 0 auto; }

@media (max-width: 56rem) {
  body.signed-in { display: block; }
  body.signed-in .bar { position: static; height: auto; flex-direction: row; flex-wrap: wrap; align-items: center; gap: .5rem;
    padding: .6rem 1rem; border-right: 0; border-bottom: 1px solid var(--border); overflow: visible; }
  body.signed-in #nav { flex-direction: row; flex: 1 1 100%; overflow-x: auto; gap: .2rem; }
  #nav a, #nav button { width: auto; white-space: nowrap; }
  .nav-group { display: none; }
  .nav-foot { margin: 0; padding: 0; border: 0; display: flex; }
  main { padding: 1rem; }
  /* A wide table scrolls inside its card, never the page. Safe here: the
     editor's panel stops being sticky below 64rem, so no sticky child
     depends on the card's overflow. */
  .card { overflow-x: auto; padding: 1rem; }
}

/* ── Surfaces ──────────────────────────────────────────────────────────── */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: 8px; padding: 1.25rem 1.5rem; margin-bottom: 1rem; }
.card > :last-child { margin-bottom: 0; }
.muted { color: var(--muted); }
a { color: var(--accent); text-underline-offset: 2px; }
a:hover { color: var(--accent-hover); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
hr { border: 0; border-top: 1px solid var(--border); }

/* Tables: quiet heads, hairline rows, figures that line up. */
table { border-collapse: collapse; width: 100%; font-variant-numeric: tabular-nums; }
th, td { text-align: left; padding: .55rem .75rem; border-bottom: 1px solid var(--border); vertical-align: top; }
thead th { background: var(--sunken); color: var(--muted); font-weight: 500; font-size: .8rem; white-space: nowrap; }
tbody tr:hover > td { background: var(--canvas); }
tbody tr:last-child > td { border-bottom: 0; }
td code { font-size: .88em; }
td pre { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; font-size: .85em; }
pre.failure { color: var(--fail); background: var(--fail-bg); border-left: 3px solid var(--fail); border-radius: 0 4px 4px 0; padding: .35rem .6rem; min-width: 12rem; }

/* State. Text colors for words in a sentence or a cell; .pill for a status
   that stands alone (one vocabulary across lists, headings, containers,
   steps and checks). Errored is amber: a timeout or a lost container is not
   a failed assertion. */
.outcome-passed { color: var(--pass); } .outcome-failed { color: var(--fail); }
.outcome-errored { color: var(--errored); } .outcome-skipped { color: var(--muted); }
.pill { display: inline-flex; align-items: center; gap: .35rem; padding: .12rem .55rem; border-radius: 999px; font-family: var(--font-sans);
  font-size: .8rem; font-weight: 500; line-height: 1.35; white-space: nowrap; vertical-align: middle; background: var(--idle-bg); color: var(--muted); }
.pill::before { content: ""; width: .4rem; height: .4rem; border-radius: 50%; background: currentColor; flex: none; }
.pill.outcome-passed { background: var(--pass-bg); color: var(--pass); }
.pill.outcome-failed { background: var(--fail-bg); color: var(--fail); }
.pill.outcome-errored, .pill.status-errored { background: var(--errored-bg); color: var(--errored); }
.pill.status-running, .pill.status-launching { background: var(--running-bg); color: var(--running); }
.pill.status-running::before { animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) { .pill.status-running::before { animation: none; } }

/* Messages: a notice, a refusal or an error reason reads as a banner. */
p.outcome-passed, p.outcome-failed, p.outcome-errored, p.warn, div.warn, .banner {
  border: 1px solid var(--border); border-left-width: 3px; border-radius: 6px; padding: .55rem .8rem; color: var(--ink); background: var(--surface); }
p.outcome-passed { border-color: var(--pass); background: var(--pass-bg); }
p.outcome-failed, p.outcome-errored[role="alert"] { border-color: var(--fail); background: var(--fail-bg); }
p.outcome-errored { border-color: var(--errored); background: var(--errored-bg); }
p.warn, div.warn, .banner.warn { border-color: var(--errored); background: var(--errored-bg); }
.banner { border-color: var(--running); background: var(--running-bg); margin: .5rem 0; }
.banner p { margin: .35rem 0; }
span.warn, td.warn { color: var(--errored); }
tr.outcome-errored > td { color: var(--fail); }

/* ── Forms ─────────────────────────────────────────────────────────────── */
label { display: block; margin: .8rem 0 .3rem; font-weight: 500; }
label .muted { font-weight: 400; }
input, select, textarea { font: inherit; color: var(--ink); background: var(--surface); border: 1px solid var(--control-edge); border-radius: 6px; }
input, select { padding: .45rem .6rem; min-width: 18rem; max-width: 100%; }
select[multiple] { padding: .25rem; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
input[type=radio], input[type=checkbox] { min-width: 0; margin: 0 .5rem 0 0; accent-color: var(--accent); }
input[type=file] { border: 0; padding: .3rem 0; }
input.wide { width: 100%; }
fieldset.slot { border: 1px solid var(--border); border-radius: 8px; margin: 1rem 0; padding: .5rem 1rem .9rem; }
fieldset.slot legend { padding: 0 .35rem; font-weight: 600; }
fieldset.slot label { display: flex; align-items: baseline; font-weight: 400; }

/* Buttons: a form's submit is the primary action (filled accent), every
   other button secondary (outlined); class="primary", "secondary" or
   "danger" overrides that where the markup knows better (Launch beside
   Resolve, Deactivate). The overrides come later at equal specificity. */
button { font: inherit; font-weight: 500; padding: .45rem .9rem; cursor: pointer; border-radius: 6px; border: 1px solid var(--control-edge);
  background: var(--surface); color: var(--ink); line-height: 1.3; }
button:hover { background: var(--sunken); }
button[type=submit], #cli-allow { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
button[type=submit]:hover, #cli-allow:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
button.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
button.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
button.secondary { background: var(--surface); border-color: var(--control-edge); color: var(--ink); }
button.secondary:hover { background: var(--sunken); }
button.danger { background: var(--surface); border-color: var(--fail); color: var(--fail); }
button.danger:hover { background: var(--fail-bg); }
button.linklike { background: none; border: 0; padding: 0; color: var(--accent); text-decoration: underline; text-underline-offset: 2px; font-weight: 400; }
button.linklike:hover { color: var(--accent-hover); background: none; }
button[disabled] { cursor: not-allowed; opacity: .6; }
/* A link that does what a secondary button does (Configure from this run). */
a.button { display: inline-block; font-weight: 500; padding: .45rem .9rem; border-radius: 6px; border: 1px solid var(--control-edge);
  background: var(--surface); color: var(--ink); text-decoration: none; line-height: 1.3; }
a.button:hover { background: var(--sunken); color: var(--ink); }
.actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin: .75rem 0 .25rem; }
.actions form { margin: 0; }
.lineage code { font-size: .85em; }
/* A save with problems still to fix names them and steps back. */
button[data-ready="false"], button[data-ready="false"]:hover { background: var(--sunken); border-color: var(--border); color: var(--muted); }

/* ── The sign-in card and the other pre-app views ──────────────────────── */
body:not(.signed-in) main { max-width: 26rem; padding-top: 3rem; }
.hero { padding: 2rem 1.75rem; }
.hero h1 { text-align: center; font-size: 1.5rem; }
.hero .mark { display: block; width: 5.5rem; height: 5.5rem; margin: 0 auto .75rem; }
.hero input { width: 100%; min-width: 0; }
.hero form button, .hero > p > button { width: 100%; margin-top: .4rem; }
#sign-in-note:empty { display: none; }
#sign-in-note { text-align: center; }

/* ── Code, diffs, artifacts ─────────────────────────────────────────────── */
img.artifact { max-width: 100%; border: 1px solid var(--border); border-radius: 6px; }
figure { margin: .75rem 0; }
textarea.code, pre.code { font-family: var(--font-mono); font-size: .85rem; width: 100%; }
textarea.code { padding: .6rem .7rem; line-height: 1.6; }
pre.code { background: var(--sunken); border: 1px solid var(--border); padding: .75rem; overflow-x: auto; border-radius: 6px; }
.editor-host { border: 1px solid var(--control-edge); border-radius: 6px; min-height: 24rem; background: var(--surface); overflow: hidden; }
.editor-host .cm-scroller { font-family: var(--font-mono); font-size: .85rem; line-height: 1.6; }
table.diff { font-family: var(--font-mono); font-size: .8rem; }
table.diff td { padding: 0 .4rem; border: 0; }
table.diff tr:hover > td { background: none; }
table.diff pre { margin: 0; white-space: pre-wrap; }
table.diff td.ln { color: var(--muted); text-align: right; width: 3rem; user-select: none; }
table.diff td.op { width: 1rem; user-select: none; }
tr.diff-insert > td, tr.diff-insert:hover > td { background: var(--pass-bg); }
tr.diff-delete > td, tr.diff-delete:hover > td { background: var(--fail-bg); }

/* ── Groups, labels, packages ──────────────────────────────────────────── */
ul.tree { list-style: none; padding: 0; margin: .5rem 0; }
ul.tree li { padding-block: .3rem; border-bottom: 1px solid var(--border); }
ul.tree li:last-child { border-bottom: 0; }
.depth-1 { padding-left: 1.5rem; } .depth-2 { padding-left: 3rem; } .depth-3 { padding-left: 4.5rem; }
.depth-4 { padding-left: 6rem; } .depth-5, .depth-6, .depth-7, .depth-8, .depth-9 { padding-left: 7.5rem; }
ul.labels { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem .9rem; }
ul.labels code { font-size: .8rem; background: var(--sunken); border: 1px solid var(--border); border-radius: 4px; padding: .05rem .4rem; }
.inherited { font-style: italic; }

/* ── Authoring editors (plan 2026-10-03-web-authoring-and-drafts §3.6): the
   editor beside its problems and readiness on wide screens, stacked below. */
.editor-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr); gap: 1.5rem; align-items: start; }
.editor-side { position: sticky; top: 1rem; max-height: calc(100vh - 2rem); overflow-y: auto; background: var(--canvas);
  border: 1px solid var(--border); border-radius: 8px; padding: .25rem 1rem 1rem; }
@media (max-width: 64rem) { .editor-grid { grid-template-columns: minmax(0, 1fr); } .editor-side { position: static; max-height: none; } }
.editor-side h2, .editor-main h2 { font-size: .95rem; margin: 1rem 0 .5rem; }
.editor-meta { margin-top: -.25rem; }
.draft-status { font-size: .88rem; margin: .25rem 0 .75rem; color: var(--muted); } .draft-dot { color: var(--pass); }
ul.problems { list-style: none; padding: 0; margin: 0; display: grid; gap: .5rem; }
li.problem { border-left: 3px solid var(--fail); border-radius: 0 6px 6px 0; padding: .45rem .7rem; background: var(--surface); }
li.problem.warning { border-left-color: var(--errored); background: var(--errored-bg); }
li.problem p { margin: .15rem 0; } li.problem code { font-size: .8rem; word-break: break-word; }
li.problem .where { font-size: .8rem; color: var(--muted); }
li.problem .options button { margin: .25rem .25rem 0 0; font-size: .82rem; padding: .2rem .5rem; text-align: left; }
.count { display: inline-block; min-width: 1.4rem; text-align: center; border-radius: 999px; font-size: .75rem; font-weight: 600; padding: .05rem .45rem; vertical-align: middle; }
.count.error { background: var(--fail-bg); color: var(--fail); } .count.warning { background: var(--errored-bg); color: var(--errored); }
ul.checklist { list-style: none; padding: 0; margin: .25rem 0 .75rem; display: grid; gap: .25rem; }
/* The marks are drawn: Plex has no ✓, and a fallback face's glyph reads as √.
   The text glyphs stay in the markup for the accessible name's sake (hidden). */
ul.checklist li { display: flex; gap: .5rem; align-items: baseline; }
ul.checklist li > span[aria-hidden="true"] { display: none; }
ul.checklist li::before { content: ""; width: .7rem; height: .7rem; border-radius: 50%; border: 1.5px solid var(--control-edge); flex: none; transform: translateY(.08rem); }
ul.checklist li.done::before { border-color: var(--pass); background: var(--pass); box-shadow: inset 0 0 0 2px var(--canvas); }
ul.checklist li.todo { color: var(--muted); }
.slot-actions { margin: .4rem 0 .2rem; font-size: .9rem; }
.inherited-flights ul { margin: .2rem 0 .6rem; padding-left: 1.2rem; }
.inherited-flights li { margin: .15rem 0; }
.candidate-list { list-style: none; margin: .25rem 0; padding: .25rem; border: 1px solid var(--border); border-radius: 6px; max-height: 16rem; overflow-y: auto;
  background: var(--surface); box-shadow: 0 6px 16px -8px rgb(20 32 34 / 25%); }
.candidate-list button { display: block; width: 100%; text-align: left; border: 0; border-radius: 4px; background: none; color: var(--ink); font-weight: 400; padding: .3rem .6rem; }
.candidate-list button[aria-selected="true"], .candidate-list button:hover { background: var(--accent-soft); color: var(--ink); }
.candidate-list button.needs { color: var(--muted); }
.needs-note { color: var(--errored); font-size: .85rem; }
[data-stale] { opacity: .55; transition: opacity .2s; }
details.palette { margin-top: 1rem; border-top: 1px solid var(--border); padding-top: .5rem; }
details.palette summary { cursor: pointer; font-weight: 600; }
ul.palette-steps { list-style: none; padding: 0; margin: .4rem 0; }
ul.palette-steps li { border-bottom: 1px solid var(--border); padding: .4rem 0; }
ul.palette-steps li p { margin: .1rem 0; font-size: .85rem; }
ul.palette-steps li[data-usable="false"] code { color: var(--muted); }
ul.palette-steps button { font-size: .8rem; padding: .15rem .5rem; }
details > summary { cursor: pointer; }

/* WHY !important: an author rule that sets display (#nav's flex) beats the
   browser's own [hidden] { display: none }, which left the signed-in nav
   visible on the sign-in page; the shell shows and hides views by the hidden
   attribute alone (shell.js). Last in the file as well, so tools that
   resolve by source order alone (jsdom, T-SHELL-3) agree with browsers. */
[hidden] { display: none !important; }
