
/* ═══════════════════════════════════════════════════════════════════════════════════════
 * GIAO DIỆN NỔI kiểu Google — Google-inspired Minimalist Floating UI
 *
 * Đo trên 137 tool trước khi sửa (`do_giao_dien.py`):
 *     viền 32,0 phần tử/trang   vs   bóng 3,8/trang      (chuẩn: ngược lại)
 *     nút có viền 2.120/2.125 · nút viên thuốc 97/2.125 = 5%   (chuẩn: 0 và 100%)
 *     bo góc trung bình ~10px                             (chuẩn: 16–28px)
 *
 * Nguyên tắc: nền phẳng, khối NỔI bằng bóng mềm thay cho viền, bo góc lớn, nút viên thuốc,
 * MỘT màu nhấn. Màu nhấn `#0b57d0` lấy đúng mã khung chung của site đang dùng.
 * ═══════════════════════════════════════════════════════════════════════════════════════ */
#tool-root {
  --nhan:        #0b57d0;
  --nhan-nhat:   #e8f0fe;
  --nhan-nhat-2: #d3e3fd;
  --nhan-dam:    #0842a0;
  --nhan-chu:    #ffffff;

  --r-the:       16px;   /* khối */
  --r-o:         12px;   /* ô nhập, ảnh */
  --r-tron:      999px;  /* nút, tab, chip */

  --noi-0: 0 1px 2px rgba(13,17,23,.06);
  --noi-1: 0 1px 2px rgba(13,17,23,.08), 0 2px 6px rgba(13,17,23,.05);
  --noi-2: 0 2px 4px rgba(13,17,23,.08), 0 6px 16px rgba(13,17,23,.08);
}
:root[data-theme="dark"] #tool-root {
  /* #a8c7fa trên nền tối đạt ~9:1 — thừa ngưỡng WCAG cho chữ nhỏ.
   * Dùng thẳng #0b57d0 ở chế độ tối chỉ được 2,4:1, tức chữ gần như đọc không ra. */
  --nhan:        #a8c7fa;
  --nhan-nhat:   #0b2a56;
  --nhan-nhat-2: #13386e;
  --nhan-dam:    #d3e3fd;
  --nhan-chu:    #06203f;
  --noi-0: 0 1px 2px rgba(0,0,0,.40);
  --noi-1: 0 1px 2px rgba(0,0,0,.50), 0 2px 6px rgba(0,0,0,.35);
  --noi-2: 0 2px 4px rgba(0,0,0,.50), 0 6px 16px rgba(0,0,0,.45);
}



/* ---------- surfaces ---------- */
#tool-root, #tool-root * { border-color: var(--line); }

#tool-root :is(section, fieldset, .panel, .card, .box, [class*="-section"], [class*="-panel"], [class*="-card"], [class*="-box"]) {
  background: var(--surface);
  /* nổi bằng bóng, KHÔNG viền — đây là điểm khác cốt lõi so với bản cũ */
  border: 0;
  border-radius: var(--r-the);
  box-shadow: var(--noi-1);
  color: var(--fg);
}
/* Thẻ lồng trong thẻ thì KHÔNG chồng bóng lên nhau — một khối nổi chứa các ngăn chìm.
 * Thiếu luật này thì mỗi lớp lồng lại thêm một quầng tối, nhìn như vết bẩn. */
#tool-root :is(.panel, .card, [class*="-panel"], [class*="-card"])
          :is(.panel, .card, .box, [class*="-panel"], [class*="-card"], [class*="-box"]) {
  box-shadow: none;
  background: var(--surface-2);
}

#tool-root :is(h1, h2, h3, h4, legend, [class*="-h"], [class*="-title"]) { color: var(--fg); }
#tool-root :is(p, li, span, dd, dt, label, small) { color: inherit; }
/* …trừ ba chip do widget tự tô nền đậm. Nêu rõ `span.lớp` để đạt (1,1,1), hơn (1,0,1) của
 * luật ngay trên. Số đo trước/sau kèm từng dòng. */
#tool-root span.isf-tag { color: #fff; }                      /* 5,15–10,38:1 trên 7 nền */
#tool-root span.isf-tag-loot,
#tool-root span.isf-tag-bartering { color: #1a1a1a; }         /* nền vàng: 5,39 và 5,01:1 */
#tool-root span.bpl-crumb-current { color: #fff; }            /* 1,33 → 7,10:1 */
#tool-root span.cctc-node-badge-craft { color: #fff; }        /* 2,66 → 7,10:1 */
#tool-root :is(.hint, .note, .desc, [class*="-hint"], [class*="-note"], [class*="-desc"], small) { color: var(--fg-muted); }
#tool-root a { color: var(--nhan); }

/* ---------- form controls: the loudest offenders ---------- */
/* background-COLOR, not the `background` shorthand. The shorthand resets background-image to
 * none, and this rule outranks the `#tool-root select` one below it — `:is()` takes the
 * specificity of its most specific argument, so the attribute selectors in the list make this
 * (1,1,1) against that rule's (1,0,1). The arrow drawn there never painted, on any select, in
 * any ported tool, in either theme, while `appearance: none` had already removed the native
 * one. A dropdown that looks exactly like a text input reads as a styling choice, which is
 * why it survived: nothing about it looks broken until you try to find the control. */
#tool-root :is(input[type="text"], input[type="number"], input[type="search"], input[type="url"],
               input[type="email"], input[type="password"], select, textarea) {
  background-color: var(--surface);
  color: var(--fg);
  /* ô nhập vẫn giữ một đường rất nhạt: không có nó thì người dùng không biết bấm vào đâu —
   * đây đúng là kiểu "outlined text field" của Material, không trái chuẩn thẻ-nổi. */
  border: 1px solid var(--line);
  border-radius: var(--r-o);
  padding: 10px 13px;
  font: inherit;
  font-size: 14px;
  outline: none;
  box-shadow: none;
  -webkit-appearance: none;
  appearance: none;
}
#tool-root select {
  /* the native arrow disappears once appearance is stripped */
  background-image: linear-gradient(45deg, transparent 50%, var(--fg-muted) 50%),
                    linear-gradient(135deg, var(--fg-muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) 52%, calc(100% - 10px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 28px;
}
#tool-root :is(input, select, textarea):focus {
  border-color: var(--nhan);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--nhan) 20%, transparent);
}
#tool-root ::placeholder { color: var(--fg-dim); opacity: 1; }
#tool-root :is(input[type="checkbox"], input[type="radio"], input[type="range"], input[type="color"]) {
  accent-color: var(--grass);
  -webkit-appearance: auto;
  appearance: auto;
}
#tool-root input[type="color"] { background: var(--surface-2); border: 1px solid var(--line); padding: 2px; }

