/* ---------------------------------------------------------------------------
   Server-rendered document and article pages.

   These are read by people arriving from a search engine, on a phone, who have never
   seen this site before. Everything below is legible with scripting turned off; the
   only script on the page copies a citation, and its button is not rendered without it.
   --------------------------------------------------------------------------- */
/* ONE MEASURE FOR THE CHROME, ON EVERY PAGE OF THE SITE.
   The header here is `.wrap` — 1180px with 20px of padding — while the home screen's is
   `.topbar`, 1560 with 16. Measured at a 1600px viewport, the wordmark stood at x=29 on
   the home screen and at x=223 on `/van-ban`: clicking a tab in the header moved the
   header itself 194px to the right, which is the jump the owner reported on 2026-09-13.
   The tabs moved with it, so the label under the cursor was no longer under the cursor.
   The vertical padding is 8, not 10, for the same reason: at 10 the wordmark sat 5px
   lower than the one it replaced.
   The measure is `.topbar`'s, restated rather than shared, because the two headers are
   different markup — `.wrap` is also the page's content measure below, and widening
   `.wrap` itself would widen the reading column with it. `main.wrap` keeps 1180 and the
   catalogue and the comparison keep the 1560 they already ask for; only the chrome is
   pinned. If `.topbar`'s measure in app.css changes, change it here too. */
.doc-page header .wrap{display:flex;align-items:center;gap:12px 20px;
  max-width:1560px;padding:14px 16px;flex-wrap:wrap}
/* One `margin-left:auto` in the row, and it is `.topbar-end`'s own from app.css. It used to be
   zeroed here while `form.mini` carried the other one, so the two would not split the slack.
   The form has since lost its auto margin and grows instead — but only to its 380px cap, and
   past that cap the leftover width sat at the far right with the account pill parked beside
   the search box, not at the edge where the home screen puts it. The account end pushes;
   below the cap the form has already eaten the slack and the margin resolves to 0. */
/* The tabs are anchors here rather than the home screen's buttons, and an anchor inside
   `.tabs` already has the right rules in app.css. What it does not have is a reason to
   shrink: this row also holds a 380px search box, and at 1180px the four labels were the
   first thing to wrap. */
.doc-page .tabs a,.doc-page .tabs button{white-space:nowrap}
/* The account control drops to its circle well before a phone does, because this bar is
   the crowded one: the home screen's holds a wordmark, four tabs and two badges, and this
   one holds a 380px search box as well. 1180px is where the name and the plan stop
   fitting beside all of it — measured, not guessed — and losing them there is much
   cheaper than the whole right-hand end of the bar dropping onto a second line and
   sitting at the left margin under the wordmark, which is what it did. Both are written
   out in full inside the menu the circle opens. */
@media (max-width:1180px){
  .doc-page .acct-name,.doc-page .acct-plan{display:none}
  .doc-page .acct summary{padding:3px}
}
/* The header's search is the same pill as the home screen's, one size down. `flex:0 1`
   rather than the pill's own `1 1 420px`: on a 1180px document page an elastic search
   box pushes the wordmark to the left edge and takes the whole middle of the bar for a
   control the reader is not here to use. */
/* It grows into the slack rather than being a fixed 380px, and that is what keeps this
   row one row. `flex-wrap` places items at their *base* size and shrink never gets a
   chance: with a 380px basis, brand + tabs + box + the account pill came to 1201px in a
   1180px bar, so the whole right-hand end dropped to a second line and sat at the left
   margin under the wordmark. A 260px basis fits with room to spare and the grow takes it
   straight back up to 380 wherever there is space, so nothing is narrower than before on
   a wide screen. `margin-left:auto` is gone with the same change — an item that grows has
   no slack left to push against, and the growth does that job now. */
form.mini{padding:0;gap:8px;flex:1 1 260px;max-width:380px}
/* The pill's positioned wrapper, which the suggestion list drops out of. It is the flex
   item here, so it — not the pill — carries the sizing, and it must not keep the
   `1 1 420px` basis app.css gives it on the home screen: inside a form already capped at
   380px a 420px basis is the overflow the cap was written to prevent. */
form.mini .searchbox{flex:1 1 auto;min-width:0}
form.mini .searchpill{flex:1 1 auto;padding:3px 3px 3px 12px}
/* 4px of padding, not 6 and 7: the pill is the tallest thing in this row, so it — not the
   tabs — sets the height of the bar, and at 44px it stood the header 61px tall against the
   home screen's 54. That is the last 3px of the jump the measure above fixes; the wordmark
   landed at y=17 here and y=14 there. A 38px pill is the same height as a tab, so the row
   is now the tabs' row on both screens. */
form.mini .searchpill input[type=search]{font-size:16px;padding:4px 0}
form.mini .searchpill button{padding:4px 14px;font-size:14px}
.doc-page main{display:block;max-width:860px}
/* Wide enough for two columns, and only on a page that has a second column to put there.
   `:has()` is the whole switch: an article page, or a document with no relation, keeps
   the single centred measure instead of leaving a 316px hole beside it. A browser
   without `:has()` gets that same single column with the block stacked above the text —
   the layout this file shipped before, so the fallback is a layout, not a defect.

   The reading column is the one that must not move, so the aside is placed by rule
   (`grid-column:2`) and everything else falls into column 1 without the markup being
   rearranged: the DOM order stays the order a screen reader and a stacked phone get. */
/* The switch is `.rail` now, not `.related`, and that is the whole of the change: the
   rail exists on every document, while a relation edge exists on half of them. Keyed on
   the relation block, a document nothing cites got a single centred column and no table
   of contents — and the documents nothing cites are not the short ones. */
