/* The comparison screen. Loaded only by /so-sanh, so nothing here is on the document
   page's first-screen budget. Colours come from the tokens app.css already defines;
   the five change kinds are the only new hues, and each is defined for both themes. */

.crumbs { font-size: 13px; color: var(--muted); margin: 18px 0 6px; }
.crumbs a { color: var(--muted); }

/* The band. `.dochero` in doc.css carries the photograph, the wash and the card; this is
   only what a comparison needs and a document does not — the same division `catalogue.css`
   makes, and the reason this page's band is now the same object as that one's rather than
   a second thing that looks like it. Until 2026-09-20 it was a bare heading, which made
   `/so-sanh` the one tab of three arriving without the band.

   `inherit`, because `.doc-page .dochero h1` is serif on the stated ground that the title
   there is the law's own. "So sánh 2 văn bản luật" is a label this site wrote, so it
   belongs in the sans the rest of the interface speaks — the same correction `.cat-hero`
   makes for "Danh mục văn bản", and the seam the two families exist to keep straight. */
.chero { margin: 0 0 18px; }
/* `.doc-page` in the selector, not decoration: the rule being overridden is
   `.doc-page .dochero h1`, two classes to a bare `.chero h1`'s one. Written without it
   the heading came back serif, and a later stylesheet does not make a weaker selector
   win. Same shape `.cat-hero h1` needed, which reaches for `!important` instead. */
.doc-page .chero h1 { font-family: inherit; font-size: clamp(24px, 3.4vw, 34px);
  margin: 0 0 8px; line-height: 1.15; letter-spacing: normal; max-width: 62%; }
@media (max-width: 900px) { .doc-page .chero h1 { max-width: 100%; } }
.chero h1 em { font-style: normal; color: var(--accent); }
/* 56ch, down from 68: the wash clears around 62% of the band's width and the photograph
   begins. A measure set for a plain paragraph put the last words of this one over the
   sky. Same number `.cat-hero .lead` is held to, for the same reason. */
.chero .lead { margin: 0; color: var(--muted); max-width: 56ch; line-height: 1.6; }

/* ---- the picker bar ---- */
/* Tops aligned, not bottoms: each side now carries a fact card under its field, and the
   two cards are different heights whenever one document has a number and the other does
   not. Aligning the bottoms made the two search fields sit on different lines. */
.cbar {
  display: grid; grid-template-columns: 1fr auto 1fr auto; gap: 12px; align-items: start;
  padding: 16px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--panel); margin-bottom: 14px;
}
.cpick { min-width: 0; }
/* Sentence case with a glyph, not micro-caps. The label names the thing the field holds,
   and mockup 3 gives it the weight of a heading — at 11px uppercase tracking it read as a
   form's fine print, which is what the field under it is not. */
.cpicklabel {
  margin: 0 0 7px; display: flex; align-items: center; gap: 7px;
  font-size: 15px; font-weight: 600; color: var(--head);
}
.cpicklabel .ico { width: 17px; height: 17px; color: var(--accent); flex: 0 0 auto; }
/* The field carries the magnifier the rest of the site's search fields carry. It is
   `.cmag` and not `.mag`: `.mag` is `app.css`'s, sized for the 52px hero pill, and this
   field is 38px. */
.cpick .searchbox { position: relative; }
.cmag {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  color: var(--muted); display: flex; pointer-events: none;
}
.cmag .ico { width: 15px; height: 15px; }
.cpick input {
  width: 100%; padding: 9px 11px 9px 33px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--bg); color: var(--ink); font: inherit;
  font-size: 16px;
}

/* What is in the field right now, stated as facts rather than as a sentence. The three
   are what tell a reader they picked the wrong edition — two editions share a title.

   One row, document then facts, as mockup 3 draws it. Stacked — which is what this was —
   the card ran taller than the field it describes and pushed the two sides of the chooser
   apart. `wrap`, so the facts drop under the document rather than crushing it when the
   window is narrow; the rule between them moves with them. */