/* File inputs keep the browser's grey "Choose file / No file chosen" chrome unless the
 * button pseudo-element is styled too, which reads as a light-theme leftover on this
 * page. The field itself is styled by the rule above; this is the button inside it. */
#tool-root input[type="file"] {
  padding: 6px 8px;
  font-size: 13px;
  color: var(--fg-muted);
  cursor: pointer;
}
#tool-root input[type="file"]::file-selector-button {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  margin-right: 10px;
  padding: 6px 11px;
  color: var(--fg);
  background: var(--nhan-nhat);
  border: 0;
  border-radius: var(--r-tron);
  cursor: pointer;
  transition: background 140ms, color 140ms;
}
#tool-root input[type="file"]::file-selector-button:hover {
  background: var(--nhan);
  color: var(--nhan-chu);
}

/* ---------- buttons ---------- */
/* ⛔ WIDGET TỰ SỞ HỮU BỀ MẶT thì KHÔNG áp lớp nút của site.
 *    `seed-map-3d` định nghĩa lại chính `#tool-root` (`--bg:#121286`, `--panel`, `--fg`),
 *    canvas phủ hết khung nhìn, và ĐÃ CÓ SẴN thanh công cụ nổi riêng. Ép vào thì nút nền
 *    trong suốt trên nền tối nhận chữ xanh của site → 2,63:1.
 *
 *    Dò bằng trình duyệt (`soi_widget_toan_man.py`), không đoán theo tên: trong 10 tool
 *    3D/canvas chỉ 2 cái tự sở hữu bề mặt, cả hai đều là app seedmap.
 *
 *    ⛔ Loại trừ theo lớp của NÚT là không đủ: nút `⧉` trong `.sm-seedcard-row` KHÔNG CÓ
 *       lớp nào — widget tạo kiểu cho nó qua tổ tiên. Phải loại theo VÙNG CHỨA.
 *       Dùng `data-tool` có sẵn trên cả 2.137 trang widget — không phải sửa HTML, và thêm
 *       widget mới vào danh sách chỉ là thêm một tên.
 *
 *    ⛔ Khớp TIỀN TỐ `^="seed-map"` là quá rộng: nó bắt cả `seed-map` bản 2D, vốn KHÁC bản
 *       chất — khung sáng (`#f6f7fa`) với màu chữ ghim cứng kiểu chế độ sáng, tức là nó CẦN
 *       lớp theme ép vào. Loại trừ nó thì chế độ tối tụt 11 → 15 chỗ kém. Khớp CHÍNH XÁC.
 *
 * HÌNH DÁNG giữ ưu tiên cao — đó là thứ phải đồng bộ trên cả 137 tool. */
#tool-root:not([data-tool="seed-map-3d"]) button:not(.btn):not([class*="tab"]) {
  border: 0;
  border-radius: var(--r-tron);
  box-shadow: var(--noi-1);
  padding: 9px 18px;
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 140ms, box-shadow 140ms, color 140ms;
}
/* MÀU ép cùng mức ưu tiên với hình dáng. Nền và chữ là MỘT CẶP — tách ra hai mức thì nút
 * lĩnh nền của widget mà lại ăn chữ của tôi, đúng kiểu đẻ ra tương phản kém.
 *
 * ⛔ Trừ nút tự vẽ nền NỘI TUYẾN (`style="background:#AA0000"` — ô màu MiniMessage): kiểu
 *    nội tuyến thắng mọi bộ chọn, nên nền đỏ ở lại mà chữ thì nghe lời tôi → 1,21:1.
 *    Nút nào tự vẽ nền bằng thuộc tính style thì để nguyên cả cặp cho nó. */
#tool-root:not([data-tool="seed-map-3d"]) button:not(.btn):not([class*="tab"]):not([style*="background"]) {
  background: var(--surface);
  color: var(--nhan);
}
#tool-root:not([data-tool="seed-map-3d"]) button:not(.btn):not([class*="tab"]):not([style*="background"]):hover {
  background: var(--nhan-nhat);
}
#tool-root:not([data-tool="seed-map-3d"]) button:not(.btn):not([class*="tab"]):hover { box-shadow: var(--noi-2); }
#tool-root:not([data-tool="seed-map-3d"]) button:not(.btn):not([class*="tab"]):active { box-shadow: var(--noi-0); }
#tool-root:not([data-tool="seed-map-3d"]) button:not(.btn):not([class*="tab"]):disabled {
  box-shadow: none; cursor: not-allowed; opacity: .55;
}
/* ⛔ Nút KHÔNG CÓ CHỮ (ô màu, ô vật phẩm, ô ảnh) phải giữ hình vuông: bo tròn 999px biến
 *    ô 26px thành hình tròn, mất hẳn lưới. `tool-theme.css` đã ghi ba lần rằng luật nút
 *    chung này từng bóp méo chip 3d-skin-editor, tab schematic và bảng màu texture-maker —
 *    cùng một luật, ba nạn nhân. Nên khoanh vùng ngay tại đây thay vì vá lẻ về sau. */
#tool-root:not([data-tool="seed-map-3d"]) button:is([class*="swatch"], [class*="-item"],
    [class*="-cell"], [class*="-tile"], [class*="color"], [class*="-sq"], [aria-label]:empty) {
  border-radius: var(--r-o);
  padding: 0;
  box-shadow: none;
}
/* whatever a widget calls its primary action */
#tool-root :is(button[class*="primary"], button[class*="copy"], button[class*="generate"], button[type="submit"]) {
  background: var(--nhan);
  border: 0;
  color: var(--nhan-chu);
  box-shadow: var(--noi-1);
}
#tool-root :is(button[class*="primary"], button[class*="copy"], button[class*="generate"], button[type="submit"]):hover {
  background: var(--nhan-dam);
  color: var(--nhan-chu);
}

/* ---------- tabs, chips, pills ---------- */
#tool-root :is([class*="tab"]:not([class*="table"]), [class*="chip"], [class*="pill"]) {
  background: transparent;
  color: var(--fg-muted);
  border: 0;
  border-radius: var(--r-tron);
  font-weight: 500;
  transition: background 140ms, color 140ms;
}
/* Hover CHI ap cho the CHUA duoc chon. Khong chan o day thi luat hover (1,3,0) de len
 * luat "dang chon" (1,2,0) va xoa mat vien thuoc mau nhan khi re chuot qua. */