@media (min-width:1120px){
  .doc-page main:has(.rail){display:grid;grid-template-columns:minmax(0,1fr) 316px;
    gap:0 28px;max-width:1180px;align-items:start}
  .doc-page main:has(.rail)>*{grid-column:1}
  /* The hero is the page's masthead and belongs over both columns; everything else falls
     into column 1 by the rule above, so the rail's row is counted off that column —
     crumbs 1, hero 2, and row 3 is the panel holding the law, which is exactly where the
     rail should start. (Before 2026-09-12 row 3 was a properties card; the facts moved
     into the rail itself and the row number stayed correct by coincidence, so it is
     written down here rather than left to be rediscovered.) `span 999` gives the sticky
     box the whole remaining height to travel through, and `align-self:start` keeps it its
     own height rather than stretching to the bottom of the law. */
  .doc-page main:has(.rail)>.dochero{grid-column:1/-1}
  .doc-page main:has(.rail)>.rail{grid-column:2;grid-row:3/span 999;align-self:start;
    position:sticky;top:80px;max-height:calc(100vh - 100px);overflow:auto;
    display:flex;flex-direction:column;gap:16px;
    scrollbar-width:thin;scrollbar-color:var(--line) transparent}
  /* Thin instead of hidden: this box scrolls on its own axis while the page scrolls on
     another, and a reader who cannot see that needs to discover it by accident. Hidden
     scrollbars are right for the horizontal tab strip above, which fades at its edge to
     say "more"; a vertical sidebar has no such cue, so the bar itself is the cue — just
     not the full-width default one that made the panel look like a separate widget. */
  .doc-page main:has(.rail)>.rail::-webkit-scrollbar{width:6px}
  .doc-page main:has(.rail)>.rail::-webkit-scrollbar-track{background:transparent}
  .doc-page main:has(.rail)>.rail::-webkit-scrollbar-thumb{background:var(--line);
    border-radius:3px}
  .doc-page main:has(.rail)>.rail::-webkit-scrollbar-thumb:hover{background:var(--muted)}
  /* Narrow column: the number goes on its own line and the title is clamped, so eight
     entries stay eight scannable rows instead of a wall beside the law. */
  .doc-page main:has(.rail) ul.rel .n{display:block;margin:0 0 2px;white-space:normal}
  .doc-page main:has(.rail) ul.rel .t{display:-webkit-box;-webkit-line-clamp:2;
    -webkit-box-orient:vertical;overflow:hidden;font-size:13px}
  .doc-page main:has(.rail) .rail h2{font-size:15px}
  .doc-page main:has(.rail) .rail>*{padding:16px;margin:0}
}
/* Below 1120px the rail is not a column, it is blocks in the flow — and the sticky table
   of contents of a phone layout is a box that covers the law it indexes. The properties it
   must give back are all four: the grid is gone with the media query, but `position`,
   `max-height` and `overflow` are not inside it.

   The order is also wrong stacked, and that is the part worth explaining. In the DOM the
   rail precedes the law, because on a wide screen it is a column beside it and both a
   screen reader and the grid want it there. Stacked, that same order puts two cards — one
   of them a relation list up to twenty-four rows long — between the title and Điều 1, so
   a reader on a phone scrolls past a page of metadata to reach the thing they opened.

   `display:contents` dissolves the rail so its three children can be ordered
   individually against the law: identity and index before the text, because they are how
   you decide what to read; the relation list after it, because it is where you go next.
   A browser without `display:contents` ignores this block and gets the DOM order, which
   is the layout that shipped before — a fallback, not a defect. */
.rail{display:block}
.rail>*{margin-bottom:16px}
@media (max-width:1119px){
  .doc-page main{display:flex;flex-direction:column}
  .doc-page main>*{order:9}
  .doc-page .crumbs{order:0}
  .doc-page .dochero{order:1}
  .doc-page main .rail{display:contents}
  .doc-page #thuoc-tinh{order:2}
  .doc-page #muc-luc{order:3}
  .doc-page #toan-van{order:4}
  .doc-page #lien-quan{order:5}
  .doc-page .provenance{order:6}
  .doc-page .doc-notes{order:7}
  /* An index that is 48 entries tall is a second wall in front of the law. Scrolled in
     place it stays an index — the reader sees where they are in the document and can
     reach any of it, in 40% of the screen instead of four screens of it. */
  .doc-page #muc-luc{max-height:40vh;overflow:auto}
}
.crumbs{font-size:13px;color:var(--muted);margin:16px 0 12px}
.crumbs a{color:var(--muted)}
.crumbs a:hover{color:var(--accent)}
.doc-page h1{font-size:24px;line-height:1.35;margin:0 0 8px;letter-spacing:-.01em}
/* Rendering, not editing — see the note beside the same rule in app.css. The `.info`
   pages set their own h1 and are unaffected either way. */
.doc-page h1::first-letter{text-transform:uppercase}
.doc-page .panel{margin-bottom:16px}
/* Navy, like every block heading on the home screen. All three h2 in the article area are
   the site talking *about* a document ("Văn bản liên quan", "N điều", "Không tìm thấy nội
   dung này"); the document talking is always an h1 (`legal.ts` 215 and 313), which this
   rule does not touch and which keeps the law's serif and the law's ink. That split is
   the whole point of the two families, so a heading colour crossing it would undo more
   than it decorated.

   Scoped to `main`, and the scope is load-bearing. `.doc-page` is on <body>, so as
   `.doc-page h2` this also matched the shared footer's column headings — and at equal
   specificity with `.footlinks h2`, doc.css loading after app.css meant it won: "TRA CỨU",
   "AI" and "THÔNG TIN" were painted navy on the footer's near-black and disappeared, on
   every document page and every information page (their body carries both classes). */
.doc-page main h2{font-size:17px;margin:0 0 12px;color:var(--head)}
/* Văn bản liên quan. Each heading names a direction ("Thay thế" vs "Bị thay thế bởi"),
   so the heading has to stay attached to its list at every width — hence the group, not
   the section, carries the spacing. The count sits in the heading because a reader
   scanning for "bị thay thế" wants to know how many before opening anything. */
.related h3{margin:16px 0 8px;font-size:13px;font-weight:600;color:var(--muted);
  letter-spacing:.02em}
.related h3:first-of-type{margin-top:0}
.related h3 .count{font-weight:600}
.related details.rel-folded{margin-top:16px}
.related details.rel-folded>summary{cursor:pointer;font-size:13px;font-weight:600;
  color:var(--muted);letter-spacing:.02em;margin-bottom:8px}
.related details.rel-folded>summary .count{font-weight:600}
ul.rel{list-style:none;margin:0;padding:0}
ul.rel li{border-top:1px solid var(--line);padding:8px 0}
ul.rel li:first-child{border-top:0}
ul.rel a,ul.rel .dead{display:block;color:var(--ink);text-decoration:none;font-size:14px;
  line-height:1.5}
ul.rel a:hover{color:var(--accent)}
/* The offer to open this pair in /so-sanh. A separate control from the row itself, so
   it needs a boundary: `ul.rel a` is a block, and without these two lines the word
   "So sánh" became a second line of the entry that read like part of the title. */
ul.rel a.cmp{display:inline-block;margin-top:5px;padding:1px 9px;font-size:12px;
  font-weight:600;color:var(--accent);border:1px solid var(--line);border-radius:20px}