/* The strip that stays put. `top` is the site bar's measured height (67px at every width
   it is pinned at) plus a hair, the same way `.crail` carries 68 — there is no
   `--header-h` on this page, because `app.js` sets that one and a server-rendered page
   does not load it.

   `z-index:4`, one below the bar's 5: this tucks under the bar, it does not cover it.
   That is the whole complaint being answered, so the number is not arbitrary. The
   background is opaque for the same reason — a sticky band with a transparent ground
   shows the rows sliding through it. */
.cpinned {
  position: sticky; top: 67px; z-index: 4;
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  padding: 9px 0; margin-bottom: 4px; background: var(--bg);
  /* A hairline, so the rows passing under the band end on an edge rather than at the
     point where one white ground stops and another starts. It is drawn at rest too: there
     it reads as the rule between the chooser and the comparison, which is what it is. */
  border-bottom: 1px solid var(--line);
}
/* One line, clamped, while pinned: two documents with titles of different lengths gave
   the band two different heights, and a band that changes height as the page scrolls
   under it is the same defect as one that slides. */
.cpinned .cpicktitle { -webkit-line-clamp: 1; }
.cpickcard {
  padding: 11px 13px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--bg);
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
}
.cpickwho { flex: 1 1 210px; min-width: 0; display: flex; align-items: flex-start; gap: 9px; }
/* Same class as the home screen's table badge, on purpose — one name for one object, so
   the two cannot drift apart by accident. The rules are here because `/so-sanh` does not
   load `blocks.css`. */
.cpickwho .tbadge {
  flex: 0 0 auto; margin-top: 1px; padding: 2px 7px; border-radius: 6px;
  background: var(--accent-soft); color: var(--accent);
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
}
/* Number over title, not beside it: the số hiệu is the identifier and the title is what
   confirms it, and side by side the title's ellipsis ate the confirmation first. */