#tool-root :is([class*="tab"]:not([class*="table"]), [class*="chip"], [class*="pill"]):not([class*="active"]):not([aria-selected="true"]):hover {
  background: var(--surface-2);
  color: var(--fg);
}
#tool-root :is([class*="tab"][class*="active"], [class*="chip"][class*="active"],
               [class*="tab"][aria-selected="true"], [class*="pill"][class*="active"]) {
  background: var(--nhan-nhat);
  border: 0;
  color: var(--nhan);
  font-weight: 700;
}
/* The dang chon van co phan hoi khi re chuot, nhung dam HON mot bac chu khong doi sang xam */
#tool-root :is([class*="tab"][class*="active"], [class*="chip"][class*="active"],
               [class*="tab"][aria-selected="true"], [class*="pill"][class*="active"]):hover {
  background: var(--nhan-nhat-2);
  color: var(--nhan);
}

/* ---------- tables ---------- */
#tool-root table { border-collapse: collapse; width: 100%; font-size: 14px; color: var(--fg); }
#tool-root :is(th, td) {
  border: 0;
  border-bottom: 1px solid var(--line);
  padding: 9px 12px;
  text-align: left;
  background: transparent;
}
#tool-root th {
  background: var(--surface-2);
  color: var(--fg-dim);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
}
#tool-root tbody tr:hover td { background: var(--surface-2); }
/* zebra stripes from the light theme read as glare here */
#tool-root tbody tr:nth-child(even) td { background: transparent; }

/* ---------- code, output, pre ---------- */
#tool-root :is(pre, code, kbd, samp, [class*="-out"], [class*="output"], [class*="result"]) {
  font-family: var(--font-mono);
  background: var(--surface-2);
  color: var(--fg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
#tool-root :is(pre, [class*="-out"], [class*="output"]) { padding: 12px 14px; overflow-x: auto; }
#tool-root code { padding: 1px 5px; font-size: 0.92em; }
#tool-root pre code { border: 0; padding: 0; background: none; }

/* ---------- imagery ---------- */
/* Minecraft sprites are 16px art; any widget scaling one must not smooth it. */
#tool-root img[src*="/textures/"], #tool-root img[src*="/_a/icons/"],
#tool-root img[width="16"], #tool-root canvas { image-rendering: pixelated; }

/* ---------- hairline dividers ---------- */
#tool-root hr { border: 0; border-top: 1px solid var(--line); margin: 16px 0; }

/* Light theme: undo the assumptions above rather than fighting them twice. */
/* background-color for the same reason as above — this one outranks it again, so using the
 * shorthand here would put the arrow back to none on the light theme only. */
:root[data-theme="light"] #tool-root :is(input, select, textarea) { background-color: #fff; }
:root[data-theme="light"] #tool-root th { background: var(--surface-2); }

/* ---------- light theme: widgets that carry a dark palette of their own ---------- */
/*
 * Two ways a ported widget breaks on the light theme, both measured rather than eyeballed
 * — at 1.12:1 the text is still *there*, it is just the same colour as the button.
 *
 * 1. seed-map-3d redefines the SITE's token names on #tool-root itself:
 *      #tool-root{--bg:#121286;--fg:#e6e6ec;--muted:#8c8c98;--panel:rgba(28,28,38,.92);…}
 *    So inside that widget --fg is always its dark-theme near-white, whatever the page
 *    theme is. The rules above then paint the button with --surface-2, which the widget
 *    does NOT redefine, so it resolves to the site's LIGHT value: near-white text on a
 *    near-white button, 1.12:1 against a required 4.5:1, on every control it owns.
 *
 *    Remapping the site's surface tokens onto the widget's own palette fixes all of them
 *    at once and keeps the app looking the way upstream drew it — which is right, because
 *    it is a full-viewport 3D world viewer with floating panels and is dark by design.
 *    Restating its individual rules here instead would be dead CSS the day it re-ports.
 *
 *    Only seed-map-3d does this. The 2D seed map ships a fully namespaced palette
 *    (--text-primary, --bg-surface, --accent) that collides with nothing, and it is a
 *    light-themed app already. Checked across the whole tools/ tree, not assumed.
 */
:root[data-theme="light"] #tool-root[data-tool="seed-map-3d"] {
  --surface:     var(--panel);
  --surface-2:   var(--bg-2);
  --surface-3:   var(--bg-2);
  --fg-muted:    var(--muted);
  --fg-dim:      var(--muted);
  --line:        var(--border);
  --line-strong: var(--accent);
}

/*
 *    Its form controls need saying twice, because the remap above cannot reach them: the
 *    light-theme rule further up hardcodes `background-color: #fff` on input/select/textarea
 *    rather than going through --surface-2, and it outranks the widget's own rule. So the
 *    field went white while `color: var(--fg)` stayed the widget's near-white — the seed, the
 *    edition and the dimension all rendered at 1.24:1, measured. The value was still painted,
 *    in the same colour as the box behind it.
 *
 *    Fixed by naming the colour rather than the background. --site-fg is --fg under a name no
 *    ported widget has redefined (see tokens.css); asking for --fg here is exactly what
 *    failed. That leaves the field the site's white with the site's ink on it, which is right
 *    now that seed-map-3d.js lifts this card out of the stage and into the toolbar under the
 *    map — it is site chrome down there, not a dark panel floating on the world.
 *
 *    Nothing rescued it at runtime either. theme-normalize.js skipped form controls outright,
 *    and even unskipped it could not see their text: it reads child TEXT NODES, and an
 *    <input> keeps its value in a property. Fixed there too, so the next one is caught.
 */
:root[data-theme="light"] #tool-root[data-tool="seed-map-3d"] :is(input, select, textarea) {
  color: var(--site-fg);
}

/*
 * 2. 3d-skin-editor paints its toolbar icons with `filter: brightness(0) invert(1)`
 *    (vendor/widget-full/widget-full.css) — a dark-theme trick that forces any artwork to
 *    pure white regardless of its own fill. On a light button the icon simply disappears.
 *    Dropping the invert leaves brightness(0), which forces the same artwork to pure black.
 *
 *    Worth remembering how this one hid: a contrast scan that reads `fill` and `stroke`
 *    reports these icons as fine, because the filter is what decides the painted colour and
 *    neither property changes. It was found by dumping computed styles, not by scanning.
 */
:root[data-theme="light"] #tool-root :is(.tool-icon, .action-icon-img) {
  filter: brightness(0);
}

/* ---------- right-to-left pages ---------- */
/* Widget interiors are English technical UIs: file extensions, coordinates, seeds, block
 * counts, command names. Mirrored into an RTL page, the neutral characters in those runs
 * take the paragraph direction and land on the wrong side — the seed map printed -2,048 as
 * "2,048-" and the schematic viewer printed .schem as "schem.". It is the same failure as the
 * bidi mark on /give, one level up: there the fix was per-string, here it is per-widget.
 *
 * An LTR technical panel inside an RTL page is the normal arrangement — the same as a code
 * block or a terminal transcript. The page chrome around the widget (h1, description, nav,
 * footer, the cross-promo block) sits outside #tool-root and stays right-to-left. */