ul.rel a.cmp:hover{border-color:var(--accent);background:var(--accent-soft)}
/* Muted, not hidden: a related document the corpus does not hold is still a fact about
   this one, and greying it says the link is missing rather than the relation. */
ul.rel .dead{color:var(--muted)}
/* Blue, matching the số hiệu in the home screen's table and the `.tbadge` beside it.
   One colour means "this is a document" across the site; red was saying it here and ink
   was saying it there, so the same fact wore two colours depending on which screen you
   reached it from. */
ul.rel .n{color:var(--blue);font-weight:600;margin-right:8px;white-space:nowrap}
ul.rel .t{color:var(--muted)}
ul.rel .when{color:var(--muted);font-size:13px;white-space:nowrap}
/* Not `.more`: that class is the centred "xem thêm" of the results pane, and borrowing
   it centred a sentence in the middle of a left-aligned list. */
.related .rel-more{margin:8px 0 0;font-size:13px}
.related .source-note{margin:16px 0 0;padding-top:12px;border-top:1px solid var(--line);
  font-size:13px;line-height:1.55}
/* The document pages are a 1180px column; the home screen's 1560px footer would hang off
   both sides of it. */
/* The footer follows the header, and both are now the site's one chrome measure — so the
   1180 override that used to sit here is gone, and app.css's 1560/16 stands on every page.
   It was written to align the footer with a 1180 header; that header is 1560 as of
   2026-09-13, and the pair has to move together or the page ends narrower than it starts.
   It also ended the third mismatch on these two screens: `/van-ban` and `/so-sanh` already
   widen `main` to 1560, so the footer was the only 1180 box left on them. */
/* The same treatment the home screen's topbar gets at this width, and for the same
   measured reason: unwrapped, the four labels squeeze to min-content and every one of
   them breaks into a column of single words. Here there is a second reason — the row
   holds a search box as well, so at 430px the header stood 213px tall with brand, tabs,
   form and toggle each on a full-width line of their own. The strip scrolls on its own
   axis instead: one line of tabs, swiped, with a fade saying it continues. */