.cpickid { margin: 0; min-width: 0; display: grid; gap: 2px; }
.cpicknum {
  font-weight: 700; font-size: 13.5px; color: var(--accent); text-decoration: none;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.cpicknum:hover { text-decoration: underline; }
.cpicknum.quiet { color: var(--muted); font-weight: 600; }
.cpicktitle {
  min-width: 0; font-size: 12.5px; color: var(--muted); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.cpickfacts {
  margin: 0; flex: 0 1 auto; display: flex; gap: 18px;
  border-left: 1px solid var(--line); padding-left: 14px;
}
.cpickfacts > div { min-width: 0; }
.cpickfacts dt {
  display: flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 500; letter-spacing: normal; text-transform: none;
  color: var(--muted); margin: 0 0 2px;
}
.cpickfacts dt .ico { width: 13px; height: 13px; flex: 0 0 auto; }
.cpickfacts dd { margin: 0; font-size: 13px; line-height: 1.35;
  font-variant-numeric: tabular-nums; }
/* The verdict under the date. Two lines rather than one, because neither answers the
   reader's question alone — a date does not say whether the text still applies, and a
   verdict does not say since when. */
/* `nowrap`, and it is what keeps the pinned strip one height for every pair: the longest
   verdict this corpus prints is "bị đình chỉ một phần", and wrapped it would make the
   band taller for some documents than for others while `.crail` clears a fixed number. */
.cverdict { display: flex; align-items: center; gap: 5px; margin-top: 2px;
  font-size: 12px; font-weight: 600; font-variant-numeric: normal; white-space: nowrap; }
.cverdict .cdot { width: 6px; height: 6px; border-radius: 99px;
  background: currentColor; flex: 0 0 auto; }
/* Below this the two sides are already stacked by `.cbar`, and the facts have the whole
   width: the rule becomes a horizontal one under the document, which is the shape the
   card had before and the right one at this size. */
@media (max-width: 760px) {
  .cpickfacts { flex: 1 1 100%; border-left: 0; padding-left: 0;
    border-top: 1px solid var(--line); padding-top: 9px; }
}
/* Four tones, not seven verdicts. `unknown` is deliberately its own: 21k documents in
   this corpus are legitimately unknown, and painting them as repealed would assert a
   verdict the corpus does not hold.

   Prefixed `ce-`, not `e-`: doc.css:275 already owns `.e-unknown` as a pill badge with a
   border and a ground, and this page loads doc.css. Under the bare name the one verdict
   the corpus is honest about rendered inside what looked like an empty input box. */
/* On `.cverdict` since 2026-09-20, not on the `dd`: the cell now holds a date above the
   verdict, and colouring the cell painted the date with the verdict's tone — a red
   "15/01/2024" states nothing about that date. */
.cpickfacts .ce-ok { color: var(--high); }
.cpickfacts .ce-warn { color: var(--medium); }
.cpickfacts .ce-off { color: var(--k-drop); }
.cpickfacts .ce-unknown { color: var(--muted); font-weight: 500; }
.cpickfacts .quiet { color: var(--muted); }

/* The document chooser. Two lines per row — the name a reader recognises, then the
   facts that separate two documents sharing a số hiệu — left-aligned, because a list
   of names is read down its left edge. */
.cpicklist {
  position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + 4px);
  margin: 0; padding: 4px; list-style: none; max-height: 320px; overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: 9px;
  box-shadow: 0 8px 26px -12px rgba(0, 0, 0, .35);
}
.cpicklist[hidden] { display: none; }
.cpicklist li { margin: 0; }
.cpicklist button {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  font: inherit; color: var(--ink); padding: 8px 10px; border-radius: 6px;
  cursor: pointer;
}
.cpicklist button span {
  display: block; font-size: 13.5px; line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cpicklist button small {
  display: block; margin-top: 2px; font-size: 11.5px; color: var(--muted);
}
.cpicklist button:hover, .cpicklist button:focus-visible {
  background: var(--accent-soft); outline: none;
}
.cswap, .cgo {
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg);
  color: var(--ink); font: inherit; padding: 9px 13px; cursor: pointer;
}
/* Both sit level with the two search fields rather than with the labels above them:
   the swap acts on the fields, and the submit repeats the pair they hold.

   29px, not 22: the offset is the height of the label row, and that row grew when the
   label stopped being 11px micro-caps (21.7px of line plus 7px of margin). A number tuned
   against the old label left both buttons riding above the fields they act on, so it is
   written here as what it measures rather than as a value that once looked right. */
.cswap {
  font-size: 17px; line-height: 1; margin-top: 29px; border-radius: 50%;
  width: 38px; height: 38px; padding: 0;
}
.cgo { background: var(--accent-solid); border-color: var(--accent-solid);
       color: var(--on-accent); font-weight: 600; margin-top: 29px; white-space: nowrap; }
.cswap:hover, .cgo:hover { filter: brightness(1.06); }

/* ---- the ready-made pairs, under the empty chooser ---- */
/* Both fields are free text over the whole corpus, and a reader arriving at an empty
   screen has to fill two of them before anything happens. These are the replacements the
   screen is asked for most; they also show what the screen does, which two empty search
   boxes do not.

   A chip, not a table row: the name and the two years are the whole fact, and nine of
   them wrap into two lines at every width the picker is read at. */
.cquick { margin: 0 0 18px; }
.cquick h2 {
  margin: 0 0 9px; font-size: 13px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .06em;
}
.cquick ul { margin: 0; padding: 0; list-style: none; display: flex;
             flex-wrap: wrap; gap: 8px; }
.cquick a {
  display: flex; align-items: baseline; gap: 8px; text-decoration: none;
  padding: 8px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--ink); line-height: 1.3;
}
.cquick a:hover, .cquick a:focus-visible {
  border-color: var(--accent); background: var(--accent-soft); outline: none;
}
.cqname { font-size: 13.5px; font-weight: 600; }
/* Tabular, and never broken across lines: "2013 → 2024" is one fact and the arrow is the
   middle of it. */