[dir="rtl"] #tool-root { direction: ltr; }

/* ---------- inline sprites beside printed ids ---------- */
/*
 * js/id-sprites.js prepends one of these wherever a tool prints a bare Minecraft id. The
 * reference browsers listed 95 ids and shipped no images at all; the atlas built for the
 * /give picker already had every one of them.
 *
 * Same two rules the picker follows: 16px art must never be smoothed, and it is scaled with
 * a transform rather than background-size, because scaling the background scales the
 * POSITION too and every sprite would point at its neighbour. The negative margins claw
 * back the space the 2x transform paints outside the 16px box, so a decorated row is the
 * same height as an undecorated one.
 */
#tool-root .mc-sprite {
  display: inline-block;
  width: 16px; height: 16px;
  margin: -4px 10px -4px 4px;
  vertical-align: middle;
  background-image: var(--mc-atlas);
  background-repeat: no-repeat;
  image-rendering: pixelated;
  transform: scale(1.5);
  flex: none;
}
[dir="rtl"] #tool-root .mc-sprite { margin: -4px 4px -4px 10px; }

/*
 * The seed tools stop leaving a 449px band of dead app-colour under the map.
 *
 * Both seedmap pages ship the upstream app's PAGE-level sizing, because the port remaps
 * :root and html/body onto #tool-root — so #tool-root inherits `min-height: 100%`, which was
 * correct when it meant "fill the window" and is wrong when it means "fill the article
 * column". Measured on the live site: the stage sized itself to the viewport at 747px while
 * #tool-root stretched to 1196, and the app painted its own background across the 449px
 * difference. That is the flat blue under the 2D map and the flat white under the 3D one —
 * not a stylesheet failing to load, which is what it looks like.
 *
 * It also pushed everything after the tool down: the cross-promo section started at y=1397
 * instead of y=947, below a screenful of nothing.
 *
 * Matched on `:has(> .sm-stage)` rather than on the two slugs, so it keeps working if the
 * pages are renamed and cannot silently apply to a tool that is not this app. Verified by
 * measurement, not by eye: #tool-root 1196 -> 747, exactly its stage, gap 0.
 *
 * NOT fixed in the vendor CSS on purpose — vendor/seedmap is regenerated by
 * scripts/port-seedmap.mjs and any edit there is overwritten on the next re-port.
 */
#tool-root:has(> .sm-stage) {
  min-height: 0;
  height: auto;
}

/* ---------- shared VERSION + SNAPSHOTS bar ---------- */
/*
 * js/version-select.js mounts this above the widget on the tools whose minecraftmaps
 * counterpart carries a version selector. Scoped to #tool-root like everything else here, so
 * a widget's own class rules cannot outrank it.
 */
#tool-root .mct-vbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-2);
}
#tool-root .mct-vbar-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
#tool-root .mct-vbar-select { flex: 0 0 auto; min-width: 10ch; width: auto; }
/* aria-pressed IS the state — styling from it keeps one source of truth rather than a class
   the script would also have to keep in step. */
#tool-root .mct-vbar-snap {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
#tool-root .mct-vbar-snap[aria-pressed="true"] { border-color: var(--grass); color: var(--grass); }
/* The note only appears on legacy versions, so it must not reserve space when empty. */
#tool-root .mct-vbar-note:not(:empty) {
  flex: 1 1 20ch;
  min-width: 0;
  font-size: 12px;
  color: var(--fg-muted);
}

/* ---------- horizontal overflow ---------- *
 *
 * Measured, not guessed: scripts/audit-rendered.mjs --overflow laid out all 87 tool pages at 360,
 * 768 and 1440 and compared scrollWidth against clientWidth, walking ancestors for overflow-x
 * first so a deliberately clipped canvas is not counted. 404 findings on 20 tools; on 11 of them
 * the BODY was wider than the viewport, which is the one a reader feels — the whole page slides
 * sideways. Worst was /armor-trim-3d-viewer at 360px: body 936 against a 360 viewport.
 *
 * Only genuinely universal causes are handled here. The rest are fixed in the widget that owns
 * them, because a global rule broad enough to collapse an arbitrary fixed-column grid is also
 * broad enough to wreck the 67 tools that were already fine. CLAUDE.md's note about class-name
 * matching never being finishable cuts the other way too: a layout rule matched on nothing in
 * particular is not a fix, it is a second bug waiting for a different page.
 *
 * The first run of that sweep reported "87 pages rendered, 0 findings, 261 elements inspected —
 * clean". Three elements per page: every URL was /en/<slug>, English has no path prefix, and the
 * sweep measured the 404 page 87 times. Worth remembering before trusting a clean overflow run.
 */

/* A canvas is a replaced element with intrinsic dimensions, so it ignores its container and
 * paints at its attribute size. avatar-maker's #am-gl is 512x512 inside a 294px column, which is
 * where /avatar-maker's 185px of body overflow came from. `height: auto` is what keeps the aspect
 * ratio while `max-width` clamps it — without it the canvas squashes to 294x512. Neither touches
 * the backing store, so nothing is drawn at lower resolution. */
#tool-root canvas { max-width: 100%; height: auto; }

/* A select is sized by its widest option, which no container width can override.
 * dialog-input-builder's action-type select measured 279px inside a 144px cell.
 *
 * `min-width: 0` is the half that matters as a FLEX ITEM: min-width defaults to auto there, which
 * resolves to the select's longest option and refuses to shrink past it. hud-font-pack-tools' 14px
 * of overflow was one target-version select in a nowrap label doing exactly that.
 *
 * .mct-vbar-select above keeps its `min-width: 10ch` — a class beats an element selector at equal
 * id count, so that rule still wins and the version bar is unaffected. Checked, not assumed. */
#tool-root select { max-width: 100%; min-width: 0; }
/* The label around it may wrap instead of forcing its row wide. `flex-direction: row !important`
 * in the widget's own CSS is untouched: wrapping is a different property. */
#tool-root :is([class*="toggle-row"], [class*="-field-row"]) label { flex-wrap: wrap; }

/* A long unbreakable run — a resource-pack path, a registry id, a base64 blob — forces its track
 * wider than the container, and a flex or grid child defaults to min-width:auto, which refuses to
 * shrink below that content. Both halves are needed: min-width:0 lets the box shrink,
 * overflow-wrap lets the text break. hud-font-pack-tools' check rows measured 449px of
 * "assets/minecraft/font/..." inside 306px for exactly this reason. */