@media (max-width:820px){
  .doc-page .tabs{order:3;flex:1 0 100%;flex-wrap:nowrap;overflow-x:auto;
    scrollbar-width:none;mask-image:linear-gradient(90deg,#000 88%,transparent)}
  .doc-page .tabs::-webkit-scrollbar{display:none}
  .doc-page .topbar-end{order:2;margin-left:auto}
  form.mini{order:4;flex:1 1 100%;margin-left:0}
}
@media (max-width:640px){
  form.mini{margin-left:0;width:100%;flex:1 1 100%}
}

/* Printing: this must live beside the rule it overrides. Left in app.css it lost, because
   doc.css loads after it and the two selectors weigh the same. */
@media print{ .doc-page main{max-width:none} }

/* ---------------------------------------------------------------------------
   The hero band, the action row, the shelves and the rail — the 2026-09-12 pass.
   --------------------------------------------------------------------------- */

/* The band is a card, on the cards' own radius and the cards' own measure, because it is
   the top of a stack of cards and not a full-bleed masthead. The photograph is declared
   as separate longhands rather than the `background` shorthand: the shorthand resets
   `background-clip` and `background-origin`, and a rule written before it is silently
   thrown away — a trap this stylesheet's sibling fell into twice in one sitting. */
.dochero{position:relative;border-radius:12px;margin:0 0 16px;padding:24px 20px;
  background-color:var(--panel);border:1px solid var(--line);box-shadow:var(--card-shadow)}
/* Above the phone breakpoint only, and that is a data decision rather than a visual one:
   `banner.jpg` is 193 KB, and a rule that does not apply is a background a browser never
   fetches. A reader opening a decree on mobile data pays nothing for the decoration, and
   the band keeps the paper ground it already has. */
@media (min-width:641px){
  .dochero{padding:36px 32px;min-height:196px;display:flex;flex-direction:column;
    justify-content:center;border-color:transparent;
    background-image:
      linear-gradient(94deg,rgb(var(--sky)) 0%,rgb(var(--sky)) 38%,rgba(var(--sky),.92) 54%,
        rgba(var(--sky),.34) 72%,rgba(var(--sky),0) 86%),
      url(/img/banner.jpg);
    background-position:center 46%;background-size:cover;background-repeat:no-repeat}
}
.dochero .kicker{margin:0 0 8px;font-size:13px;color:var(--muted);letter-spacing:.02em}
/* Serif, because this is the law's own title and not a label the site wrote about it —
   the same reason `article.panel h1` is serif. Moving the title into the band would have
   quietly dropped it into the sans stack, which is the exact seam the two families exist
   to keep straight. The measure is capped so a long title stops before the wash clears
   and the words reach the photograph. */
.doc-page .dochero h1{font-family:var(--serif);font-size:34px;line-height:1.22;
  margin:0 0 16px;max-width:62%;letter-spacing:-.01em}
@media (max-width:900px){.doc-page .dochero h1{max-width:100%;font-size:24px}}
.docfacts{list-style:none;display:flex;flex-wrap:wrap;gap:8px;margin:0;padding:0;
  font-size:13px}
/* Each fact gets a ground of its own. On the band these sit over a photograph at its
   lightest, and 13px of `--muted` on a lit sky is the illegible row the home screen's
   chips already had to be given a pill for. */
.docfacts>li{background:var(--panel);border:1px solid var(--line);border-radius:99px;
  padding:4px 12px;color:var(--muted)}
.docfacts .f-issuer{color:var(--ink)}

/* The verdict. Four tones for seven states: `held` carries ngưng hiệu lực and both
   partial states, because each says "still law, but not all of it, or not now" — which
   a colour cannot tell apart and the label beside it can. Grey for unknown is load
   bearing: colouring silence would publish an inference the API layer refuses to make. */
.effect{display:inline-block;border-radius:99px;padding:3px 10px;font-size:13px;
  font-weight:600;white-space:nowrap}
.e-live{background:var(--t1b);color:var(--t1)}
.e-dead{background:var(--t6b);color:var(--t6)}
.e-held{background:var(--warn-soft);color:var(--warn)}
.e-unknown{background:var(--bg);color:var(--muted);border:1px solid var(--line)}
/* The badge is the value of this row, so the pill sits on the baseline of the sentence
   that explains it rather than above it. */
.docfacts .f-effect{padding:0;border:0;background:none}
/* Same box as the chips beside it: 4px 12px plus a 1px border (transparent unless the
   tone draws one), so the verdict is not a size smaller than the facts it closes. */
.docfacts .effect{padding:4px 12px;font-weight:400;border:1px solid transparent}
.docfacts .e-unknown{border-color:var(--line)}
/* One rule between the controls and the facts, not two. `dl.props` carries a border-top
   of its own for the article page, where it follows the law's text; directly under the
   action row that made a 20px corridor with a hairline on each side of it. */
.docactions + dl.props{border-top:0;padding-top:0;margin-top:0}
dl.props .wide{grid-column:1/-1}
dl.props .wide dd{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px;
  line-height:1.55}
dl.props .wide dd .quiet{font-size:13px;flex:1 1 320px;min-width:0}
dl.props .wide dd code{font:12px/1.4 var(--mono)}
/* Two sources disagreeing is not a decoration: it is printed in the warning ink the rest
   of the site uses for a fact it cannot vouch for. */
.suspect{color:var(--warn)}

/* Back, print, cite, share, source. `.act` restates the ground and the padding because
   the global `button` rule is a filled red control at 12/16 — one of these left unstyled
   would be five solid red rectangles across the top of a document page.

   The row ends in a rule of its own rather than borrowing the one on `dl.props`: the
   actions are not a property of the instrument, and running them into the same box made
   the first fact on the card look like a fifth button. */
.docactions{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0 0 20px;
  padding-bottom:20px;border-bottom:1px solid var(--line)}
/* The way out sits on the left and everything you can do with the document on the right,
   which is the mockup's arrangement and also the correct one: "back" undoes arriving
   here, and grouping it with "share" would file leaving under the same heading as acting. */
.docactions .back{margin-right:auto}
.docactions .act{display:inline-flex;align-items:center;gap:7px;
  background:var(--panel);color:var(--ink);border:1px solid var(--line);border-radius:8px;
  padding:7px 13px;font:14px/1.4 var(--sans);text-decoration:none;cursor:pointer;
  transition:border-color .12s,color .12s}
/* Grey until the button is hovered, then it takes the accent with the label. An icon set
   at full ink weight competes with the word beside it, and the word is the thing being
   read — the icon is there to be recognised in the corner of the eye. */
.docactions .ico{width:15px;height:15px;flex:0 0 auto;color:var(--muted)}
.docactions .act:hover,.docactions .act:focus-visible{border-color:var(--accent);
  color:var(--accent)}
.docactions .act:hover .ico,.docactions .act:focus-visible .ico{color:inherit}
/* The confirmation. Both glyphs are in the markup and one of them is always hidden, so
   saying "copied" costs no icon surgery in script — and a button whose script never ran
   shows its own icon and its own label, which is the state the server drew.
   The accent is the hover colour: the row already means "this one" in that red, and a
   sixth colour introduced for 1.6 seconds is a colour the palette has to keep. */
.docactions .act .ico.ok{display:none}
.docactions .act[data-said="done"] .ico{display:none}
.docactions .act[data-said="done"] .ico.ok{display:block;color:inherit}
.docactions .act[data-said]{border-color:var(--accent);color:var(--accent)}
/* On a phone five bordered pills wrap to three rows and the card opens with a wall of
   controls. The labels stay — an icon-only row is a quiz — but the row is allowed to
   scroll on its own axis instead, with the fade that says it continues. */
@media (max-width:640px){
  .docactions{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;
    mask-image:linear-gradient(90deg,#000 90%,transparent)}
  .docactions::-webkit-scrollbar{display:none}
  .docactions .act{flex:0 0 auto}
  /* `margin-right:auto` in a scrolling row pushes every sibling past the right edge. */
  .docactions .back{margin-right:0}
}

/* The shelves, in the hero row beside the status. Blue, not red: one colour means "this
   is a document or a way to reach documents" across the site, and rule 5 keeps red for
   identity, place, action and choice. A shelf label is a filter, and a filter is none of
   those — it is also the only thing in that row that is somebody else's filing opinion
   rather than the document's own words, which is why it is the one chip that is a link. */
.docfacts .f-shelf{padding:0;border:0;background:none}
/* The same neutral pill as the date beside it, not the blue it wore first. Blue means
   "this is a document or a way to reach one" elsewhere on the site, and the reasoning was
   that a shelf is a way to reach documents — but on this row it put a saturated colour
   next to a status badge that has to be the only coloured thing there. Colour in that row
   is the verdict; everything else is an outline. It is still a link and still says so, by
   taking the accent on hover and focus. */
.shelf{display:inline-block;background:var(--panel);color:var(--muted);border-radius:99px;
  padding:4px 12px;font-size:13px;text-decoration:none;border:1px solid var(--line)}
.shelf:hover,.shelf:focus-visible{color:var(--accent);border-color:var(--accent)}

/* The rail's information box. One column, so the label sits above its value rather than
   beside it: at 316px a two-column definition list gives the value 140px, and "BỘ KHOA
   HỌC VÀ CÔNG NGHỆ" is not a 140px value. */
.railbox .props{display:block;margin:0;padding:0;border:0}
.railbox .props>div{margin:0 0 12px}
.railbox .props>div:last-child{margin-bottom:0}
.railbox .props dd{font-size:14px;line-height:1.45}

/* The source line, closing the document: above the rule, pulled right, one line.

   The rule is this element's `border-bottom` rather than the notes box's `border-top`,
   and that is what puts the source on the document's side of it. `margin-left:auto` is
   not enough on its own for a block-level p — `text-align:right` is what moves the inline
   content, and the block stays full width so the border spans the column. */
.provenance{margin:0 0 20px;padding:12px 0;border-bottom:1px solid var(--line);
  text-align:right;font-size:13px;line-height:1.6;color:var(--muted);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.pv-label{font-size:12px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);
  margin-right:6px}
/* The CC BY credit, on the 8,344 documents whose text came from the TVPL snapshot. It is
   a sentence and the line above it is a host name, so it opts out of the nowrap/ellipsis
   the source link needs — clipped at the column edge, a licence term is not honoured. */
.pv-credit{display:block;margin-top:4px;white-space:normal;font-size:12px;
  line-height:1.5;opacity:.85}

/* The notes: what the verdict rests on, and what this page is not. One box, because both
   are the site speaking about the law — the reader meets them together at the point where
   they decide what to do with what they have read. */
.doc-notes{margin:0 0 40px;padding:14px 16px;border:1px solid var(--line);
  border-radius:12px;background:var(--panel)}
.doc-notes p{margin:0;color:var(--muted);font-size:13px;line-height:1.6}
/* Stacked here, unlike on the source line: this label introduces a sentence, and a
   sentence that starts after an inline label reads as a continuation of it. */
.doc-notes .pv-label{display:block;margin:0 0 2px}
.doc-notes .quiet{font-size:13px}

/* The action row is inside the text panel now, above the count of articles. It keeps its
   rule: the panel's own edge is 24px away at the top of the card, and without a line of
   its own the buttons read as the first row of the document rather than as controls over
   it — which is what the row looked like before it had one. */
.panel .docactions{padding-bottom:16px;margin-bottom:16px}

/* The rail's table of contents. Navigation, so sans and quiet — the Mục lục column is not
   the law, and setting it in the law's face is the mistake `ol.toc` was fixed for from
   the other direction. `.on` is painted by page.js as the reader scrolls. */
.railnav{list-style:none;margin:0;padding:0;font-size:13px}
.railnav li{border-top:1px solid var(--line)}
.railnav li:first-child{border-top:0}
.railnav a{display:block;padding:7px 0 7px 10px;color:var(--muted);text-decoration:none;
  line-height:1.45;border-left:2px solid transparent;margin-left:-12px}
.railnav a:hover{color:var(--ink)}
.railnav a.on{color:var(--accent);border-left-color:var(--accent);font-weight:600}
.railnav .n{font-weight:600;margin-right:6px;color:inherit}
/* Clamped to two lines: an article title can be a sentence, and fifty of them unclamped
   turn a 316px column into a second document standing beside the first.

   The clamp is on the inner span, not on the anchor, and that is the whole fix for what
   the first attempt looked like on screen. `-webkit-line-clamp` cuts the *content box* at
   N lines while the element's padding stays where it is, so clamping a padded anchor left
   a third line sliced through the middle showing under every long entry. The span carries
   no padding, so two lines is two lines. */
.railnav .ln{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden}



/* An anchored heading must not land under the sticky header — 172px of chrome swallowing
   the first line of the Điều a reader just clicked is the failure this project already
   measured once. */
.doc-page :target,ol.toc>li[id],h3.division[id],section.annex[id]{scroll-margin-top:88px}

.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap}

/* ---------------------------------------------------------------------------
   The law's own text, wherever it is drawn.

   These rules were in app.css, which the home screen loads on first paint and which
   paints not one of them: the home screen has no article, no citation, no table of
   contents. They belong to the two surfaces that show statutory text — the
   server-rendered document and article pages, which load this file directly, and the
   reading pane, for which `panes()` in app.js now loads it beside panes.css.

   The note they used to carry said they had to stay in app.css because the reading pane
   renders the same markup as a server-rendered page. That is still true, and is now the
   reason this file is loaded in both places rather than the reason the rules sit on the
   first screen's byte budget.
   --------------------------------------------------------------------------- */
/* The h1 of a document or an article panel is the law's own title — "Điều 4. Điều kiện
   của cơ sở xét nghiệm" is the heading the gazette printed — so it is set in the face of
   the text it names. The static pages have no `article.panel`; their h1 stays sans. */
article.panel h1{font-family:var(--serif)}
/* Every family here was checked with infra/check-font-coverage.py. Iowan Old Style was
   first in this stack and lacks ư and ơ: macOS then substitutes per glyph and "tương
   đương" renders as "tuóng đuóng", which reads as corrupted law rather than a missing
   typeface. A serif for Vietnamese legal text is chosen by coverage, not by taste. */
.legal{font-family:var(--serif);
  font-size:17px;line-height:1.75}
.khoan{margin:12px 0}
/* A fifth of all articles have no khoản and render as bare paragraphs, which the browser
   spaces by 1em — 17px here, the one value on these pages that was off the grid and the
   only reason two articles of the same law could have two different rhythms. */
.legal p{margin:12px 0}
.khoan>.n{font-weight:600;font-family:inherit}
.diem{margin:4px 0 4px 24px}
.diem>.n{color:var(--muted);font-weight:600}
/* A khoản or điểm that carries its own citation. The number is the control — see
   page.js — so it gets the only affordance it can have without moving the law's own
   text: a hover underline, and a focus ring for the keyboard. Untouched when the script
   never loads, which is most crawlers and any reader on a failed asset. */
[data-cite]>.n{border-radius:4px}
[data-cite]>.n:hover{text-decoration:underline dotted;text-underline-offset:3px}
/* A hover affordance discovers nothing on a phone, which is where this page is mostly
   read. Touch gets the underline permanently: the number is already set apart from the
   law's own words, so making it look actionable costs no legibility. */
@media (hover:none){
  [data-cite]>.n{text-decoration:underline dotted;text-underline-offset:3px}
}
[data-cite]>.n:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* Confirmation cannot replace the label: "3." is part of the document. It is appended,
   in the UI font, so it reads as chrome rather than as text of the law. */
[data-cite][data-copied]>.n::after{margin-left:6px;font:11px/1 var(--sans);
  font-weight:500;color:var(--accent);vertical-align:middle}
[data-cite][data-copied="yes"]>.n::after{content:"đã chép"}
[data-cite][data-copied="no"]>.n::after{content:"không sao chép được";color:var(--muted)}
/* A citation the document itself printed, now openable: "khoản 2 Điều 7 Nghị định số
   138/2020/NĐ-CP". It is the law's own words, so it is not restyled into a link — no
   colour, no weight, nothing that would make a reader take it for our text. A dotted
   underline in the accent is the whole affordance, and it becomes solid on hover. Only
   references that resolve to a page here are marked, so an underline is a promise the
   site can keep. */
.legal a.xref{color:inherit;text-decoration:underline dotted var(--accent);
  text-underline-offset:3px;text-decoration-thickness:1px}
.legal a.xref:hover{text-decoration-style:solid;color:var(--accent)}
.legal a.xref:focus-visible{outline:2px solid var(--accent);outline-offset:2px;
  border-radius:3px}
/* The sticky header would otherwise cover the unit a citation's #fragment lands on —
   the same trap the document page's panes already pay for. */
.khoan[id],.diem[id]{scroll-margin-top:96px}
.khoan[id]:target,.diem[id]:target{background:var(--accent-soft);border-radius:8px;
  box-shadow:0 0 0 6px var(--accent-soft)}
.cite{margin-top:20px;border-top:1px solid var(--line);padding-top:16px;font-size:13px}
.cite code{background:var(--accent-soft);color:var(--accent);padding:2px 8px;border-radius:8px;
  font:13px/1.5 var(--mono);display:inline-block;margin:2px 4px 2px 0}
.cite a{color:var(--accent);word-break:break-all}
dl.props{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:12px 24px;margin:16px 0 0;padding-top:16px;border-top:1px solid var(--line)}
dl.props dt{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
dl.props dd{margin:2px 0 0;font-size:14px}
/* The source is a fact about the instrument, so it sits in the grid; but it is the one
   cell a reader can click, so it is marked as a link without being set louder than the
   dates beside it — underlined only on hover, and carrying the outbound arrow. */
/* Scoped to the class, not to `dl.props dd` where it was written. The source moved out of
   the properties grid into the provenance block at the foot of the page on 2026-09-12, and
   a rule anchored to its old parent stopped matching silently: the link fell back to the
   global anchor style and came out as a plain blue underline in the middle of a muted
   footnote. A rule that names where a thing lives breaks when the thing moves. */
a.source-link{color:inherit;text-decoration:none;border-bottom:1px solid var(--line)}
a.source-link:hover,a.source-link:focus-visible{color:var(--accent);
  border-bottom-color:currentColor}
a.source-link::after{content:" ↗";color:var(--muted);font-size:11px}
.cite-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
/* The article page's source line, set like the document page's provenance: a label and a
   host name, not a 44-character URL of which 21 are an opaque id. The link keeps
   `a.source-link` — no `.cite-source a` override, because an equal-specificity rule
   written later silently won and painted it accent-red inside a muted footnote. */
.cite-source{margin:8px 0 0;font-size:13px;color:var(--muted);word-break:break-word}
/* A division title can run to a 90-word paragraph; it is context, not a heading. */
h3.division{font-size:13px;font-weight:600;color:var(--muted);margin:24px 0 8px;line-height:1.5}
p.division{font-size:13px;margin:0 0 12px}
/* "9 điều" counts what follows; it is not a third heading level above headings that are
   now set in the law's own face. Given the label styling the page already uses for
   `dl.props dt` and the pane heads, so a reader meets one kind of label, not three. */
.panel:has(>ol.toc)>h2,.panel:has(>h3.division)>h2{font-size:12px;font-weight:600;
  color:var(--muted);letter-spacing:.05em;text-transform:uppercase;margin:0 0 16px}

/* An annex heading is the law talking, not the site. The label styling above is for
   "9 điều", which is this page describing the document; a Phụ lục title is printed in
   the instrument and is set in the instrument's face. Written after that rule and with
   the same specificity so it wins on the annex sections only. */
section.annex>h2.annex-title{font-family:var(--serif);font-size:19px;font-weight:600;
  line-height:1.35;color:var(--ink);text-transform:none;letter-spacing:0;margin:0 0 6px}
p.annex-note{font-size:13px;margin:0 0 16px}
/* `<details>` opens only past eight annexes; the heaviest document carries 122. */
.railmore{margin-top:8px}
.railmore>summary{cursor:pointer;font-size:13px;color:var(--muted);padding:4px 0}
.railmore>summary:hover{color:var(--accent)}
@media print{section.annex{page-break-before:always}}
ol.toc{list-style:none;margin:0;padding:0}
ol.toc>li{border-top:1px solid var(--line);padding:12px 0}
ol.toc>li:first-child{border-top:0}
/* `anywhere` rather than `break-word`, because the run that overflows here has no break
   opportunity at all: an annex holds form templates, and their headings carry the dotted
   leader a person writes on — "Giao cho ông (bà) …………………". The browser treats that as one
   word, the list is `overflow-x:visible`, and the width propagates all the way to
   `documentElement`: 31/2010/NĐ-CP scrolled the whole page to 628px at a 390px viewport.
   Measured 2026-09-13: 106 of 133,709 documents carry a leader of six or more in a unit
   title. Scoped to the link, not the list, so a real long word in body text is untouched. */
ol.toc>li>a{display:block;color:var(--ink);text-decoration:none;font-size:15px;
  line-height:1.5;overflow-wrap:anywhere}
ol.toc>li>a:hover{color:var(--accent)}
/* An article heading printed above the article's own text belongs to that text. Where the
   two alternate — a document page is 65 blocks of serif interleaved with 63 of sans — the
   page reads as two documents shuffled together, and the heading was also a step *smaller*
   than the paragraphs it introduced. Same face, same size, bold. The Mục lục column is
   navigation, not law, and keeps the sans list (panes.css). */
ol.toc>li:has(>.legal:not([hidden]))>a{font-family:var(--serif);font-size:17px;
  font-weight:600;line-height:1.45}
ol.toc .n{font-weight:600;margin-right:8px}
ol.toc .legal{margin-top:8px}
/* A heading that opens its own text says so, and only once a script is on the page to
   open it: `aria-expanded` is set by page.js, so the caret cannot appear on a heading
   whose click still navigates. The unit is a real link either way — the caret says "this
   opens here", not "this is a button". */
ol.toc>li>a[aria-expanded]{padding-right:22px;position:relative}
ol.toc>li>a[aria-expanded]::after{content:"";position:absolute;right:4px;top:.55em;
  width:6px;height:6px;border-right:1.5px solid currentColor;
  border-bottom:1.5px solid currentColor;transform:rotate(45deg);
  transform-origin:center;transition:transform .15s ease;opacity:.55}
ol.toc>li>a[aria-expanded="true"]::after{transform:rotate(-135deg);opacity:.9}
ol.toc>li>a[aria-busy]::after{opacity:.3}
.unitwait{margin-left:8px;font-size:13px}
/* The way to the unit's own page. The heading expands instead of navigating, so the
   number keeps the permalink (page.js lets a click on `.n` through): a reader who wants to
   share, print or cite one Điều needs its own address. Only the number reacts to hover,
   so it reads as the link and the rest as the toggle. */
ol.toc>li>a[aria-expanded]:hover{color:var(--ink)}
ol.toc>li>a[aria-expanded] .n{color:var(--accent)}
ol.toc>li>a[aria-expanded] .n:hover{text-decoration:underline;text-underline-offset:3px}
@media print{ol.toc>li>a[aria-expanded]::after{display:none}}
.pager{display:grid;grid-template-columns:1fr auto 1fr;gap:12px;align-items:center;
  margin:24px 0 40px;font-size:14px}
.pager a{color:var(--accent);text-decoration:none}
.pager a:hover{text-decoration:underline}
.pager .next{text-align:right}
.pager .up{text-align:center;color:var(--muted)}
@media (max-width:640px){
  .pager{gap:8px;font-size:13px}
}

/* Printing is how legal work leaves a screen. Neither incumbent handles it: one ships
   a 1.09 MB page, the other nineteen ad slots. Chrome and navigation go; the citation
   and the source URL stay, because a printed article without them is unciteable. */
@media print{
  header,footer,.pager,.crumbs,form,button{display:none!important}
  /* The rail is navigation and the action row is controls; neither survives leaving the
     screen. The hero does survive, because the title of the instrument is on it — but as
     type on paper, with the photograph and the card dropped. A 193 KB background is not
     something to hand a printer, and the status badge under it is a fact worth keeping. */
  .docactions,.rail{display:none!important}
  .dochero{background-image:none!important;background-color:#fff;border:0;box-shadow:none;
    padding:0;min-height:0;margin:0 0 12pt}
  .doc-page .dochero h1{max-width:none;font-size:18pt}
  .effect{border:1px solid #999;background:none;color:#000}
  .doc-notes{border:0;border-top:1px solid #999;border-radius:0;padding:8pt 0 0;
    background:none}
  .doc-notes p,.doc-notes .quiet{color:#000}
  /* On paper the source is the one line that lets a reader go back to the original, so it
     keeps its rule and its place — and `a.source-link::after` below prints the whole URL. */
  .provenance{color:#000}
  body{background:#fff;color:#000;font-size:11pt}
  .panel{border:0;padding:0;background:#fff}
  .legal{font-size:11pt;line-height:1.55}
  .cite{border-top:1px solid #999;page-break-inside:avoid}
  .cite code{background:none;color:#000;border:1px solid #999}
  /* On paper the host is not enough to go back to the original, so the property cell
     prints the whole URL the screen was spared. */
  .cite-source a::after,a.source-link::after{
    content:" (" attr(href) ")";font-size:9pt;word-break:break-all;color:#000}
  ol.toc>li{page-break-inside:avoid}
}

/* ---------------------------------------------------------------------------
   Schedules
   ---------------------------------------------------------------------------
   Cells wrap and rows grow tall rather than the table scrolling sideways — the same
   layout the print stylesheet already used. `.tbl` keeps `overflow-x:auto` as a
   fallback only: a table whose columns cannot shrink any further (e.g. a long
   unbroken so_hieu or URL in a cell) still scrolls instead of blowing out the grid
   column, which stays `minmax(0,1fr)` rather than `1fr` for that reason.

   Sans rather than the serif the law is set in, because a rate schedule is data: at
   14px it fits two more columns on a 360px screen, and a column a reader cannot see is
   a figure they cannot check. */
.tbl{margin:16px 0;max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;
  border:1px solid var(--line);border-radius:8px}
.tbl:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.tbl>table{border-collapse:collapse;width:100%;min-width:0;table-layout:auto;
  font-family:var(--sans);font-size:14px;line-height:1.45}
.tbl th,.tbl td{border:1px solid var(--line);padding:6px 10px;text-align:left;
  vertical-align:top;overflow-wrap:break-word}
.tbl th{background:var(--paper-2,#f6f7f9);font-weight:600}
/* A row the pipeline found a known mistake in (db/migrations/0043) — same vocabulary
   as .e-held/.suspect above, since this is the same kind of flag: a reader should see
   it without hovering, and the sentence beside it already says it is the catalogue's
   own mistake, not this site's. */
.row-flag td,.row-flag th{background:var(--warn-soft)}
.row-flag-note td{background:var(--warn-soft);border-top:0;padding-top:0}
.row-flag-note .quiet{color:var(--warn)}
@media print{
  .tbl{overflow:visible;border:0}
  .tbl>table{font-size:9pt}
  .tbl tr{page-break-inside:avoid}
}

/* ---------------------------------------------------------------------------
   "Thấy chỗ nào sai trên trang này?" — the defect report at the foot of every
   document and every Điều.

   A closed <details>, and the closed state is the design. This block sits under
   1,152,715 articles; open by default it would be a form on every page of the corpus for
   the fraction of readers who found a mistake, and the thing they came for is the law.
   Closed it is one line, and it costs no JavaScript to open — which is also why the form
   inside it is a real POST rather than a fetch.

   Nothing in it varies by reader. That is what keeps these pages cacheable at the edge,
   and the edge cache is what lets two OCPU serve the corpus.
   --------------------------------------------------------------------------- */
.report{margin:24px 0 8px;border:1px solid var(--line);border-radius:12px;
  background:var(--panel)}
.report>summary{cursor:pointer;padding:14px 18px;font-size:14px;color:var(--muted);
  list-style:none;display:flex;align-items:center;gap:8px;border-radius:12px}
.report>summary::-webkit-details-marker{display:none}
/* The disclosure triangle is drawn rather than inherited, so it can rotate and so it
   reads at the same weight as the label beside it. */
.report>summary::before{content:"›";font-size:17px;line-height:1;color:var(--accent);
  transition:transform .15s ease;display:inline-block}
.report[open]>summary::before{transform:rotate(90deg)}
.report>summary:hover{color:var(--ink)}
.report-body{padding:0 18px 18px;border-top:1px solid var(--line);margin-top:-1px}
.report-body>.quiet{margin:14px 0 16px;max-width:70ch}
/* `app.css` lays every form out as a flex row; this one is a stack of fields. Same
   override, same reason, as the review form on /gop-y. */
.report-form{display:block;padding-bottom:0;gap:0}
.report-field{display:block;margin:0 0 14px}
.report-field>span{display:block;font-size:13px;margin:0 0 6px;color:var(--ink)}
.report-field em{font-style:normal;color:var(--muted)}
.report-field select,.report-field input,.report-field textarea{width:100%;
  box-sizing:border-box;font:inherit;font-size:16px;padding:9px 11px;
  border:1px solid var(--line);border-radius:8px;background:var(--bg);color:var(--ink)}
.report-field textarea{resize:vertical;line-height:1.6}
.report-field select:focus,.report-field input:focus,.report-field textarea:focus{
  outline:2px solid var(--accent);outline-offset:-1px;border-color:transparent}
.report-actions{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.report-actions button{padding:10px 16px;font-size:14px}
@media print{ .report{display:none} }

/* ---------------------------------------------------------------------------
   The masthead and the signature block — db/migrations/0030.

   The page opened on "Điều 1." and closed on the last article, because until 0030
   neither end of the document was in the database. Now that both are, they are set the
   way the paper sets them: the issuing body and the số hiệu in the left cell, the
   national heading and the dateline in the right, the name of the instrument centred
   under both, the recitals in the document's own words, and the signature at the foot
   against the right margin.

   Two columns, not a table. The source text arrives as labelled lines rather than as a
   grid — Công báo's two-column read interleaves the cells and tvpl joins them with a
   pipe — so the layout is rebuilt here from the labels. Below 640px the two cells stack:
   a letterhead squeezed into two 150px columns on a phone wraps every cell to three
   lines and reads worse than one column of four.
   --------------------------------------------------------------------------- */
.masthead{margin:0 0 28px;padding:0 0 20px;border-bottom:1px solid var(--line)}
.masthead-cells{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);
  gap:8px 24px;align-items:start}
.masthead p{margin:0;line-height:1.5}
.masthead-left{text-align:center}
.masthead-right{text-align:center}
.masthead-issuer{font-weight:600;font-size:14px;letter-spacing:.01em}
.masthead-motto:first-child{font-weight:600;font-size:14px}
/* The motto sits under the national heading with a rule between them on paper. The rule
   is drawn rather than transcribed: the underscore run the extractors carry is print
   furniture, and `parser/masthead.py` splits cells on it. */
.masthead-motto+.masthead-motto{display:inline-block;font-weight:600;font-size:14px;
  border-bottom:1px solid currentColor;padding-bottom:2px;margin-bottom:4px}
.masthead-number,.masthead-date{font-size:14px;color:var(--ink)}
.masthead-date{font-style:italic}
.masthead-title{text-align:center;margin:26px 0 0}
/* Never `text-transform:uppercase`. The instrument decides its own case and the two
   halves of the corpus differ: the gazette prints "LUẬT / CẢNH SÁT CƠ ĐỘNG" in capitals
   and "Ban hành Quy chế xử lý sạt lở bờ sông, bờ biển" in sentence case, and vbpl's
   provincial Quyết định name themselves "Quy định về cải tạo, chỉnh trang…". Forcing
   the case rewrote the title of every document that had been read correctly. */
.masthead-title p{margin:0;font-weight:700;font-size:17px;line-height:1.4}
.masthead-kind{font-size:20px;letter-spacing:.02em}
/* The recitals are the document speaking, so they are set as prose and not as a note:
   same measure and colour as an article, italic because the paper italicises them, and
   indented on the first line the way the instrument prints them. */
.masthead-recitals{margin:22px 0 0}
.masthead-recitals p{margin:0 0 8px;font-style:italic;line-height:1.75;text-align:left}
/* A preface under the name ("Lời nói đầu"): plain prose, left-aligned, as vbpl sets it. */
.masthead-preface{margin:18px 0 0}
.masthead-preface p{margin:0 0 8px;font-style:italic;font-weight:400;line-height:1.75;
  text-align:left}

/* The foot of the signed page: "Nơi nhận:" at the left margin, the signature against
   the right, on one row. That is how the office types it and how vbpl.vn and the
   gazette both print it; stacking them would put the distribution list where a reader
   is still expecting law. Below 640px they stack, list first, because two columns of
   twelve recipients each on a phone is neither. */
.docfoot{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,auto);gap:16px 40px;
  align-items:start;margin:32px 0 0;padding:20px 0 0;border-top:1px solid var(--line)}
/* Quiet, and smaller than the law: this is the office saying who got a copy. It is
   never searched and never quoted — `parser/furniture.py` cuts it out of the text
   before a single unit is built, which is why it can be printed here without any of it
   reaching the FTS index, the coverage gate or an answer's evidence. */
.recipients{font-size:12.5px;color:var(--muted);line-height:1.55}
.recipients-block p{margin:0}
.recipients-block p:first-child{font-style:italic;font-weight:600;color:var(--ink);
  margin-bottom:4px}
.recipients-block+.recipients-block{margin-top:12px}
.attest{margin:28px 0 0;padding-top:14px;border-top:1px solid var(--ink)}
.attest p{margin:0;font-style:italic;line-height:1.6}
.signatures{display:flex;flex-wrap:wrap;gap:24px 40px;justify-content:flex-end}
/* Each signature is its own column and is centred inside it, which is how a joint
   circular prints two ministries side by side. `min-width` keeps a two-word office from
   collapsing to a column narrower than the name under it. */
.signature{text-align:center;min-width:180px}
.signature p{margin:0;line-height:1.6}
.signature-office{font-weight:700;font-size:14px}
/* The gazette's note that the paper copy carries a signature. Quiet: it is the
   publisher speaking, not the signatory. */
.signature-mark{color:var(--muted);font-size:13px;font-style:italic;margin:6px 0}
.signature-name{font-weight:700;font-size:15px;margin-top:22px}
.signature-mark+.signature-name{margin-top:6px}

@media (max-width:640px){
  .docfoot{grid-template-columns:1fr}
  .masthead-cells{grid-template-columns:1fr;gap:14px}
  .masthead-title p{font-size:15px}
  .masthead-kind{font-size:18px}
  .masthead-recitals p{text-align:left}
  .signatures{justify-content:flex-start}
}

/* The authority naming itself above the recitals ("THỦ TƯỚNG CHÍNH PHỦ"), and the word
   that answers them ("QUYẾT ĐỊNH:"). Both are printed centred and in capitals on the
   paper, and both were missing from this page until the reader compared it with the
   gazette's own PDF: the first was deduplicated away as a repeat of the letterhead, the
   second was read as the first line of the body and dropped. */
.masthead-authority{text-align:center;margin:22px 0 0}
.masthead-authority p{margin:0;font-weight:700;font-size:15px}
.masthead-enact{text-align:center;margin:18px 0 0}
.masthead-enact p{margin:0;font-weight:700;font-size:16px;letter-spacing:.02em}
/* The preview over a citation (xref-card.js). The text inside is the law's own, set in the
   same face as the page it hangs over; the card itself is ours, so it gets a border and a
   shadow rather than the page's reading column. */
.xcard{position:absolute;z-index:60;width:min(680px,calc(100vw - 16px));max-height:min(75vh,640px);
  overflow:auto;padding:12px 14px;background:var(--panel,#fff);color:var(--ink,inherit);
  border:1px solid var(--line,#ddd);border-radius:10px;box-shadow:0 8px 28px rgba(0,0,0,.16);
  font-size:.92rem;line-height:1.55}
.xcard[hidden]{display:none}
.xcard .xp-head{display:flex;flex-direction:column;gap:2px;margin-bottom:6px}
.xcard .xp-title{margin:0 0 4px}
.xcard .xp-title::first-letter{text-transform:uppercase}
.xcard .quiet{color:var(--muted)}
.xcard p{margin:0 0 6px}
