/* Tool pages. Loads after /styles.35430c1e.css and reuses its tokens, so the palette,
   type and spacing stay identical to the rest of the site.

   Every tool uses the same accent. One variable rather than a literal, so the
   whole set changes in one place; per-tool colours were tried and dropped. */
:root { --threat: var(--accent-2); }

.tool-head { padding: 40px 0 22px; }
.tool-kicker {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--threat); margin: 0 0 10px;
}
.tool-head h1 { font-size: clamp(1.7rem, 4vw, 2.4rem); margin: 0 0 12px; line-height: 1.15; }
.tool-head .lede { max-width: 62ch; margin: 0; text-align: left; }

.panel {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 12px; padding: 20px;
}
.io { display: grid; gap: 16px; grid-template-columns: 1fr 1fr; }
@media (max-width: 780px) { .io { grid-template-columns: 1fr; } }

.io label, .findings h2, .reference h2 { font-size: .95rem; font-weight: 600; }
.io textarea, .io .out, .panel > div > textarea {
  width: 100%; min-height: 190px; margin-top: 8px;
  background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: 9px;
  padding: 12px 14px; font-family: var(--mono); font-size: .92rem; line-height: 1.6;
  resize: vertical; white-space: pre-wrap; word-break: break-word; overflow: auto;
}
.io textarea:focus-visible, .io .out:focus-visible { outline: 2px solid var(--threat); outline-offset: 2px; }
.io .row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.count { font-family: var(--mono); font-size: .78rem; color: var(--muted); }

.actions { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; align-items: center; }
/* The example is the primary action while the field is empty — a visitor with no
   hostile text to paste has nothing else to do here. Once there is input, the
   cleaned output is what they came for and takes the emphasis instead. */