#tool-root :is([class*="-row"], [class*="-check"], [class*="-item"], [class*="-field"]) > * { min-width: 0; }
#tool-root :is([class*="-path"], [class*="-id"], [class*="-key"], [class*="-name"]) { overflow-wrap: anywhere; }

/* A fieldset's default `min-inline-size: min-content` is not overridable by width alone, so it
 * refuses to shrink below its widest child and pushes the page out. resource-pack-studio's
 * .rps-fieldset measured 404px inside a 328px column with `min-width: min-content` computed. This
 * is the one legacy quirk in this section that has nothing to do with the ports. */
#tool-root fieldset { min-width: 0; }

/* `anywhere`, not `break-word`. Only `anywhere` affects MIN-CONTENT sizing, which is the whole
 * point: a grid track or flex item is sized by its content's minimum, so a path like
 * `data/<namespace>/enchantment/<name>.json` sets a 359px floor no container width can beat.
 * custom-enchant-trim-builder and skin-viewer both overflowed on one such string. With spaces
 * available nothing breaks differently, so ordinary prose is unaffected. */
#tool-root :is(p, span, label, td, th, li, dd, dt, code, [class*="-label"], [class*="-note"],
               [class*="-hint"], [class*="-json"], [class*="-path"], [class*="-cmd"]) {
  overflow-wrap: anywhere;
}

/* A data table cannot shrink below its columns, so the WRAPPER has to scroll. Same treatment
 * `pre` already gets further up this file, and for the same reason: the content is a grid of
 * values that stops being readable if it reflows. spawn-proofing-calculator's table measured
 * 413px inside 328px. Naming here follows the convention the widgets already use; a table with no
 * wrapper at all is left alone, since adding scroll to the table box itself would need
 * `display: block` and that destroys column alignment. */
#tool-root :is([class*="table-wrap"], [class*="table-wrapper"], [class*="table-scroll"],
               [class*="tablewrap"], [class*="-table-outer"]) {
  overflow-x: auto;
}

/* Flex and grid items default to min-width:auto and refuse to shrink below their content. The
 * earlier rule above covers items in a container whose class contains -row/-check/-item/-field;
 * this covers the rest, where the container is named something the list does not predict —
 * hud-font-pack-tools' toggle rows nest a bare LABEL that then holds the long text. CLAUDE.md's
 * note that a class-name list can never be finished is why this stops guessing at container names
 * and states the property on the items instead.
 *
 * `span` is deliberately NOT in this list. Including it collapsed item-picker's glyph span to 2px
 * inside its button on five tools — a regression the next sweep caught, since the glyph then
 * painted 14px outside a 2px box. An inline span is virtually never the flex item that needs to
 * shrink; the block-level container around it is. */
#tool-root :is(label, p, div, section, fieldset) { min-width: 0; }

/* 3d-skin-editor's body-part picker is a humanoid FIGURE laid out on a fixed 20px grid — head
 * spanning columns 2-3, arms at 1 and 4, legs at 2 and 3. Its chips overflowed their cells by 8px
 * at every viewport, and the cause is this stylesheet: the generic button rule further up applies
 * `padding: 8px 13px`, which gives a chip a 26px minimum inside a 20px track.
 *
 * This is the trap the widget doctrine already records — `button:not(.btn):not([class*="tab"])`
 * got there first and made the schematic viewer's selected tab invisible in both themes. Same
 * rule, different victim. The chips carry their own sizing from the figure grid, so they want no
 * padding from here at all.
 *
 * Fixed from CSS rather than in vendor/widget-full/widget-full.css, which port-skin-tools
 * overwrites and which the doctrine flags as repeatedly mis-patched.
 *
 * `button.chip-button`, not `.chip-button`. The first attempt lost on specificity and the way it
 * lost is worth writing down, because `min-width` and `overflow` from the same block DID apply
 * while `padding` did not — which reads like a cascade mystery until the arithmetic is done.
 * `:is()` takes the specificity of its most specific argument, so
 * `#tool-root :is(.part-figure-main, …) .chip-button` is (1,2,0), while the generic button rule
 * `#tool-root button:not(.btn):not([class*="tab"])` is (1,2,1) — one extra element selector. It
 * only ever set padding, so only padding was contested. Naming the element here ties at (1,2,1)
 * and this block is later in the file. Measured after: 28px chips in 20px tracks became 20px,
 * scrollWidth 124 -> 116. */
#tool-root :is(.part-figure-main, .part-figure-side) button.chip-button {
  padding: 0;
  min-width: 0;
  overflow: hidden;
}

/* THE GENERIC BUTTON RULE, THIRD VICTIM: texture-maker's 16-colour palette.
 *
 * Same cause as the 3d-skin-editor chips above and the schematic viewer's invisible tab before
 * that: `#tool-root button:not(.btn):not([class*="tab"])` sets `padding: 8px 13px`, so a button
 * cannot be narrower than 28px however small its track is. The palette is 8 columns in a 240px
 * side column — 25.6px each — and it overflowed by exactly 19px, which is 8 × 28 + 7 × 5 gap
 * minus 240. Measured on /en/texture-maker at 1440: scrollWidth 1031 in a clientWidth of 1012,
 * traced to `#tmk-swatches` scrolling 259 in 240.
 *
 * A swatch is a colour, not a label — it has no text at all — so it wants no padding from here.
 *
 * THE FIX HAS TO LIVE IN THIS FILE, and that is the part worth writing down. The widget's own
 * `#tmk .tmk-swatch` is (1,1,0) and the generic rule is (1,2,1), so it lost on specificity; and
 * even a (1,2,1) selector in texture-maker.css would lose, because this stylesheet loads AFTER
 * every widget's and wins ties. Naming the element here ties at (1,2,1) and this block is later
 * in the file, which is the same arithmetic the chip fix above records.
 * The count has to be exact: `#tool-root button.tmk-swatch` is (1,1,1) and lost, because the
 * generic rule's two :not() arguments are class-level and it carries an element as well. The
 * parent class brings this to (1,2,1). */
#tool-root .tmk-swatches button.tmk-swatch { padding: 0; min-width: 0; }


/* ═══════════════════════════════════════════════════════════════════════════════════════
 * BA CHỖ CHỮ BỊ CHE — `soi_che_phu.py` quét 139 tool, tìm ra đúng 3 (10 chỗ)
 * ═══════════════════════════════════════════════════════════════════════════════════════ */