.cqyears {
  font-size: 12.5px; color: var(--muted); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.cquick a:hover .cqyears, .cquick a:focus-visible .cqyears { color: var(--accent); }

.cnote, .cwarn {
  margin: 0 0 14px; padding: 11px 14px; border-radius: 10px; font-size: 13.5px;
  line-height: 1.55; border: 1px solid var(--line); background: var(--panel);
  color: var(--muted);
}
/* Amber and marked, not grey. This is the one sentence on the page that says the
   alignment is computed; printed in the same grey as the row counter, it read as
   furniture and a reader could take the grid below as something an issuer published. */
.cnote {
  display: flex; gap: 10px; align-items: flex-start;
  border-color: var(--medium); background: var(--k-edit-bg); color: var(--ink);
}
.cnoteicon {
  flex: none; width: 18px; height: 18px; border-radius: 50%; margin-top: 1px;
  background: var(--medium); color: var(--on-accent); font-size: 12px; font-weight: 700;
  line-height: 18px; text-align: center;
}
.cnote b, .cnote strong { color: var(--ink); }
.cwarn { border-color: var(--k-drop); background: var(--k-drop-bg); color: var(--ink); }

/* ---- the whole comparison at a glance ---- */
.cmap { display: flex; align-items: center; gap: 12px; margin: 0 0 14px; }
.cmaplabel {
  margin: 0; font-size: 10.5px; font-weight: 600; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted); line-height: 1.3; white-space: nowrap;
}
.cmapbars {
  flex: 1; min-width: 0; display: flex; gap: 1px; height: 26px; padding: 2px;
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel);
  overflow-x: auto;
}
/* Each bar takes an equal share, but never thins below a pixel a reader can aim at:
   a 900-row pair scrolls sideways instead of becoming a smear. */
.cmapbars a {
  flex: 1 0 auto; min-width: 3px; border-radius: 1px; background: var(--kc);
  opacity: .72;
}
.cmapbars a:hover { opacity: 1; }
.cmapbars a.here { opacity: 1; box-shadow: inset 0 0 0 1.5px var(--ink); }

/* The one page on this site that is wider than `.wrap`'s 1180px. Two columns of
   statutory text at that width leave about 45 characters a line, which is below the
   comfortable range and makes every article twice as tall as it needs to be. 1560px is
   not a new number — it is what the site's own header and footer already use. */
main.wrap { max-width: 1560px; }

/* ---- the rail beside the rows ---- */
/* The summary stays answered while the reader scrolls, which the filter row above the
   stream stops doing the moment the list starts loading as they go. */
.clayout { display: grid; grid-template-columns: 250px minmax(0, 1fr); gap: 18px; }
/* 174px: the site bar (67, measured) plus the pinned fact strip (99, measured) plus 8 of
   air. It was 68 — the bar alone — and the rail then pinned itself *behind* the strip,
   which is the defect this page was just fixing one floor up.
   The 99 is a constant and not a coincidence: `.cpinned` clamps the title to one line and
   `.cverdict` refuses to wrap, so every pair in the corpus builds a band of the same
   height. Change either of those and this number is wrong. */
.crail { min-width: 0; align-self: start; position: sticky; top: 174px; }
.csum {
  display: flex; flex-direction: column; gap: 2px; padding: 13px 15px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel);
  margin-bottom: 10px;
}
.csum b { font-size: 21px; line-height: 1.1; font-variant-numeric: tabular-nums; }
.csum span { font-size: 12px; color: var(--muted); }

.ckinds {
  display: flex; flex-direction: column; padding: 6px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel);
}
.ckinds a {
  display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 8px;
  text-decoration: none; color: var(--ink); font-size: 13.5px;
  border-left: 3px solid transparent;
}
.ckinds a span { flex: 1; min-width: 0; }
.ckinds a b { font-variant-numeric: tabular-nums; color: var(--muted); font-weight: 600; }
.ckinds a:hover { background: var(--accent-soft); }
.ckinds a.on {
  background: var(--kc-bg, var(--accent-soft)); border-left-color: var(--kc, var(--accent));
  font-weight: 600;
}
.ckinds a.on b { color: var(--kc, var(--accent)); }

/* ---- filters ---- */
.cfilters {
  display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
}
.cfilters a {
  border: 1px solid var(--line); background: var(--panel); color: var(--ink);
  font-size: 12.5px; padding: 6px 13px; border-radius: 20px; text-decoration: none;
}
.cfilters a b { font-variant-numeric: tabular-nums; color: var(--muted); margin-left: 3px; }
.cfilters a.on { border-color: var(--kc, var(--accent)); background: var(--kc-bg, var(--accent-soft)); }
.cfilters a.on b { color: inherit; }
/* The unfiltered tab is the page's default state, so it is the one that reads as
   chosen — the five kind tabs carry their own hue and do not need a second one. */
.cfilters > a:first-child.on {
  background: var(--accent-solid); border-color: var(--accent-solid);
  color: var(--on-accent);
}
.cfilters > a:first-child.on b { color: inherit; opacity: .8; }