.sample-note { margin: 12px 0 0; color: var(--muted); font-size: .88rem; max-width: 68ch; }
.sample-note.hidden { display: none; }
.actions .btn { cursor: pointer; font-family: inherit; }
button.btn.primary { background: var(--accent); color: #07101f; border-color: var(--accent); }
button.btn.primary:hover { background: #8bbcff; }
button.btn:disabled { opacity: .5; cursor: not-allowed; }

/* Verdict — the whole point of the tool. Stripping invisibles leaves output
   that looks identical to the input, so the count has to be stated loudly. */
.verdict {
  margin-top: 18px; padding: 16px 18px; border-radius: 10px;
  border: 1px solid var(--border); background: var(--bg);
  border-left: 4px solid var(--threat);
}
.verdict.clean { border-left-color: var(--muted); }
/* `bad` and `warn` were set by three tools and never defined, so a banner saying
   the text was damaged rendered in the same green as a clean one. They match the
   truncation cards: red for damage, amber for intact but wrong. */
.verdict.bad { border-left-color: #e06c58; background: color-mix(in srgb, #e06c58 7%, var(--bg)); }
.verdict.warn { border-left-color: #e0a458; background: color-mix(in srgb, #e0a458 6%, var(--bg)); }
.verdict .headline { font-size: 1.12rem; font-weight: 600; margin: 0; }
.verdict .sub { margin: 6px 0 0; color: var(--muted); font-size: .92rem; }

/* The reveal. A table says what was removed; this shows where it sat, which is
   the part that makes the attack legible — a brand name split down the middle. */
.reveal-wrap { margin-top: 22px; }
.reveal-wrap h2 { font-size: .95rem; font-weight: 600; margin: 0 0 6px; }
.reveal-note { color: var(--muted); font-size: .88rem; margin: 0 0 10px; max-width: 68ch; }
.reveal {
  background: var(--bg); border: 1px solid var(--border); border-radius: 9px;
  padding: 14px 16px; font-family: var(--mono); font-size: .95rem; line-height: 2.1;
  white-space: pre-wrap; word-break: break-word; max-height: 260px; overflow: auto;
}
.reveal:focus-visible { outline: 2px solid var(--threat); outline-offset: 2px; }
.reveal-gap { color: var(--muted); opacity: .7; padding: 0 .35em; user-select: none; }
.reveal-trim { margin: 8px 0 0; color: var(--muted); font-size: .82rem; font-family: var(--mono); }
.cp-badge {
  display: inline-block; font-family: var(--mono); font-size: .72rem;
  padding: 1px 5px; margin: 0 1px; border-radius: 4px; vertical-align: baseline;
  background: var(--threat); color: #07101f; font-weight: 600; cursor: help;
}

table.findings-table { width: 100%; border-collapse: collapse; margin-top: 14px; font-size: .9rem; }
table.findings-table th, table.findings-table td {
  text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border); vertical-align: top;
}
table.findings-table th {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); font-weight: 500;
}
table.findings-table td.cp { font-family: var(--mono); color: var(--accent-2); white-space: nowrap; }
table.findings-table td.n { font-family: var(--mono); text-align: right; font-variant-numeric: tabular-nums; }
.tablescroll { overflow-x: auto; }

.chip {
  display: inline-block; font-family: var(--mono); font-size: .74rem;
  padding: 1px 7px; border-radius: 5px; border: 1px solid var(--threat);
  color: var(--threat); white-space: nowrap;
}
/* .chip is used on both spans and buttons. The transparent background comes
   from the base rule in styles.css; these are the button affordances. */
button.chip { font-family: var(--mono); font-size: .74rem; line-height: inherit; }
button.chip:hover { background: color-mix(in srgb, var(--threat) 16%, transparent); }
button.chip:active { background: color-mix(in srgb, var(--threat) 26%, transparent); }

.equiv { margin-top: 26px; }
.equiv pre {
  background: var(--bg); border: 1px solid var(--border); border-radius: 9px;
  padding: 14px 16px; overflow-x: auto; font-family: var(--mono); font-size: .86rem; margin: 8px 0 0;
}
.equiv .tabs { display: flex; gap: 8px; flex-wrap: wrap; }
.equiv .tab {
  font-family: var(--mono); font-size: .78rem; padding: 5px 11px; cursor: pointer;
  color: var(--muted); border: 1px solid var(--border); border-radius: 7px;
}
.equiv .tab[aria-selected="true"] { color: var(--threat); border-color: var(--threat); }

.reference { margin-top: 44px; }
.reference p { color: var(--muted); max-width: 68ch; }
.engine-note { margin-top: 30px; font-size: .85rem; color: var(--muted); }
.engine-note code { font-family: var(--mono); color: var(--accent-2); }

/* Tools index */
.tool-list { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); padding: 8px 0 20px; }
.tool-card {
  background: var(--panel); border: 1px solid var(--border);
  border-left: 3px solid var(--threat);
  border-radius: 12px; padding: 20px; display: flex; flex-direction: column; gap: 8px;
}
.tool-card h3 { margin: 0; font-size: 1.05rem; }
.tool-card h3 a { color: var(--fg); }
.tool-card p { margin: 0; color: var(--muted); font-size: .93rem; }
.tool-card .meta { margin-top: auto; padding-top: 12px; font-family: var(--mono); font-size: .72rem; color: var(--muted); }
.tool-card.soon { opacity: .62; }

/* Trojan Source: the two readings side by side. The left pane is deliberately
   rendered with the browser's own bidi algorithm applied — that is the point, it
   shows what a reviewer sees. The right pane replaces each control with a badge,
   so nothing remains to reorder and the bytes appear in logical order. */
.two-views { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 20px; }
@media (max-width: 860px) { .two-views { grid-template-columns: 1fr; } }
.two-views h2 { font-size: .95rem; font-weight: 600; margin: 0 0 4px; }
.view-note { color: var(--muted); font-size: .82rem; margin: 0 0 8px; }
.view {
  background: var(--bg); border: 1px solid var(--border); border-radius: 9px;
  padding: 12px 14px; font-family: var(--mono); font-size: .86rem; line-height: 1.9;
  min-height: 190px; max-height: 340px; overflow: auto;
  white-space: pre-wrap; word-break: break-word; margin: 0;
}
.view.rendered { color: var(--muted); }
.code-line { display: flex; gap: 12px; align-items: baseline; }
.line-no {
  color: var(--muted); opacity: .6; user-select: none; text-align: right;
  min-width: 2.4ch; flex: none; font-variant-numeric: tabular-nums;
}
.line-body { white-space: pre-wrap; word-break: break-word; }

/* The source pane is code, so it wants to be taller than a text field. */
#input { min-height: 210px; }

/* Confusables: rows where the two digit policies disagree are the point of the
   table, so they carry the accent rather than being left to the reader to spot. */
table.findings-table tr.differs td { background: color-mix(in srgb, var(--threat) 8%, transparent); }
table.findings-table tr.differs td:first-child { box-shadow: inset 3px 0 0 var(--threat); }

/* A confusable character is visible, unlike an invisible one, so the chip shows
   the glyph as well as its codepoint — the glyph is the thing that fooled you,
   and the codepoint is the proof. */
.conf-chip {
  display: inline-flex; align-items: baseline; gap: .3em;
  padding: 1px 6px; margin: 0 2px; border-radius: 5px;
  background: color-mix(in srgb, var(--threat) 16%, transparent);
  border: 1px solid var(--threat); cursor: help; line-height: 1.4;
}
.conf-chip b { font-weight: 600; color: var(--fg); font-style: normal; }
.conf-chip i { font-size: .68em; font-style: normal; color: var(--threat); letter-spacing: .02em; }

/* Zalgo: depth is the signal, so the chip carries it and the shade rises with it.
   Depths 1 and 2 stay quiet — that is where ordinary orthography lives. */
.zal-chip {
  display: inline-flex; align-items: baseline; gap: .25em;
  padding: 1px 4px; margin: 1px; border-radius: 4px; line-height: 1.9;
  border: 1px solid transparent;
}
.zal-chip b { font-weight: 400; font-style: normal; color: var(--fg); }
.zal-chip i {
  font-size: .62em; font-style: normal; color: var(--bg);
  background: var(--threat); border-radius: 3px; padding: 0 3px; font-weight: 700;
}
.zal-chip.d0 i { display: none; }
.zal-chip.d1 { background: color-mix(in srgb, var(--muted) 12%, transparent); }
.zal-chip.d1 i { background: var(--muted); }
.zal-chip.d2 { background: color-mix(in srgb, var(--muted) 18%, transparent); }
.zal-chip.d2 i { background: var(--muted); }
.zal-chip.d3 { background: color-mix(in srgb, #e0a458 22%, transparent); border-color: #e0a458; }
.zal-chip.d3 i { background: #e0a458; }
.zal-chip.d4 { background: color-mix(in srgb, #e06c58 26%, transparent); border-color: #e06c58; }
.zal-chip.d4 i { background: #e06c58; }

/* Hostname labels, shown apart so the script of each is visible — the TLD's
   script is half the question and it is easy to overlook when the name is one
   string. */
.labels { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-top: 14px; }
.label-box {
  display: flex; flex-direction: column; gap: 2px;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 12px;
}
.label-box.flagged { border-color: var(--threat); background: color-mix(in srgb, var(--threat) 10%, transparent); }
.label-box b { font-family: var(--mono); font-size: 1rem; font-weight: 600; color: var(--fg); }
.label-box span { font-size: .72rem; color: var(--muted); }
.label-box.flagged span { color: var(--threat); }
.label-dot { font-family: var(--mono); color: var(--muted); font-size: 1.1rem; }

.host-chip {
  font-family: var(--mono); font-size: .82rem; cursor: pointer;
  background: var(--panel); color: var(--fg);
  border: 1px solid var(--border); border-radius: 7px; padding: 5px 10px;
}
.host-chip:hover { border-color: var(--threat); }
#example-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
#input.host { min-height: 0; height: auto; }

/* Whole-script confusables: the string is drawn exactly like Latin, so every
   impostor character carries its codepoint and what it folds to. */
.char-chip {
  display: inline-flex; align-items: baseline; gap: .3em;
  padding: 1px 6px; margin: 1px 2px; border-radius: 5px;
  background: color-mix(in srgb, var(--threat) 14%, transparent);
  border: 1px solid var(--threat); cursor: help;
}
.char-chip b { font-weight: 600; font-style: normal; color: var(--fg); font-size: 1.02em; }
.char-chip i { font-size: .64em; font-style: normal; color: var(--threat); white-space: nowrap; }
#chars {
  background: var(--bg); border: 1px solid var(--border); border-radius: 9px;
  padding: 14px 16px; font-family: var(--mono); font-size: .95rem; line-height: 2.2;
  word-break: break-word;
}
.char-summary { margin: 10px 0 0; font-size: .9rem; color: var(--muted); }
.char-summary strong { color: var(--fg); }

/* Whitespace: the classification is the signal, so the chip carries it. The
   blind-spot class — renders blank, but the caller's own whitespace test says
   no — is the one the page exists to show, so only it takes the threat colour.
   Ordinary spaces are never chipped at all; they are rendered as spaces. */
.ws-chip {
  display: inline-flex; align-items: baseline; gap: .3em;
  padding: 1px 5px; margin: 0 2px; border-radius: 5px; line-height: 1.7;
  border: 1px solid var(--border); background: color-mix(in srgb, var(--muted) 12%, transparent);
  cursor: help; white-space: nowrap;
}
.ws-chip b { font-weight: 600; font-style: normal; color: var(--fg); font-size: .82em; }
.ws-chip i { font-size: .62em; font-style: normal; color: var(--muted); letter-spacing: .02em; }
.ws-chip .flag {
  font-size: .6em; font-weight: 700; letter-spacing: .03em;
  color: var(--bg); background: var(--threat); border-radius: 3px; padding: 0 3px;
}
.ws-chip.ws-blind { background: color-mix(in srgb, var(--threat) 16%, transparent); border-color: var(--threat); }
.ws-chip.ws-blind i { color: var(--threat); }
.ws-chip.ws-line { border-style: dashed; }

.left-note {
  margin: 14px 0 0; padding: 12px 14px; font-size: .92rem; color: var(--muted);
  background: var(--panel); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: 0 8px 8px 0;
}
.left-note strong { color: var(--fg); }

/* Filenames: the reveal is a comparison of two rows, not an annotation of one.
   The chips are deliberately identical in style between the rows — the whole
   point is that the two forms look the same — so the difference has to come
   from the codepoints and the byte counts, not from colour. */
.form-row { margin: 0 0 10px; }
.form-label {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: .82rem; font-weight: 600; color: var(--fg); margin: 0 0 5px;
}
.form-label em { font-style: normal; font-weight: 400; color: var(--muted); font-size: .92em; }
.form-label .tag {
  font-family: var(--mono); font-size: .72em; font-weight: 700; letter-spacing: .04em;
  color: var(--bg); background: var(--muted); border-radius: 3px; padding: 1px 5px;
}
.form-meta { margin-left: auto; font-weight: 400; color: var(--muted); font-family: var(--mono); font-size: .92em; }
.fn-strip {
  display: flex; flex-wrap: wrap; gap: 3px; padding: 9px 10px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 8px;
  overflow-x: auto;
}
.fn-chip {
  display: inline-flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 3px 5px; border-radius: 5px; border: 1px solid transparent; min-width: 2.1em;
}
.fn-chip b { font-family: var(--mono); font-weight: 500; font-size: .95em; color: var(--fg); }
.fn-chip i { font-family: var(--mono); font-style: normal; font-size: .58em; color: var(--muted); }
.fn-chip.non-ascii {
  background: color-mix(in srgb, var(--threat) 15%, transparent);
  border-color: var(--threat);
}
.fn-chip.non-ascii i { color: var(--threat); }

/* The parameter selects sit in the action bar beside the buttons. */
.sel {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: .85rem; color: var(--muted);
}
.sel select {
  font: inherit; font-size: .95em; color: var(--fg); background: var(--panel);
  border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px;
}
.sel select:hover { border-color: var(--accent); }

/* Graphemes: for once the damage is visible, so the three cuts sit side by side
   and the styling only has to say which one is correct. */
.limit-row {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 14px 0 4px;
  font-size: .88rem; color: var(--muted);
}
.limit-row label { font-weight: 600; color: var(--fg); }
.limit-row input[type="range"] { flex: 1 1 200px; min-width: 160px; accent-color: var(--threat); }
.limit-row output {
  font-family: var(--mono); font-weight: 700; color: var(--threat);
  min-width: 2.2em; text-align: right;
}
.limit-unit { font-size: .92em; }
.sec-h { font-size: .95rem; font-weight: 600; margin: 20px 0 8px; }

.cuts { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; }
.cut {
  background: var(--panel); border: 1px solid var(--border);
  border-left: 3px solid var(--border); border-radius: 0 9px 9px 0; padding: 12px 14px;
}
/* The disarm card is the product, not one of three equal options. It gets the
   full border, a tinted ground and a badge; the other two are what the caller's
   own standard library does, and are labelled as such. Without that the three
   cards read as an authorless comparison and the page stops demonstrating
   anything. */
.cut.good {
  border-color: var(--threat); border-left-color: var(--threat);
  background: color-mix(in srgb, var(--threat) 8%, var(--panel));
  order: -1;
}
/* A mangled cut is the finding, so it carries the same visual weight as the
   disarm card and the opposite colour. Amber sits between: nothing is broken,
   but the limit bought fewer characters than it promised. */
.cut.broken {
  border-color: #e06c58; border-left-color: #e06c58;
  background: color-mix(in srgb, #e06c58 12%, var(--panel));
}
.cut.broken .cut-body { color: #ffb9ac; }
.cut.broken .cut-badge { color: #2a0d08; background: #e06c58; border-color: #e06c58; }
.cut.short {
  border-color: #e0a458; border-left-color: #e0a458;
  background: color-mix(in srgb, #e0a458 10%, var(--panel));
}
.cut.short .cut-badge { color: #2a1c08; background: #e0a458; border-color: #e0a458; }
.cut.short .cut-note strong { color: #e0a458; }
.cut-head { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.cut-who { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.cut-head strong { font-size: .9rem; color: var(--fg); }
.cut-head > span { font-family: var(--mono); font-size: .7rem; color: var(--muted); }
.cut-badge {
  font-family: var(--mono); font-size: .62rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  padding: 2px 6px; border-radius: 4px;
  color: var(--muted); border: 1px solid var(--border);
}
.cut-badge.disarm {
  color: var(--bg); background: var(--threat); border-color: var(--threat);
}
.cut-badge.disarm::before { content: "\203A"; margin-right: .35em; font-weight: 700; }
.cut.good .cut-note strong { color: var(--fg); }
.cut-body {
  font-family: var(--mono); font-size: 1.35rem; line-height: 1.5; min-height: 1.9em;
  padding: 8px 10px; background: var(--bg); border-radius: 7px;
  word-break: break-word; white-space: pre-wrap;
}
.cut-note { margin: 8px 0 0; font-size: .8rem; color: var(--muted); line-height: 1.5; }
.cut.broken .cut-note strong { color: #e06c58; }

/* One box per user-perceived character. The multi-codepoint ones are the only
   ones a naive cut can land inside, so only they are marked. */
#clusters { display: flex; flex-wrap: wrap; gap: 5px; padding: 10px; background: var(--bg);
  border: 1px solid var(--border); border-radius: 8px; overflow-x: auto; }
.gr-cluster {
  display: inline-flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 5px 8px; border-radius: 6px; border: 1px solid var(--border); min-width: 2.4em;
}
.gr-cluster b { font-size: 1.25rem; font-weight: 400; line-height: 1.25; }
.gr-cluster i { font-family: var(--mono); font-style: normal; font-size: .56rem; color: var(--muted); }
.gr-cluster.multi { border-color: var(--threat); background: color-mix(in srgb, var(--threat) 13%, transparent); }
.gr-cluster.multi i { color: var(--threat); }

/* A C0 control has no glyph, so a table cell holding one renders as nothing at
   all — an empty box where the reader expects to see the character. Show its
   abbreviation in a frame instead, the way a hex editor would. */
.ctl-box {
  display: inline-block; font-family: var(--mono); font-size: .72em; font-weight: 600;
  padding: 0 4px; border: 1px dashed var(--muted); border-radius: 3px; color: var(--muted);
}

/* The index is organised by mechanism, which only helps a reader who already
   knows what they are looking at. The router is the other door in: a symptom
   is what someone actually arrives with. */
.router { margin: 8px 0 34px; }
.router h2 { font-size: 1.15rem; margin: 0 0 6px; }
.router-note { color: var(--muted); font-size: .93rem; margin: 0 0 14px; max-width: 62ch; }
.symptoms { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.symptoms li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .5em;
  padding: 9px 12px; background: var(--panel);
  border: 1px solid var(--border); border-left: 3px solid var(--threat); border-radius: 0 8px 8px 0;
}
.symptoms a { font-weight: 600; font-size: .95rem; }
.symptoms span { color: var(--muted); font-size: .88rem; }

/* The corpus behind the confusables supplement came from mined misses. A link
   costs nothing and points at the one thing a visitor has that the project
   does not: a string that broke for them. */
.report-miss {
  margin: 30px 0 0; padding: 12px 14px; font-size: .9rem; color: var(--muted);
  background: var(--panel); border: 1px dashed var(--border); border-radius: 9px;
}

/* Said next to the feature, because "we do not upload your text" and "here is a
   link containing your text" look contradictory until you know where the text
   actually lives. */
.share-note { margin: 8px 0 0; font-size: .82rem; color: var(--muted); max-width: 66ch; }

/* The ellipsis costs one cluster, one codepoint, one UTF-16 unit — and three
   bytes. Which is the page's argument, applied to the marker itself. */
.ell-toggle {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: .85rem; color: var(--muted); cursor: pointer;
}
.ell-toggle input { accent-color: var(--threat); cursor: pointer; }

/* The copy button tells a visitor to paste the sample elsewhere; this is where
   they bring it back, which is the half of the demonstration that was missing. */
.round-trip { margin-top: 22px; padding: 14px 16px; background: var(--panel);
  border: 1px dashed var(--border); border-radius: 10px; }
.round-trip textarea {
  width: 100%; min-height: 0; margin-top: 6px; background: var(--bg); color: var(--fg);
  border: 1px solid var(--border); border-radius: 8px; padding: 9px 11px;
  font-family: var(--mono); font-size: .9rem; resize: vertical;
}

/* Two strings overlaid. Shared text is printed plainly as context; a badge
   marks a codepoint present in only one of them. A and B get different colours
   because "which side is this on" is the question being asked — but neither is
   the bad one, so neither takes the threat colour. */
#diff {
  padding: 11px 13px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 9px; font-family: var(--mono); font-size: .95rem; line-height: 2.1;
  white-space: pre-wrap; word-break: break-word; overflow-x: auto;
}
.diff-chip {
  display: inline-flex; align-items: baseline; gap: .3em;
  padding: 1px 5px; margin: 0 2px; border-radius: 5px; cursor: help;
  border: 1px solid; white-space: nowrap;
}
.diff-chip s { text-decoration: none; font-size: .58em; font-weight: 700; letter-spacing: .04em; }
.diff-chip b { font-weight: 500; font-style: normal; color: var(--fg); }
.diff-chip i { font-size: .6em; font-style: normal; }
.diff-chip.only-a {
  border-color: #6ea8fe; background: color-mix(in srgb, #6ea8fe 15%, transparent);
}
.diff-chip.only-a s, .diff-chip.only-a i { color: #9ec5ff; }
.diff-chip.only-b {
  border-color: #e0a458; background: color-mix(in srgb, #e0a458 15%, transparent);
}
.diff-chip.only-b s, .diff-chip.only-b i { color: #e8bd7f; }

/* The narrowest fix is the answer; the rest are context. */
.findings-table tr.narrowest td { background: color-mix(in srgb, var(--threat) 9%, transparent); }
.findings-table tr.narrowest td:first-child { font-weight: 700; }