/* 1. `minimessage-viewer` / `server-text-studio` — ĐÃ GỠ BẢN VÁ CŨ, nó là một SAI LẦM.
 *
 *    Tôi từng ghi ở đây: "nhãn màu vô hình, chữ 8,5px đen trên ô đen, đo được 1,11:1" rồi
 *    dựng một dải nền đặc dưới ô màu để hiện tên. Soi lại bằng DevTools mới thấy luật gốc là
 *        #sts .sts-swatch span { position:absolute; inset:auto 0 -18px; opacity:0;
 *                                pointer-events:none }
 *    — nhãn CỐ Ý ẩn, nằm dưới ô 18px, chỉ hiện khi rê chuột. Nó chưa bao giờ hiển thị ra, nên
 *    "tương phản 1,11:1" là BÁO ĐỘNG GIẢ: bộ đo tương phản của tôi chấm màu trên một phần tử
 *    `opacity: 0`.
 *
 *    Tệ hơn, bản vá còn thêm `overflow: hidden` lên nút, mà nhãn thì nằm ở `bottom: -18px`
 *    — tức NGOÀI nút. Kết quả: chú giải khi rê chuột bị CẮT MẤT. Tôi đã phá một thứ đang
 *    chạy tốt để chữa một thứ không hỏng, và suốt mấy vòng đo không ai thấy vì phép đo chỉ
 *    nhìn con số, không nhìn màn hình.
 *
 *    Giữ lại đúng một thứ: trên thiết bị CẢM ỨNG không có "rê chuột", nên tên màu không bao
 *    giờ hiện được. Chừa chỗ rồi cho nó hiện hẳn. */
@media (pointer: coarse) {
  #tool-root button[class*="sts-swatch"] { margin-bottom: 20px; overflow: visible; }
  #tool-root button[class*="sts-swatch"] > span {
    opacity: 1;
    font-weight: 600;
    text-align: center;
  }
}

/* 2. `datapack-builders-simple` — NÚT XOÁ KHÔNG BẤM ĐƯỢC.
 *    Hàng là flex: [input 60px][input 780px][nút chọn vật phẩm][nút xoá].
 *    `.ipick-open` đặt `position:absolute; right:5px` tính theo CẢ HÀNG, nên nó rơi xuống
 *    đúng chỗ nút xoá (965 vs 970, cùng 36px) và nuốt mọi cú bấm.
 *    Sửa: đẩy nút chọn vào trong mép phải của ô nhập (chừa 48px cho nút xoá). Chỉ khoanh
 *    trong `.dbs-list-row` vì `.ipick-open` là thành phần dùng chung nhiều tool. */
#tool-root .dbs-list-row .ipick-open { right: 48px; }

/* 3. ⛔ `seed-map` — nút `?` (22px) lọt trong vùng một nút 38px cạnh nó. ĐÃ THỬ VÀ GỠ.
 *    `position:relative; z-index:5` KHÔNG ăn: nút nằm trong một tổ tiên `absolute; z-index:11`
 *    CÓ `transform`, tức một ngữ cảnh xếp chồng riêng — `z-index` của nút chỉ so với anh em
 *    trong ngữ cảnh đó, không bao giờ vượt được phần tử ở ngữ cảnh khác.
 *    Muốn thắng phải nâng z-index của chính tổ tiên, nhưng thế là đẩy cả bảng lọc đè lên thứ
 *    khác — đổi một lỗi lấy một lỗi. Đây là bố cục của app seedmap, phải sửa ở vendor.
 *    Để lại luật chết chỉ làm người sau tưởng đã xử lý. */


/* ═══════════════════════════════════════════════════════════════════════════════════════
 * CHỮ TO RÕ HƠN  (chủ site 06/10/2026: "cho to rõ ràng lên, không để bé quá. In đậm, tô
 * màu linh hoạt, phù hợp để tăng sự hiểu biết và trải nghiệm")
 *
 * Đo trước khi sửa — `do_co_chu.py`, 6.838 đoạn chữ trên 139 tool:
 *     96,8% chữ dưới 15px        29,4% dưới 13px        nhỏ nhất 8,5px
 *     hai nhóm lớn nhất: 14px (36,9%) và 13px (26,5%)
 *     chỗ bé nhất: .gcg-lib-name 10,5px · .eyebrow-sm 10px · .tmk-itemkind 10px
 *
 * ⛔ KHÔNG nâng đại trà bằng `font-size: larger` hay nhân hệ số: nhiều chỗ chữ bé là CÓ CHỦ Ý
 *    (nhãn trục toạ độ, chỉ số trong ô 26px). Nâng mù sẽ phá lưới. Nên đặt SÀN theo nhóm đã
 *    đo được, và luôn chạy lại phép đo tràn khung sau khi sửa.
 * ═══════════════════════════════════════════════════════════════════════════════════════ */

/* nền tảng: 14px → 15px cho chữ nội dung */
#tool-root { font-size: 15px; line-height: 1.55; }
#tool-root :is(p, li, dd, td, th, label, .prose) { font-size: 15px; }

/* SÀN 13px cho nhóm nhãn/ghi chú — đây là chỗ 29,4% chữ dưới 13px tập trung */
#tool-root :is([class*="-label"], [class*="-note"], [class*="-hint"], [class*="-desc"],
               [class*="-name"], [class*="-count"], [class*="-page"], [class*="-caption"],
               [class*="-kind"], [class*="-presetname"], [class*="-path"], small) {
  font-size: 13.5px;
}

/* nhãn mục IN HOA: 10px là quá bé dù có giãn chữ — 12px vẫn gọn mà đọc được */
#tool-root :is([class*="eyebrow"], legend, [class*="-kicker"]) {
  font-size: 12px;
  letter-spacing: .8px;
  font-weight: 700;
}

/* huy hiệu/chip: giữ nhỏ hơn chữ nội dung nhưng không dưới 12,5px */
#tool-root :is([class*="-tag"], [class*="badge"], [class*="chip"], [class*="-seg"]) {
  font-size: 12.5px;
}

/* ô danh sách dữ liệu (`.mcdb-list` — 150 chỗ, 12,5px) và ô vật phẩm */
#tool-root :is([class*="-list"], [class*="-item"], [class*="-cell"]) { font-size: 13.5px; }

/* IN ĐẬM + MÀU có chủ đích: nhãn đậm, giá trị đậm hơn, chữ phụ xám — phân cấp bằng
 * độ đậm và màu chứ không bằng đường kẻ (đúng tinh thần Floating UI). */
#tool-root :is(label, [class*="-label"]) { font-weight: 600; color: var(--fg); }
#tool-root :is([class*="-value"], [class*="-result"], [class*="-total"], strong, b) {
  font-weight: 700; color: var(--fg);
}
#tool-root :is([class*="-note"], [class*="-hint"], [class*="-desc"], small) {
  color: var(--fg-muted);
}
#tool-root :is(h1, h2, h3) { font-weight: 700; }
#tool-root h2 { font-size: 20px; }
#tool-root h3 { font-size: 17px; }
#tool-root :is(code, pre, kbd) { font-size: 14px; }