.ccount { margin: 0 0 11px; font-size: 12.5px; color: var(--muted); }

.cpager { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 16px; }
.cpager a, .cpager b {
  border: 1px solid var(--line); border-radius: 7px; padding: 5px 11px; font-size: 13px;
  text-decoration: none; color: var(--ink); font-variant-numeric: tabular-nums;
}
.cpager b { background: var(--accent-solid); border-color: var(--accent-solid);
            color: var(--on-accent); }
.cgap { color: var(--muted); padding: 0 2px; }

/* ---- load-as-you-scroll ---- */
/* The button is the visible half of the observer: it says what is about to happen, and
   it is what a reader clicks when the fetch failed or when they scroll faster than the
   network. Centred and quiet, so it reads as the end of the list rather than an action. */
.cfoot { display: flex; justify-content: center; padding: 14px 0 4px; }
.chead-load { padding: 0 0 12px; }
.cloadmore {
  border: 1px solid var(--line); background: var(--panel); color: var(--ink);
  border-radius: 20px; padding: 7px 18px; font-size: 13px; cursor: pointer;
  font-family: inherit;
}
.cloadmore:hover { border-color: var(--accent); color: var(--accent); }
.cloadmore:disabled { color: var(--muted); cursor: default; border-color: var(--line); }
.cfoot.cdone { color: var(--muted); font-size: 12.5px; padding: 16px 0 4px; }
/* On the counter line, so it reads as a note about the count rather than an action bar. */
.cwhole {
  border: 0; background: none; padding: 0; font: inherit; color: var(--accent);
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}
.cwhole:disabled { color: var(--muted); text-decoration: none; cursor: default; }

/* ---- one article, both sides ---- */
.crow {
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel);
  padding: 13px 15px 15px; margin-bottom: 11px; scroll-margin-top: 14px;
}
.crow[hidden] { display: none; }
.crow:focus-visible, .crow.sel { outline: 2px solid var(--accent); outline-offset: 1px; }
.crow.sel { background: var(--sel); }
.chead { display: flex; gap: 9px; align-items: baseline; flex-wrap: wrap; }
.cicon {
  width: 7px; height: 7px; border-radius: 2px; background: var(--kc); flex: none;
  transform: translateY(-1px);
}
.cheadnum { font-weight: 700; font-size: 14.5px; color: var(--ink); font-variant-numeric: tabular-nums; }
.cheadtitle { flex: 1; min-width: 0; font-weight: 600; font-size: 15.5px; }
.ckind {
  font-size: 11.5px; font-weight: 600; padding: 3px 10px; border-radius: 20px;
  background: var(--kc-bg); color: var(--kc); white-space: nowrap;
}
/* The row's headline figure, on the far right of its own line. Tabular digits so a
   column of them lines up when the reader is scanning for the heavily-changed rows. */
.cratio {
  margin-left: auto; font-size: 12.5px; color: var(--muted); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* The fold control. A chevron drawn in CSS rather than a glyph: "˅" sits on the text
   baseline and looked like a diacritic that had come loose from the heading. */
.cfold {
  flex: none; width: 26px; height: 26px; padding: 0; border: 0; background: none;
  cursor: pointer; border-radius: 6px; position: relative;
}
.cfold::before {
  content: ""; position: absolute; inset: 0; margin: auto; width: 8px; height: 8px;
  border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted);
  transform: translateY(-2px) rotate(-135deg); transition: transform .15s;
}
.cfold[aria-expanded="false"]::before { transform: translateY(-3px) rotate(45deg); }
.cfold:hover { background: var(--accent-soft); }
.cfold:hover::before { border-color: var(--accent); }
.crow.folded .cgrid, .crow.folded .cbadges, .crow.folded .cmore { display: none; }
.crow.folded { padding-bottom: 13px; }

.cbadges { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; }
.cbadges span {
  font-size: 11.5px; padding: 2px 8px; border-radius: 5px; border: 1px solid var(--line);
  color: var(--muted); font-variant-numeric: tabular-nums;
}
.cmoved { color: var(--ink) !important; font-weight: 600; }

.cgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 11px; }
/* Each side is a panel rather than bare text. Two columns of statutory prose with only
   a gap between them let the eye slide from the end of one line into the start of the
   other side's next one; a border and a ground stop that without tinting the text. */
.ccell {
  min-width: 0; padding: 11px 13px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg);
}
.ccell.empty {
  display: flex; align-items: center; justify-content: center; min-height: 64px;
  border: 1px dashed var(--line); border-radius: 8px; color: var(--muted);
  font-size: 13px; font-style: italic; padding: 12px; text-align: center;
}
.ccell.empty p { margin: 0; }
.corigin {
  margin: 0 0 6px; font-size: 11.5px; font-weight: 600; padding: 2px 8px;
  border-radius: 5px; display: inline-block;
  background: var(--kc-bg); color: var(--kc);
}
.ccell.old .corigin { background: var(--old-bg); color: var(--old-fg); }
.ccell.new .corigin { background: var(--new-bg); color: var(--new-fg); }
.cnum { margin: 0 0 2px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.ctitle { margin: 0 0 6px; font-size: 15px; line-height: 1.35; }
.cbody {
  margin: 0; font-size: 14.5px; line-height: 1.65; color: var(--ink);
  white-space: pre-wrap; overflow-wrap: break-word;
  max-height: 15em; overflow: hidden; position: relative;
}
.crow.open .cbody { max-height: none; }
.cbody.clamped::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 3em; pointer-events: none;
  /* Fades to the cell's own ground, which is `--bg` now that each side is a panel — and
     stays `--bg` inside a selected row, because `.ccell` sets it either way. */
  background: linear-gradient(to bottom, transparent, var(--bg));
}
.cmore {
  margin-top: 9px; border: 0; background: none; color: var(--accent); font: inherit;
  font-size: 13px; font-weight: 600; cursor: pointer; padding: 0;
}

del { background: var(--del-bg); color: var(--del-fg); text-decoration: line-through;
      text-decoration-thickness: 1px; border-radius: 2px; padding: 0 1px; }
ins { background: var(--ins-bg); color: var(--ins-fg); text-decoration: none;
      border-radius: 2px; padding: 0 1px; }

/* ---- the five kinds ----
   Four of the five reuse the status ramp app.css already defines — `--high` is what a
   page means by "good", `--medium` by "watch this", `--low` by "wrong" — so a reader who
   has seen a confidence badge already knows this scale. Only "viết lại" is a new hue,
   because the ramp has three steps and there are four states that are not neutral, and
   a rewrite is genuinely a fourth thing: nothing was added or removed, the provision was
   restated. The tints are new because the ramp ships ink without grounds. */
:root {
  --k-edit: var(--medium);  --k-edit-bg: #fbf2e0;
  --k-new: var(--high);     --k-new-bg: #e4f1e9;
  --k-drop: var(--low);     --k-drop-bg: #fbe9e6;
  --k-same: var(--muted);   --k-same-bg: #f0eeea;
  --k-rewrite: #5b46a8;     --k-rewrite-bg: #eeebf8;
  --old-bg: #f0eeea; --old-fg: #4a443d;
  --new-bg: #e4f1e9; --new-fg: #1f5a3c;
  --del-bg: #fbe3e0; --del-fg: #8a1c1c;
  --ins-bg: #dcf0e6; --ins-fg: #14563a;
  --sel: var(--mark);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* `--low` is the one step of the status ramp app.css leaves at its light value
       in dark mode, so it is restated here rather than inherited: #8a1c1c on the
       dark ground is 1.8:1 and the badge would read as switched off. */
    --k-drop: #e08a8a;
    --k-edit-bg: #332813; --k-new-bg: #143026; --k-drop-bg: #3a1f1c;
    --k-same-bg: #262420; --k-rewrite: #b0a0e8; --k-rewrite-bg: #26203b;
    --old-bg: #262420; --old-fg: #cfc8bd;
    --new-bg: #143026; --new-fg: #8ccfa8;
    --del-bg: #3d1f1c; --del-fg: #eda49c;
    --ins-bg: #12362a; --ins-fg: #7fd3ab;
  }
}
:root[data-theme="dark"] {
  --k-drop: #e08a8a;
  --k-edit-bg: #332813; --k-new-bg: #143026; --k-drop-bg: #3a1f1c;
  --k-same-bg: #262420; --k-rewrite: #b0a0e8; --k-rewrite-bg: #26203b;
  --old-bg: #262420; --old-fg: #cfc8bd;
  --new-bg: #143026; --new-fg: #8ccfa8;
  --del-bg: #3d1f1c; --del-fg: #eda49c;
  --ins-bg: #12362a; --ins-fg: #7fd3ab;
}
.k-edit    { --kc: var(--k-edit);    --kc-bg: var(--k-edit-bg); }
.k-rewrite { --kc: var(--k-rewrite); --kc-bg: var(--k-rewrite-bg); }
.k-new     { --kc: var(--k-new);     --kc-bg: var(--k-new-bg); }
.k-drop    { --kc: var(--k-drop);    --kc-bg: var(--k-drop-bg); }
.k-same    { --kc: var(--k-same);    --kc-bg: var(--k-same-bg); }
.crow[data-kind="edit"]    { --kc: var(--k-edit);    --kc-bg: var(--k-edit-bg); }
.crow[data-kind="rewrite"] { --kc: var(--k-rewrite); --kc-bg: var(--k-rewrite-bg); }
.crow[data-kind="new"]     { --kc: var(--k-new);     --kc-bg: var(--k-new-bg); }
.crow[data-kind="drop"]    { --kc: var(--k-drop);    --kc-bg: var(--k-drop-bg); }
.crow[data-kind="same"]    { --kc: var(--k-same);    --kc-bg: var(--k-same-bg); }