/* ═══════════════════════════════════════════════════════════════════════════════════════
 * SỬA TƯƠNG PHẢN CHẾ ĐỘ TỐI — theo đúng chỗ ĐO ĐƯỢC, không theo giả thuyết
 *
 * ⛔ Giả thuyết ban đầu của tôi SAI: tôi tưởng thiếu `color: inherit` ở `th/td`. Đo ra thì
 *    màu hỏng nhiều nhất là `rgb(234,240,242)` — tức chữ SÁNG của chế độ tối nằm trên nền
 *    SÁNG mà widget tự tô và không đổi theo chế độ. Ngược hẳn giả thuyết.
 * ═══════════════════════════════════════════════════════════════════════════════════════ */

/* `.wbdt-yes/.wbdt-no` — 20 chỗ, nền xanh/đỏ nhạt ghim cứng, chữ kế thừa thành vô hình */
:root[data-theme="dark"] #tool-root :is(.wbdt-yes, .wbdt-no) { color: #0b1410; }
/* `<caption>` và `<strong>` trong bảng tối: 1,47:1 */
:root[data-theme="dark"] #tool-root :is(caption, table strong) { color: var(--fg); }
/* ⛔ `pottery-flag-gallery` — ĐÃ THỬ VÀ GỠ RA, ghi lại để không ai làm lại.
 *    Mỗi ô `.pfg-sherd-icon` tô nền theo MÀU CỦA MẢNH GỐM nên nền khác nhau từng ô; đo được
 *    tỉ lệ 3,26 / 3,78 / 4,44 với chữ trắng và 3,36 / 3,96 / 4,24 với chữ tối. Đây là dải
 *    màu TRUNG TÍNH — cả trắng lẫn đen đều không đạt 4,5. Ép một màu chữ duy nhất làm số chỗ
 *    kém TĂNG từ 12 lên 20.
 *    Sửa đúng phải đổi markup: đặt nhãn lên một dải nền đặc riêng, hoặc tách nhãn ra khỏi ô
 *    màu. Không làm được bằng CSS mà vẫn giữ ý nghĩa "ô này LÀ màu mảnh gốm". */
/* mũi tên gấp/mở ở seed-map: 4,09:1 — nâng lên mức đọc được */
#tool-root :is([class*="toggle-arrow"], [class*="tool-arrow"]) { color: var(--fg); }

/* ═══════════════════════════════════════════════════════════════════════════════════════
 * BẢNG data-browser: cột NAME rơi chữ DỌC một ký tự mỗi dòng
 *
 * Bảng mang CẢ HAI lớp `regb-table mcdb-table`; chiều rộng `regb-id: 42%` vốn thiết kế cho
 * bảng 4 cột, áp lên bảng 8 cột làm cột NAME còn 38px. Đo sau khi sửa: chiều cao hàng
 * 109px → 64px, 50 hàng hiện trong chỗ trước đây chỉ vừa 5.
 * ═══════════════════════════════════════════════════════════════════════════════════════ */
#tool-root .mcdb-table :is(.regb-th-id, .regb-id) { width: auto; }
#tool-root .mcdb-table th { white-space: nowrap; }
#tool-root .mcdb-table { min-width: 1040px; }

/* ═══════════════════════════════════════════════════════════════════════════════════════
 * NÚT "Full Screen" — thôi đè lên nội dung
 *
 * Chủ site chỉ ra, `soi_che_phu.py` xác nhận:
 *     span.sk-edition-note "Java accepts 64×64…"  ←  button.fsbtn [absolute, z=80]
 * Script nội trang neo nút vào `main.t9b__than` (toàn bộ cột nội dung) nên "góc phải trên" rơi
 * trúng bất cứ thứ gì ở hàng đầu. `lang.js` chuyển nút vào hàng `.thead`; dưới đây là phần
 * tạo kiểu cho chỗ mới.
 * ═══════════════════════════════════════════════════════════════════════════════════════ */
.t9b .thead .tbar-fs {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.t9b .thead .tbar-fs .fsbtn.fsbtn-inline {
  position: static; margin-left: auto; z-index: auto;
}


/* ── sửa tương phản cho widget, số đo kèm theo từng dòng ────────────────────────────────── */

/* `#2f8f5b` trên nền trắng chỉ 4,04:1 ở cỡ 12px. Một màu không thể hợp cả hai chế độ
 * (#2c8656 đạt 4,51 nền sáng nhưng tụt 3,95 nền tối), nên tách theo chế độ. */
#tool-root .hbc-stat-best { color: #297d4f; }                 /* 5,07 trên trắng · 4,57 trên --surface-2 */
:root[data-theme="dark"] #tool-root .hbc-stat-best { color: #329861; }  /* 4,58–5,06 trên ba nền tối */

/* Chín huy hiệu nguồn của `item-source-finder` đều khai `color:#fff`, đúng cho 7 nền.
 * Hai nền vàng thì chữ trắng chỉ 3,23 và 3,47:1 — chữ đen cho 5,39 và 5,01:1. */
#tool-root .isf-tag-loot,
#tool-root .isf-tag-bartering { color: #1a1a1a; }


/* ═══════════════════════════════════════════════════════════════════════════════════════
 * ĐIỆN THOẠI (390px) — ba lỗi mà MỌI vòng đo trước đều mù, vì tất cả đều chạy ở 1440px
 * `soi_dien_thoai.py` quét 137 tool: 39 tràn ngang · 43 có vùng chạm <24px · 18 có chữ <12px
 * ═══════════════════════════════════════════════════════════════════════════════════════ */

/* 1. TRÀN NGANG — 39/137 tool, và đây mới là LÝ DO THẬT khiến chữ trông bé trên điện thoại.
 *    Trong thẻ "Related tools" cuối trang, `<span>` chứa tên tool không co lại được, nên
 *    `.hlcard` rộng hơn khung. Chrome ở chế độ điện thoại gặp nội dung quá khổ thì NỚI khung
 *    nhìn bố cục ra cho vừa — 390 → 436 — và hậu quả là CẢ TRANG bị thu nhỏ khoảng 12%: mọi
 *    dòng chữ, mọi cái nút, ở mọi chỗ. Không một dòng CSS cỡ chữ nào sai cả.
 *
 *    ⛔ Đã thử `min-width:0` trên `.hlbody`, trên `.hlcard`, trên cả hai, và đổi
 *       `minmax(200px,1fr)` thành `minmax(min(200px,100%),1fr)` — ĐO TỪNG CÁI, cả bốn vẫn
 *       436px. Chỉ khi chính `<span>` được phép co VÀ xuống dòng thì mới về 390. Suy luận về
 *       flexbox bốn vòng không bằng một thí nghiệm. */
.t9b .hlcard .hlbody { min-width: 0; }
.t9b .hlcard .hlbody span { min-width: 0; overflow-wrap: anywhere; }

/* 2. VÙNG CHẠM QUÁ NHỎ — 43/137 tool, trong đó 136 ô tick vẽ ở đúng 13×13px (cỡ mặc định của
 *    trình duyệt). Ngón tay không bấm trúng thì nút đẹp mấy cũng vô dụng; WCAG 2.5.8 đặt sàn
 *    24×24. Khoanh trong `pointer: coarse` nên chuột trên máy tính không đổi một pixel nào. */
@media (pointer: coarse) {
  /* ⛔ `width` thôi là CHƯA ĐỦ: ô tick nằm trong hàng flex vẫn bị co lại — đo được 17×24,
   *    tức `height` ăn còn `width` thì không. Phải chặn co bằng `flex: none`. */
  #tool-root input[type="checkbox"],
  #tool-root input[type="radio"] {
    width: 24px;
    height: 24px;
    min-width: 24px;
    min-height: 24px;
    flex: none;
  }
  /* Thanh trượt ngang cao 16px thì ngón tay trượt rất dễ rơi ra ngoài.
   * ⛔ CHỪA thanh dọc (`orient="vertical"`, như thước độ cao của `ore-distribution`):
   *    ép `height` ở đó là bóp nát chính cái thước. */
  #tool-root input[type="range"]:not([orient="vertical"]) { height: 24px; }
  #tool-root :is(button, a[href])[class*="-item"] { min-height: 28px; }
}