/* One filter on screen at a time, and which one depends on whether the rail has a column
   to stand in. Above 1100px the rail does, and it is `position:sticky` — it answers "what
   is in this comparison and which part am I looking at" and keeps answering it through
   288 rows, which the chip row cannot: the row scrolls away with the first screenful and
   the stream loads as the reader goes. So the chips stand down and the rail is the filter.

   Both are rendered, and that is deliberate rather than waste: they are the same six
   links, so neither width is left without a filter and there is no state where a script
   has to move a control between two places. Mockup 3 draws both at once; drawn in one
   static screenshot the repetition does not show, and on a screen that scrolls it does.
   USER read them as duplicates on 2026-09-20, which is the report this rule answers. */
@media (min-width: 1101px) {
  .cfilters { display: none; }
}
/* Below this the rail has nowhere to stand, so it goes above the rows and keeps only the
   count — the six links it carried are the same six the filter row already has, and
   printing them twice down a phone screen is two screens of the same navigation. */
@media (max-width: 1100px) {
  .clayout { grid-template-columns: minmax(0, 1fr); gap: 0; }
  /* Not pinned below this. The bar wraps to two rows here and the strip would take a
     third of a short viewport, which is the trade a phone cannot afford — and the rail,
     which is the other thing that stays put on a wide screen, has already gone static on
     the same line above. */
  .cpinned { position: static; }
  .crail { position: static; }
  .ckinds { display: none; }
  .csum { flex-direction: row; align-items: baseline; gap: 9px; }
}

@media (max-width: 900px) {
  .cmaplabel { display: none; }
  .cbar { grid-template-columns: 1fr; }
  .cswap, .cgo { margin-top: 0; }
  .cswap { justify-self: start; }
  .cgrid { grid-template-columns: 1fr; }
  .cpinned { grid-template-columns: 1fr; }
  /* `gap` only. This was `grid-template-columns`, which stopped doing anything when the
     fact row became a flex row on 2026-09-20 — a rule that reads as layout and is not. */
  .cpickfacts { gap: 14px; }
}

/* On a phone the header's five parts cannot share one line: the title, being the only
   thing that may shrink, was left a ~100px column and broke one word per line. Below
   this width the title takes a line of its own, indented by the icon's width so it
   starts under "Điều", and the number, the badge, the figure and the fold control keep
   the line above — reordered, not re-marked-up, so the reading order stays
   number → kind → title. */
@media (max-width: 640px) {
  .chead { row-gap: 5px; }
  .cratio { order: 1; }
  .cfold { order: 2; }
  .cheadtitle {
    order: 3; flex: 0 0 100%; box-sizing: border-box; padding-left: 16px;
  }
}