/* 3. CHỮ DƯỚI 12px — 18/137 tool. Dưới 12px trên màn hình điện thoại là đọc bằng cách đoán.
 *    Liệt kê ĐÍCH DANH các lớp đo được, không quét bằng `[class*=...]`: kiểu quét đó từng
 *    kéo theo cả những chỗ không liên quan và làm hỏng 12 tool trong đợt này. */
/*    ⛔ VÌ SAO LẶP `#tool-root` BA LẦN: vòng vá đầu dùng `#tool-root :is(…)` = (1,1,0) và
 *       `.cm-chip` vẫn trơ ra 11px. Hỏi DevTools mới biết kẻ thắng là
 *       `#tool-root #capemaker :is(.cm-chip, .cm-ghost)` = (2,1,0) — luật của chính bộ vá này
 *       viết ở vòng trước. Lặp ID cho (3,1,0) là cách gọn nhất để chắc chắn thắng mọi luật
 *       theo-tool mà không phải dùng `!important`. */
@media (max-width: 480px) {
  #tool-root#tool-root#tool-root
    :is(.cpn-blank, .cpn-slotmeta, .cpn-slotname, .pfg-sherd-icon, .pfg-pot-face,
        .cct-effectid, .gcz-texrole, .ssr-capsub, .ssr-statlabel, .ssr-statsub,
        .cm-chip, .cm-ghost, .bsg-statlabel, .hbc-stat-unit, .pc-lbl,
        .sir-icon-placeholder, .gcg-lib-title, .stat-value, .sm-edge-tab-mini,
        .ored-ruler span, button[class*="sts-swatch"] > span) {
    font-size: 12px;
  }
}
/* 4. NHÃN NÚT BỊ CẮT trên thanh công cụ `seed-map` ở 390px: "26.2" hiện ra "26.⁚", số seed cụt
 *    đuôi, và "Share" gãy giữa từ thành "Shar e".
 *    `.tb-group` là lưới cột ghim cứng theo px; cho cột tự co theo nội dung và cấm nút gãy chữ
 *    là đủ cứu ba chỗ đó (ảnh chụp trước/sau xác nhận).
 *    ⛔ CÒN LẠI, CHƯA SỬA: hai ô chọn "Overworld" và "Surface" vẫn cụt. Chúng nằm trong
 *       `div.seed-card` — cũng là lưới, nhưng cột `62px 62px 34px 72px` do CHÍNH TOOL tính ra
 *       lúc chạy. Đè lên đó là đùa với bố cục của cả bản đồ, nên để nguyên và báo lại.
 *       Đã thử bốn cách (flex xuống dòng, auto-fit, thu nhỏ chữ, cho thẻ bọc wrap) — cách nào
 *       cũng hoặc không ăn, hoặc kéo thanh công cụ cao gấp ba và nhìn rối hơn hẳn. */
@media (max-width: 480px) {
  #tool-root#tool-root .tb-group { grid-template-columns: auto auto; }
  #tool-root#tool-root .tb-group :is(button, select) { white-space: nowrap; }
}

/* ⛔ KHÔNG đụng chữ trong `<svg>` của `world-border-planner` / `world-border-difficulty-tools`
 *    (10px). Chữ ở đó đặt theo TOẠ ĐỘ CỐ ĐỊNH trong sơ đồ; phóng to lên là chúng chồng vào
 *    nhau, còn khó đọc hơn lúc nhỏ. Chữ nhỏ trong một sơ đồ là nhãn trục, không phải chữ
 *    giao diện — để nguyên và báo lại cho chủ site quyết. */
/* seed-map man hep 08/10 */
@media(max-width:560px){
  /* Tra lai cach dan GOC cua tool: ban de `.tb-group{auto auto}` cua minh (dung de
     cuu "Share" gay giua tu o man rong) chinh la thu lam cot co xuong 62px o day. */
  #tool-root#tool-root#tool-root .tb-group{grid-template-columns:revert}
  /* `<select>` tu co theo noi dung chu khong theo o luoi -> phai ep 100%. */
  #tool-root#tool-root#tool-root #toolbar.seed-card select{
    font-size:11.5px;padding-inline:4px;width:100%;max-width:none}
}
/* vung cham 24px 08/10 */
/* WCAG 2.5.8: dich bam toi thieu 24x24. Chi NANG cai dang thieu, khong dat kich thuoc
   co dinh — dat cung la pha bo cuc cua 137 tool.
   ⛔ `:has(> input)` KHONG du: nhieu nhan boc o danh dau trong mot <span>, phai dung
      hau due. ⛔ Thanh truot DOC thieu be NGANG chu khong phai chieu cao. */
#tool-root label:has(input[type=checkbox]),
#tool-root label:has(input[type=radio]){min-height:24px;display:inline-flex;align-items:center}
#tool-root button,#tool-root summary{min-height:24px}
#tool-root input[type=range]{min-height:24px;min-width:24px}
#tool-root input[type=color]{min-width:24px;min-height:24px}
