/* ===========================================================================
   Olenza — bộ giao diện DÙNG CHUNG cho cả bốn site.
   ===========================================================================

   # VÌ SAO FILE NÀY TỒN TẠI

   Trước 2026-09-28, ba codebase dựng giao diện độc lập: olenza.io là HTML
   tĩnh với CSS nội tuyến, olenza-account có 288 dòng CSS riêng (phục vụ cả
   account.olenza.io lẫn node.olenza.io), olenza-explorer có 364 dòng CSS
   riêng. Không file nào dùng chung với file nào.

   Đo được hậu quả: thanh nav cao 64 / 60 / 60 / 83 px ở bốn site nên nó
   NHẢY khi người dùng chuyển trang; bốn bộ link điều hướng khác nhau; ba
   kiểu xác thực khác nhau ("Account" / "Log in + Sign up" / "Account");
   một trang explorer dùng 12 cỡ chữ khác nhau (13.12, 13.3333, 13.6,
   14.08 px — sản phẩm của `em` lồng nhau, không phải một thang chữ).

   File này là nguồn DUY NHẤT. nginx phục vụ nó ở /shared/olenza.css trên
   cả bốn host từ cùng một file trên đĩa, nên không có bản sao nào để trôi.

   # BẢNG MÀU — GIỮ NGUYÊN, KHÔNG SỬA

   Phần token màu dưới đây bê nguyên từ stylesheet cũ của explorer. Nó đã
   được đo theo WCAG AA và có một quy tắc đã chốt:

       THƯƠNG HIỆU ĐỊNH DANH, TRẠNG THÁI THÔNG BÁO.
       brand  -> dấu hiệu, wordmark, nút chính, vòng focus.
       status -> badge, thông báo. KHÔNG BAO GIỜ dùng màu thương hiệu.

   Lý do: dấu hiệu Olenza là hổ phách và nâu đỏ, đúng chỗ "cảnh báo" và
   "lỗi" đang ở. Sienna cách --warn 8.7° sắc độ và cách --bad 24.8°. Tô
   link bằng màu thương hiệu sẽ khiến "đây là link", "đây là cảnh báo" và
   "cái này hỏng" thành ba sắc của cùng một màu.

   # HAI THỨ MỚI

   1. THANG CHỮ và THANG KHOẢNG CÁCH tường minh. Mọi cỡ chữ phải lấy từ
      --t-*, mọi khoảng cách từ --s-*. Không `em` lồng nhau, vì đó chính là
      cái đẻ ra 12 cỡ chữ trên một trang.

   2. BỐ CỤC SNAP. Mỗi trang là một chồng card, mỗi card vừa đúng một màn
      hình, cuộn một nhịp là sang card kế. KHÔNG BAO GIỜ có thanh cuộn bên
      trong card — bảng dài thì phân trang, không cuộn.
   ======================================================================== */

:root {
  /* --- màu: giữ nguyên, đã đo --- */
  accent-color: #B4541C;
  --text: #1F1B17;
  --muted: #6B625A;
  --line: #E7E1DA;
  --bg: #fff;
  --soft: #FCFAF8;
  --accent: #1A5FA8;
  --accent-text: #fff;
  --brand: #B4541C;
  --brand-gold: #D99A32;
  --brand-text: #fff;
  --brand-ink: #1C1814;
  --ok: #17803D;
  --warn: #B35C00;
  --bad: #C0262D;
  --ok-bg: #eaf6ee;
  --accent-bg: #e9effb;
  --warn-bg: #fdf3e6;
  --bad-bg: #fdecec;
  --info-bg: #eaf1fc;

  /* --- thang chữ: 7 bậc, CO THEO KHUNG ---------------------------------
     Khung là một hàm của màn hình (rộng = min(100vw − 2·mép, --measure),
     cao = 100dvh − shell − 2·mép), nên chữ bám theo màn hình thì cũng là
     bám theo khung.

     Mỗi bậc là clamp(sàn, min(bề-ngang, chiều-cao), trần). Lấy min của HAI
     chiều chứ không riêng bề ngang: một cửa sổ rộng mà thấp (1600×700, hay
     điện thoại xoay ngang) nếu chỉ tính vw sẽ có chữ to trong một khung
     lùn, và khung lập tức tràn quá một màn.

     Sàn giữ cho chữ không bao giờ nhỏ tới mức khó đọc trên điện thoại;
     trần giữ cho màn 4K không thành áp phích. */
  --t-xs:  clamp(11px,   min(0.85vw, 1.45vh), 12.5px);  /* nhãn phụ */
  --t-sm:  clamp(12px,   min(0.95vw, 1.60vh), 14px);    /* nhãn bảng */
  --t-md:  clamp(13px,   min(1.10vw, 1.90vh), 16px);    /* chữ thường */
  --t-lg:  clamp(15px,   min(1.30vw, 2.20vh), 19px);    /* tiêu đề nhỏ */
  --t-xl:  clamp(17px,   min(1.70vw, 2.90vh), 26px);    /* tiêu đề khung */
  --t-2xl: clamp(20px,   min(2.60vw, 4.40vh), 38px);    /* số liệu lớn */
  --t-3xl: clamp(26px,   min(3.60vw, 6.00vh), 54px);    /* tiêu đề trang chủ */

  /* --- thang khoảng cách: bội số của 4 --- */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;

  --radius: 6px;
  --shell-h: 56px;      /* CAO BẰNG NHAU Ở CẢ BỐN SITE. Không site nào đổi. */
  --frame-gap: 16px;    /* mép quanh khung tranh */
  /* Thanh trang (chọn chain + tab) — chỉ có trên một số trang. Khi không
     có nó thì hai biến này bằng 0 và hình học khung không đổi. */
  --bar-h: 0px;
  --bar-sp: 0px;
  --measure: 1180px;    /* bề ngang tối đa của khung */
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    accent-color: #D99A32;
    --text: #ECE7E1;
    --muted: #A39A90;
    --line: #38302A;
    --bg: #17130F;
    --soft: #221C17;
    --accent: #78A9E6;
    --accent-text: #17130F;
    --brand: #D99A32;
    --brand-gold: #D99A32;
    --brand-text: #17130F;
    --brand-ink: #17130F;
    --ok: #4CC27A;
    --warn: #E79A42;
    --bad: #EF6B6F;
    --ok-bg: #16281c;
    --accent-bg: #17203a;
    --warn-bg: #2d2214;
    --bad-bg: #2e1718;
    --info-bg: #17223a;
  }
}

/* ========================================================================
   NỀN
   ==================================================================== */

*, *::before, *::after { box-sizing: border-box; }

/* Thuộc tính [hidden] PHẢI ẩn, kể cả khi phần tử có display riêng (vd .start,
   .card là display:flex — chúng đè display:none mặc định của UA, nên JS đặt
   hidden=true mà phần tử vẫn hiện). views.js dùng [hidden] để ẩn khối guest
   (Create a free account) khi đã đăng nhập (user báo 2026-10-01). */
[hidden] { display: none !important; }

html {
  /* MỘT MÀN HÌNH = MỘT KHUNG. Cuộn một nhịp sang khung kế.
     `always` chặn một cú lướt mạnh nhảy qua hai khung.

     Điều kiện để mô hình này không loãng: mỗi khung phải được XẾP CHO ĐẦY.
     Bản trước có snap nhưng không có điều kiện ấy, và đo được node.olenza.io
     thành 5 màn dùng trung bình 34 phần trăm chỗ. Khung rỗng là lỗi bố cục,
     không phải lỗi của snap. */
  scroll-snap-type: y mandatory;
  scroll-padding-top: calc(var(--shell-h) + var(--bar-sp) + 2 * var(--frame-gap));
  scroll-behavior: smooth;
}

body {
  margin: 0;
  /* Nền TRANG là --soft, nền KHUNG là --bg. Trước đây cả hai cùng trắng
     nên chỉ mỗi đường viền 1px phân biệt khung với nền, và nó không đọc
     ra là một cái khung. Chênh lệch này là "mặt bồi" của khung tranh. */
  background: var(--soft);
  color: var(--text);
  font: var(--t-md)/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

:where(a, button, summary, input, select):focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 3px;
}

h1, h2, h3 { margin: 0; font-weight: 650; line-height: 1.2; letter-spacing: -0.01em; }
h1 { font-size: var(--t-xl); }
h2 { font-size: var(--t-lg); }
h3 { font-size: var(--t-sm); font-weight: 600; color: var(--muted);
     text-transform: uppercase; letter-spacing: 0.06em; }
p { margin: 0 0 var(--s-3); }
p:last-child { margin-bottom: 0; }

/* ========================================================================
   SHELL — giống hệt nhau ở cả bốn site
   ------------------------------------------------------------------------
   Hai thứ duy nhất trong thanh này: dấu hiệu (luôn dẫn về olenza.io) và
   Account. Các link sang sản phẩm khác hiện trên desktop; trên điện thoại
   chúng nhường chỗ cho card "đi đâu" ở cuối mỗi chồng card, vì nhồi năm
   link vào 390px là cách thanh nav explorer phình lên 170px.
   ==================================================================== */

/* Header là MỘT KHUNG, cùng họ với khung tranh bên dưới: cùng bề ngang
   (--measure), cùng viền, cùng bo góc, cùng bóng đổ, cùng nền --bg.
   Trước đây nó là một dải chạy tràn mép màn hình với nền mờ và mỗi đường
   viền dưới — đặt trên một khung tranh bo góc thì nó lạc loài.

   .masthead là lớp bọc dính ở mép trên, nền --soft ĐẶC: nội dung cuộn lên
   phải biến mất sau nó, không được lộ ra trong khe giữa mép màn hình và
   khung header. */
.masthead {
  position: sticky; top: 0; z-index: 50;
  padding: var(--frame-gap) var(--frame-gap) 0;
  background: var(--soft);
}
.shell {
  height: var(--shell-h);
  max-width: var(--measure); margin: 0 auto;
  display: flex; align-items: center; gap: var(--s-4);
  /* Đệm ngang bằng đúng đệm ngang của khung nội dung, để dấu hiệu Olenza
     thẳng cột với tiêu đề của khung bên dưới. */
  padding: 0 var(--s-6);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgb(0 0 0 / .05), 0 10px 30px -14px rgb(0 0 0 / .16);
}

/* MỘT header cho cả bốn site (2026-09-30, theo yêu cầu): trái là dấu Olenza
   và ba nút sản phẩm Olenza · Node · Explorer; phải là Pricing · Docs · API ·
   Account. Giống hệt nhau ở mọi site — chỉ nút "đang ở đây" đổi. Trước đó mỗi
   site ghi một tên ("Olenza Node", "Olenza Explorer", "Olenza Account") và một
   bộ link hơi khác, nên chuyển site là header nhảy. */
.shell .mark { display: flex; align-items: center; flex: none; }
.shell .mark img { width: 34px; height: 34px; display: block; }

.shell nav.prods { display: flex; align-items: center; gap: 2px; margin-left: var(--s-1); }
.shell nav.prods a {
  padding: 6px 13px; border-radius: 999px;
  color: var(--muted); text-decoration: none; white-space: nowrap;
  font-size: var(--t-md); font-weight: 650; letter-spacing: -0.01em;
}
.shell nav.prods a:hover { color: var(--text); background: var(--soft); }
.shell nav.prods a.here { color: var(--brand); background: color-mix(in srgb, var(--brand) 12%, transparent); }

.shell nav.side { margin-left: auto; display: flex; align-items: center; gap: var(--s-5); }
.shell nav.side a {
  color: var(--muted); text-decoration: none; font-size: var(--t-md);
  white-space: nowrap;
}
.shell nav.side a:hover { color: var(--text); }
.shell nav.side a.here { color: var(--text); font-weight: 600; }

/* Account: MỘT cái điều khiển duy nhất, tên giống nhau ở cả bốn site.
   Đăng nhập rồi thì nó mở menu; chưa thì nó dẫn tới trang đăng nhập.
   Hành vi đổi theo trạng thái, KHÔNG đổi theo site — đó là chỗ trước đây
   bốn site có ba kiểu khác nhau. */
.acct { position: relative; }
/* .acctlink là cùng một cái điều khiển ấy trên site KHÔNG nhìn thấy phiên
   đăng nhập (olenza.io tĩnh, explorer). Nó phải trông y hệt: người dùng
   không cần biết site nào đọc được cookie nào. */
.acct > summary, .acctlink {
  list-style: none; cursor: pointer; text-decoration: none;
  display: flex; align-items: center; gap: var(--s-2);
  font-size: var(--t-md); color: var(--text);
  padding: var(--s-1) var(--s-3);
  border: 1px solid var(--line); border-radius: 999px;
}
.acctlink:hover { border-color: var(--brand); }
/* Trên account.olenza.io nút Account là "chỗ đang đứng", tô như pill sản
   phẩm đang chọn (trước 2026-09-30 header ở đây không đánh dấu gì). */
.acct.here > summary, .acctlink.here {
  color: var(--brand); border-color: color-mix(in srgb, var(--brand) 40%, transparent);
  background: color-mix(in srgb, var(--brand) 12%, transparent);
}
.acct > summary::-webkit-details-marker { display: none; }
.acct > summary::after {
  content: ""; width: 5px; height: 5px; margin-left: 2px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
}
.acct[open] > summary { border-color: var(--brand); }
.acct .menu {
  position: absolute; right: 0; top: calc(100% + var(--s-2));
  min-width: 208px; padding: var(--s-2);
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: 0 8px 28px rgb(0 0 0 / 0.12);
  display: flex; flex-direction: column;
}
.acct .menu a, .acct .menu button {
  padding: var(--s-2) var(--s-3); border-radius: var(--radius);
  color: var(--text); text-decoration: none; font-size: var(--t-md);
  background: none; border: 0; text-align: left; cursor: pointer; font: inherit;
}
.acct .menu a:hover, .acct .menu button:hover { background: var(--soft); }
.acct .menu hr { border: 0; border-top: 1px solid var(--line); margin: var(--s-2) 0; }
.acct .who { padding: var(--s-2) var(--s-3); font-size: var(--t-xs); color: var(--muted); }

/* ========================================================================
   CARD — một card = một màn hình
   ------------------------------------------------------------------------
   min-height chứ không phải height, và đó là chủ ý: nếu nội dung một card
   cao hơn màn hình (điện thoại nhỏ, người dùng phóng chữ, chữ dài hơn khi
   dịch) thì card GIÃN RA và trang vẫn cuộn qua nó bình thường. Dùng height
   thì phần thừa bị cắt và không cách nào tới được.
   ==================================================================== */

.deck { padding: var(--frame-gap); display: flex; flex-direction: column; gap: var(--frame-gap); }

/* .card là KHUNG TRANH: một màn hình, có viền, có mép.
   min-height chứ không height — nội dung vượt khung thì khung giãn ra chứ
   không cắt mất chữ. Đó là lối thoát cho trang tài liệu và cho người phóng
   to cỡ chữ. */
.card {
  scroll-snap-align: start;
  scroll-snap-stop: always;
  /* mép trên header + header + mép + khung + mép dưới */
  min-height: calc(100dvh - var(--shell-h) - var(--bar-sp) - 3 * var(--frame-gap));
  box-sizing: border-box;
  margin: 0 auto; width: 100%; max-width: var(--measure);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgb(0 0 0 / .05), 0 10px 30px -14px rgb(0 0 0 / .16);
  padding: var(--s-5) var(--s-6);
  display: flex; flex-direction: column; gap: var(--s-4);
}
.card + .card { border-top: 1px solid var(--line); }
.card + .card { border-top: 1px solid var(--line); padding-top: var(--s-5); }

/* .top dành cho card có BẢNG: bảng phải bắt đầu ngay dưới tiêu đề, và số
   dòng của nó vốn đã co theo chiều cao màn hình nên không cần căn giữa.
   Card không có bảng thì căn giữa — căn trên sẽ để lại một mảng trống lớn
   phía dưới, đúng cái làm trang trông sơ sài. */
/* .top: nội dung bám mép trên của khung (khung có bảng).
   Không có .top thì các phần tử dàn đều theo chiều dọc. */
.card.top { justify-content: flex-start; }
/* .fill: phần tử này ăn hết chỗ thừa của khung — đây là cái làm khung ĐẦY
   thay vì để một mảng trống ở dưới. */
.card > .fill { flex: 1; min-height: 0; display: flex; flex-direction: column; }

.card > header { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap; }
.card > header .ticker { font-size: var(--t-sm); color: var(--muted); font-family: var(--mono); }
.card > header .grow { margin-left: auto; }

/* Gợi ý còn card nữa ở dưới. Ẩn trên card cuối bằng class .last.
   Đặt tuyệt đối chứ không dùng `margin-top: auto`: với margin auto nó đẩy
   phần còn lại lên trên, nên card căn giữa hoá ra căn trên và để lại một
   mảng trống ở dưới. */
/* .cue trỏ sang "card kế" — không còn card kế nữa. Ẩn đi chứ không xoá
   khỏi template, để một lượt sửa CSS không phải kèm 37 lượt sửa HTML. */
.cue { display: none; }
.cue::after {
  content: ""; width: 8px; height: 8px; margin-left: var(--s-2);
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg); align-self: center;
}
.card.last .cue { display: none; }

/* ========================================================================
   CHỈ SỐ — MỘT khuôn duy nhất
   ------------------------------------------------------------------------
   Trước đây bốn thẻ chỉ số trên trang chain mỗi thẻ một kiểu: một thẻ có
   pill trạng thái, một thẻ có link, một thẻ chữ mono nhỏ, một thẻ tràn số
   ra ngoài (Difficulty hiện "132,757,073,449,48" — cụt giữa chừng). Đó là
   lý do bốn thẻ trông như bốn thứ rời nhau.

   Khuôn ở đây là: NHÃN, SỐ, và một dòng phụ không bắt buộc. Hết. Mọi thẻ
   đều có đúng ba phần đó, kể cả khi dòng phụ trống.
   ==================================================================== */

.stats {
  display: grid; gap: var(--s-3);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.stat {
  padding: var(--s-4);
  /* Trong khung (nền --bg) thì --soft vẫn nổi lên đúng chiều: nhạt hơn
     nền trang, đậm hơn nền khung. */
  background: var(--soft); border: 1px solid var(--line); border-radius: var(--radius);
  display: flex; flex-direction: column; gap: var(--s-1);
  min-width: 0;                       /* cho phép con co lại, nếu không số dài đẩy vỡ lưới */
}
.stat .k { font-size: var(--t-xs); color: var(--muted);
           text-transform: uppercase; letter-spacing: 0.06em; }
.stat .v {
  font-size: var(--t-2xl); font-weight: 650; line-height: 1.1;
  letter-spacing: -0.02em;
  /* Số to phải TỰ THU LẠI chứ không được tràn. Đây là chỗ Difficulty bị
     cắt cụt trước đây: chữ cố định cỡ, ô thì hẹp. */
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}
.stat .v.long { font-size: var(--t-xl); }   /* số rất dài: hạ một bậc, vẫn đọc được */
.stat .sub { font-size: var(--t-sm); color: var(--muted); min-height: 1.4em; }
.stat .sub a { color: var(--accent); }

/* ========================================================================
   BẢNG — luôn vừa một màn hình
   ------------------------------------------------------------------------
   Không có thanh cuộn trong card, nên số dòng phải tự co theo chiều cao
   màn hình. Không dùng JS: các truy vấn media theo CHIỀU CAO ẩn bớt dòng
   cuối. Phần bị ẩn luôn tới được qua nút phân trang bên dưới.
   ==================================================================== */

.rows { width: 100%; border-collapse: collapse; font-size: var(--t-md); }
.rows th {
  text-align: left; font-size: var(--t-xs); color: var(--muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.06em;
  padding: 0 var(--s-3) var(--s-2); border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
/* KHÔNG nowrap mặc định. Bảng ở trang tài liệu có ô là câu văn, và ép
   nowrap cho mọi ô làm trang API tràn ngang 1310px trên điện thoại (đo
   2026-09-28). Nowrap chỉ đúng với thứ không được phép xuống dòng: số và
   hash — chúng tự khai báo bằng class của mình. */
/* Đệm dọc 8px chứ không phải 12px: một dòng bảng cao ~42px thay vì 50px.
   Đây là trang dữ liệu; 24px đệm mỗi dòng nhân với mười mấy dòng là cả một
   mảng trắng đẩy dữ liệu ra khỏi khung. */
.rows td { padding: var(--s-2) var(--s-3); border-bottom: 1px solid var(--line); }
.rows td.num, .rows td.nw, .rows th { white-space: nowrap; }
.rows tbody tr:hover td { background: var(--soft); }
.rows .num { text-align: right; font-variant-numeric: tabular-nums; }
.rows .hash { font-family: var(--mono); font-size: var(--t-sm); }
.rows td:first-child, .rows th:first-child { padding-left: 0; }
.rows td:last-child, .rows th:last-child { padding-right: 0; }

/* Số dòng hiện ra co theo CHIỀU CAO MÀN HÌNH, vì khung là một màn hình.
   Hai hướng sai đều đã gặp: quá ít dòng thì khung hở một mảng trống ở
   dưới, quá nhiều thì khung phình quá một màn. Các mức dưới đây được ĐO
   trên trang chain chứ không ước lượng. Phần dữ liệu không hiện ra luôn
   tới được bằng nút phân trang ngay dưới bảng. */
.rows[data-fit] tbody tr:nth-child(n+17) { display: none; }
@media (max-height: 1200px) { .rows[data-fit] tbody tr:nth-child(n+15) { display: none; } }
@media (max-height: 1100px) { .rows[data-fit] tbody tr:nth-child(n+12) { display: none; } }
@media (max-height: 1000px) { .rows[data-fit] tbody tr:nth-child(n+12) { display: none; } }
@media (max-height:  900px) { .rows[data-fit] tbody tr:nth-child(n+9)  { display: none; } }
@media (max-height:  800px) { .rows[data-fit] tbody tr:nth-child(n+8)  { display: none; } }
@media (max-height:  700px) { .rows[data-fit] tbody tr:nth-child(n+6)  { display: none; } }
@media (max-height:  600px) { .rows[data-fit] tbody tr:nth-child(n+5)  { display: none; } }

.pager { display: flex; align-items: center; gap: var(--s-3); font-size: var(--t-sm); }
.pager .grow { margin-left: auto; }
.pager .at { color: var(--muted); font-variant-numeric: tabular-nums; }

/* ========================================================================
   BỘ CHỌN CHAIN — thay cho 9 link trên thanh nav
   ------------------------------------------------------------------------
   Chín link chain trên thanh nav làm nó cao 170px trên điện thoại, tức 20%
   màn hình chỉ để liệt kê. Bộ chọn này là MỘT nút; nó cũng thuộc về nội
   dung explorer chứ không thuộc shell, nhờ vậy thanh shell cao bằng nhau
   ở cả bốn site.
   ==================================================================== */

.chainpick { position: relative; display: inline-block; }
.chainpick > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg); font-size: var(--t-md); font-weight: 600;
}
.chainpick > summary::-webkit-details-marker { display: none; }
.chainpick > summary::after {
  content: ""; width: 5px; height: 5px; margin-left: var(--s-1);
  border-right: 1.5px solid var(--muted); border-bottom: 1.5px solid var(--muted);
  transform: rotate(45deg) translateY(-2px);
}
.chainpick[open] > summary { border-color: var(--brand); }
.chainpick img { width: 20px; height: 20px; display: block; flex: none; }

/* Neo PHẢI, không phải trái. Nút chọn chain nằm ở mép phải của đầu card,
   nên một bảng ba cột neo trái sẽ thò hẳn ra ngoài màn hình (thấy khi mở
   nó trên /btc ở 1440px). */
.chainpick .list {
  position: absolute; right: 0; left: auto; top: calc(100% + var(--s-2)); z-index: 40;
  max-width: calc(100vw - 2 * var(--s-4));
  display: grid; grid-template-columns: repeat(3, minmax(150px, 1fr));
  gap: var(--s-1); padding: var(--s-2);
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: 0 10px 32px rgb(0 0 0 / 0.14);
}
.chainpick .list a {
  display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3); border-radius: var(--radius);
  color: var(--text); text-decoration: none; font-size: var(--t-md);
}
.chainpick .list a:hover { background: var(--soft); }
.chainpick .list a[aria-current],
.chainpick .list .here {
  background: var(--soft); font-weight: 600;
  display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-3); border-radius: var(--radius);
  color: var(--text); font-size: var(--t-md);
}
.chainpick .list .tk { margin-left: auto; font-family: var(--mono);
                       font-size: var(--t-xs); color: var(--muted); }

/* ========================================================================
   NÚT, Ô NHẬP, NHÃN TRẠNG THÁI
   ==================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-4); border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--bg); color: var(--text);
  font: 600 var(--t-md)/1.4 inherit; text-decoration: none; cursor: pointer;
  white-space: nowrap;
}
.btn:hover { background: var(--soft); }
.btn.primary { background: var(--brand); border-color: var(--brand); color: var(--brand-text); }
.btn.primary:hover { filter: brightness(1.06); }
.btn.big { padding: var(--s-3) var(--s-5); font-size: var(--t-lg); }

/* Nút trơn trong form (Log in, Create account, Create key, Save…). Trước
   2026-09-30 không có quy tắc nào cho <button> không class, nên chúng hiện
   là nút xám mặc định của trình duyệt, cả ở chế độ tối. Mặc định là nút
   chính; .secondary / .danger / .small đổi kiểu. :where() giữ độ ưu tiên ở
   0 để mọi quy tắc riêng (menu Account, button.danger…) vẫn thắng. */
:where(form) :where(button:not(.btn)) {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: var(--s-2) var(--s-4); border-radius: var(--radius);
  border: 1px solid var(--brand); background: var(--brand); color: var(--brand-text);
  font: 600 var(--t-md)/1.4 inherit; cursor: pointer; white-space: nowrap;
}
:where(form) :where(button:not(.btn)):hover { filter: brightness(1.06); }
:where(form) :where(button:not(.btn)):disabled { opacity: .55; cursor: default; filter: none; }
:where(form) button.secondary, :where(form) button.small.secondary {
  background: var(--bg); color: var(--text); border-color: var(--line);
}
:where(form) button.secondary:hover { background: var(--soft); filter: none; }
:where(form) button.small, button.small { padding: 2px var(--s-3); font-size: var(--t-sm); }

.field { display: flex; flex-direction: column; gap: var(--s-1); }
.field label { font-size: var(--t-sm); font-weight: 600; }
.field input, .field select {
  padding: var(--s-3); font: var(--t-md)/1.4 inherit;
  color: var(--text); background: var(--bg);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.field input:focus { border-color: var(--brand); }

.search { display: flex; gap: var(--s-2); width: 100%; }
.search input { flex: 1; min-width: 0; padding: var(--s-3) var(--s-4);
                font: var(--t-md)/1.4 inherit; color: var(--text); background: var(--bg);
                border: 1px solid var(--line); border-radius: var(--radius); }

/* Badge LUÔN là trạng thái, không bao giờ mang màu thương hiệu. */
.badge {
  display: inline-block; padding: 1px var(--s-2); border-radius: 999px;
  font-size: var(--t-xs); font-weight: 600;
}
.badge.ok { background: var(--ok-bg); color: var(--ok); }
.badge.warn { background: var(--warn-bg); color: var(--warn); }
.badge.bad { background: var(--bad-bg); color: var(--bad); }
.badge.info { background: var(--info-bg); color: var(--accent); }

.muted { color: var(--muted); }
.mono { font-family: var(--mono); }

/* ========================================================================
   CHÂN TRANG — một DẢI, không phải một màn hình
   ------------------------------------------------------------------------
   Bản trước để chỗ điều hướng chéo này thành một card riêng cao bằng màn
   hình. Đo được: nó dùng 22% chỗ của một màn, trên mọi trang của cả bốn
   site. Cùng chừng ấy link nằm gọn trong một dải cao ~56px.

   Nó vẫn là chỗ điều hướng giữa các sản phẩm sống trên điện thoại, nơi
   thanh shell không đủ rộng để chứa link.
   ==================================================================== */

.sitefoot {
  margin-top: var(--s-5);
  border-top: 1px solid var(--line);
  background: var(--soft);
}
.sitefoot > div {
  max-width: var(--measure); margin: 0 auto;
  padding: var(--s-4);
  display: flex; align-items: center; gap: var(--s-3) var(--s-5); flex-wrap: wrap;
  font-size: var(--t-sm); color: var(--muted);
}
.sitefoot nav { display: flex; gap: var(--s-4); flex-wrap: wrap; }
.sitefoot a { color: var(--text); text-decoration: none; }
.sitefoot a:hover { text-decoration: underline; }
.sitefoot .note { margin-left: auto; }

/* .go vẫn dùng cho lưới lựa chọn giữa trang (trang tìm kiếm chẳng hạn). */
.go { display: grid; gap: var(--s-3); grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.go a {
  display: flex; flex-direction: column; gap: var(--s-1);
  padding: var(--s-3) var(--s-4); border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--soft); color: var(--text); text-decoration: none;
}
.go a:hover { border-color: var(--brand); }
.go a b { font-size: var(--t-md); }
.go a span { font-size: var(--t-sm); color: var(--muted); }

.foot { font-size: var(--t-sm); color: var(--muted);
        display: flex; gap: var(--s-3); flex-wrap: wrap; align-items: center; }

@media (max-width: 560px) { .sitefoot .note { margin-left: 0; } }

/* ========================================================================
   MÀN HÌNH NHỎ
   ==================================================================== */

@media (max-width: 720px) {
  /* Ba nút sản phẩm vẫn ở trên header; Pricing · Docs · API · Account gập
     vào nút ☰ (.navm). */
  .shell nav.side, .shell .acctdesk { display: none; }
  .shell { gap: var(--s-1); }
  .shell .mark img { width: 30px; height: 30px; }
  .shell nav.prods { gap: 0; margin-left: 0; }
  .shell nav.prods a { padding: 5px 9px; font-size: var(--t-sm, 14px); }
  .card { padding: var(--s-5) var(--s-4); gap: var(--s-4); }
  .chainpick .list { grid-template-columns: repeat(2, minmax(130px, 1fr)); }
  /* HAI cột, không phải một. Với auto-fit/minmax(190px) thì một màn 390px
     chỉ đủ một cột, và bảy chỉ số của Ethereum hay Monero xếp dọc làm card
     cao 1254px trong một màn 788px (đo 2026-09-28). */
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2); }
  .stat { padding: var(--s-3); }
  .stat .sub { min-height: 0; }
}

@media (max-width: 420px) {
  .chainpick .list { grid-template-columns: 1fr; }
}

/* Cột đánh dấu .drop nhường chỗ trước khi bảng tràn ngang. Ngưỡng là 560px
   chứ không phải 420px: một bảng năm cột đã rộng 503px trong một màn 390px,
   và nó bắt đầu chật từ rất trước 420. */
@media (max-width: 560px) { .rows .drop, .rows th.drop, .rows td.drop { display: none; } }
/* Tiêu đề cột nowrap là thứ làm bảng tràn trên điện thoại: "Đơn vị 7 ngày"
   rộng 126px trong khi số bên dưới chỉ cần 60px (đo 2026-09-30 ở 390px,
   /admin/accounts tràn 90px, /usage 24px). Trên màn hẹp cho tiêu đề xuống
   dòng và thu khoảng đệm giữa các ô. */
@media (max-width: 560px) {
  .rows th { white-space: normal; }
  .rows td, .rows th { padding-inline: var(--s-2); }
  .rows td:first-child, .rows th:first-child { padding-left: 0; }
  .rows td:last-child, .rows th:last-child { padding-right: 0; }
}

@media (max-height: 480px) {
  .card { padding-block: var(--s-4); gap: var(--s-3); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* In ra giấy: shell dính và điều hướng không còn nghĩa gì. */
@media print {
  .masthead, .shell, .cue, .go { display: none; }
  .card { page-break-inside: avoid; }
}

/* --- Hai kiểu vỡ trên màn hẹp, đo trên trang tài liệu API 2026-09-28 ---- */

/* Một <code> chứa URL hoặc khoá dài 589px trong một màn 390px. Inline code
   phải được phép xuống dòng ở bất kỳ đâu — nó là chữ, không phải khối mã. */
code { overflow-wrap: anywhere; }
/* …trừ trong ô bảng: ở đó "anywhere" cho cột co tới một ký tự nên mã lỗi
   gãy giữa chừng ("MISSING_API_KE / Y", "accoun / t" — 2026-09-30). Trong
   bảng, mã chỉ xuống dòng ở dấu phẩy giữa các mã; cột rộng theo mã dài nhất. */
.rows code { overflow-wrap: normal; word-break: normal; }
@media (max-width: 360px) { .rows code { font-size: var(--t-xs); padding-inline: 2px; } }

/* .rows.stack — bảng SO SÁNH (ô là câu văn, không phải số) xếp chồng trên
   màn hẹp. Bảng bốn cột văn xuôi có bề rộng tối thiểu 537px và không có
   cách nào nhét vừa 358px; xếp chồng giữ được đủ chữ. Bảng dữ liệu KHÔNG
   dùng class này: hash và số đọc theo cột mới có nghĩa. */
@media (max-width: 560px) {
  /* `th` cũng phải ẩn, không chỉ `thead`. Một số bảng viết hàng tiêu đề
     thẳng trong tbody (không có thẻ thead), nên quy tắc chỉ nhắm thead
     không chạm tới chúng và hàng tiêu đề nowrap giữ bảng rộng 534px trong
     một màn 390px — đúng chỗ trang API tràn ngang. Nhãn của từng ô đã nằm
     ở data-k rồi. */
  .rows.stack thead, .rows.stack th { display: none; }
  .rows.stack tr { display: block; padding: var(--s-3) 0; border-bottom: 1px solid var(--line); }
  .rows.stack td { display: block; border: 0; padding: var(--s-1) 0; }
  .rows.stack td.num { text-align: left; }
  .rows.stack td::before { content: attr(data-k); display: block;
    font-size: var(--t-xs); color: var(--muted);
    text-transform: uppercase; letter-spacing: .06em; }
}

/* --- Flash ---------------------------------------------------------------
   Thông báo một lần: dính ngay dưới shell, không chiếm chỗ của card nào.
   Trong một chồng card snap, một khối chen giữa hai card sẽ tạo ra một
   điểm dừng không tương ứng với card nào. */
.flashbar {
  position: sticky; top: calc(var(--shell-h) + var(--bar-sp) + var(--frame-gap)); z-index: 40;
  max-width: var(--measure); margin: var(--frame-gap) auto 0; border-radius: var(--radius);
  padding: var(--s-3) var(--s-4); font-size: var(--t-md);
  border-bottom: 1px solid var(--line);
}
.flashbar.ok { background: var(--ok-bg); color: var(--ok); }
.flashbar.error, .flashbar.bad { background: var(--bad-bg); color: var(--bad); }
.flashbar.warn { background: var(--warn-bg); color: var(--warn); }
.flashbar.info { background: var(--info-bg); color: var(--accent); }

/* .card.center — card chứa MỘT khối hẹp: biểu mẫu đăng nhập, một thông
   báo. Không có nó, biểu mẫu đăng nhập dán sát mép trái trong khi nửa phải
   màn hình bỏ trống — đo trên account.olenza.io/login 2026-09-28. */
.card.center { align-items: center; text-align: left; }
.card.center > * { width: 100%; max-width: 420px; }
.card.center > .cue { max-width: none; }

/* ========================================================================
   SIẾT KHUNG THEO CHIỀU CAO MÀN HÌNH
   ------------------------------------------------------------------------
   Khung là một màn hình, nên đệm và khoảng cách phải co theo màn hình chứ
   không cố định. Đo 2026-09-28 trên /btc: với đệm cố định 24px, khung vượt
   một màn 17px ở 1440x900 và 53px ở 1366x768 — vượt ít nhưng đủ để trang
   thành 1,07 màn, tức vẫn phải cuộn để thấy nốt mép dưới của khung.
   ==================================================================== */

@media (max-height: 900px) {
  .card { padding: var(--s-4) var(--s-5); gap: var(--s-3); }
  .shell { padding: 0 var(--s-5); }
}
@media (max-height: 800px) {
  .card { padding: var(--s-3) var(--s-4); gap: var(--s-2); border-radius: 10px; }
  .shell { padding: 0 var(--s-4); border-radius: 10px; }
  :root { --frame-gap: 10px; }
}

/* Màn hẹp: bảng ngắn lại. Ở đây chỉ số xếp hai cột nên chúng cao gấp đôi
   desktop, và phần còn lại cho bảng ít đi đúng chừng ấy. */
@media (max-width: 560px) {
  .rows[data-fit] tbody tr:nth-child(n+7) { display: none; }
  .card { padding: var(--s-4); }
  :root { --frame-gap: 8px; }
}

/* Màn hẹp VÀ thấp cùng lúc (điện thoại 844px trở xuống): bớt thêm một dòng.
   Hai truy vấn riêng lẻ không bắt được trường hợp này — 390x844 vừa hẹp
   (chỉ số xếp hai cột, cao gấp đôi) vừa thấp, và khung vượt 53px. */
@media (max-width: 560px) and (max-height: 860px) {
  .rows[data-fit] tbody tr:nth-child(n+6) { display: none; }
}
@media (max-width: 560px) and (max-height: 760px) {
  .rows[data-fit] tbody tr:nth-child(n+5) { display: none; }
}

/* ========================================================================
   BẢNG NẰM CHUNG KHUNG VỚI MỘT BẢNG CHI TIẾT
   ------------------------------------------------------------------------
   Trang block và trang giao dịch có .kv (mười mấy dòng khoá–giá trị) rồi
   mới tới danh sách giao dịch. Mức ẩn dòng chung được đo trên trang chain,
   nơi phía trên bảng chỉ có chỉ số — ở đây phía trên còn cả .kv, nên cùng
   số dòng ấy làm khung vượt một màn (đo 2026-09-28: 1013px trong một màn
   812px).

   Bộ chọn anh em `~` bắt đúng trường hợp đó: chỉ những bảng đứng SAU một
   .kv trong cùng khung mới bị siết thêm.
   ==================================================================== */

.kv ~ .fill .rows[data-fit] tbody tr:nth-child(n+9) { display: none; }
@media (max-height: 1000px) { .kv ~ .fill .rows[data-fit] tbody tr:nth-child(n+7) { display: none; } }
@media (max-height:  900px) { .kv ~ .fill .rows[data-fit] tbody tr:nth-child(n+5) { display: none; } }
@media (max-height:  800px) { .kv ~ .fill .rows[data-fit] tbody tr:nth-child(n+4) { display: none; } }
@media (max-height:  700px) { .kv ~ .fill .rows[data-fit] tbody tr:nth-child(n+3) { display: none; } }
@media (max-width:  560px)  { .kv ~ .fill .rows[data-fit] tbody tr:nth-child(n+4) { display: none; } }

/* .kv gọn lại: nó là bảng tra cứu, không phải chỗ để thở. */
.kv > div { padding: var(--s-2) var(--s-3); }
@media (max-height: 900px) { .kv > div { padding: 5px var(--s-3); } }

/* .card.multi — khung chứa NHIỀU bảng ngắn cạnh nhau. Mỗi bảng dùng mức
   ẩn dòng chung thì cộng lại vẫn vượt khung, nên ở đây siết theo số bảng
   chứ không theo một bảng. */
.card.multi .rows[data-fit] tbody tr:nth-child(n+6) { display: none; }
@media (max-height: 900px) { .card.multi .rows[data-fit] tbody tr:nth-child(n+5) { display: none; } }
@media (max-height: 800px) { .card.multi .rows[data-fit] tbody tr:nth-child(n+4) { display: none; } }
@media (max-width: 560px)  { .card.multi .rows[data-fit] tbody tr:nth-child(n+4) { display: none; } }

/* ========================================================================
   .card.auto — khung CO THEO NỘI DUNG
   ------------------------------------------------------------------------
   Dành cho trang vốn ít nội dung: đăng nhập, đăng ký, quên mật khẩu, một
   thông báo. Ép chúng chiếm trọn một màn thì khung chỉ đầy 43 phần trăm và
   trông như lỗi bố cục; co lại thì nó đọc ra là một hộp thoại, tức là có
   chủ ý. Khung vẫn nằm giữa màn hình theo chiều dọc.
   ==================================================================== */

.deck:has(> .card.auto:only-child) {
  min-height: calc(100dvh - var(--shell-h) - var(--bar-sp) - var(--frame-gap));
  display: flex; align-items: center; justify-content: center;
}
.card.auto { min-height: 0; }
.card.auto.center { max-width: 480px; }
.card.auto.center > * { max-width: none; }

/* Menu cho màn hẹp: cùng bộ link của header, gập lại. Trên màn rộng các
   link đã nằm thẳng trên header nên menu này ẩn. Nó mượn nguyên kiểu của
   điều khiển Account (viên thuốc + bảng thả xuống) để hai thứ trông là một
   họ. */
.navm { display: none; }
.navm > summary { padding: var(--s-1) var(--s-2); }
.navm > summary::after { display: none; }
.navm .bars, .navm .bars::before, .navm .bars::after {
  display: block; width: 16px; height: 2px; border-radius: 1px; background: currentColor; content: "";
}
.navm .bars { position: relative; margin: 7px 2px; }
.navm .bars::before { position: absolute; top: -5px; }
.navm .bars::after { position: absolute; top: 5px; }
@media (max-width: 720px) {
  .navm { display: block; margin-left: auto; }
  .navm .menu a.here { font-weight: 600; }
}
/* Rất hẹp (dưới 360px): ba nút sản phẩm thu thêm để không phải cuộn ngang. */
@media (max-width: 360px) {
  .shell nav.prods a { padding: 4px 6px; font-size: 13px; }
  .shell .mark img { width: 26px; height: 26px; }
}

/* ========================================================================
   THANH TRANG — chọn chain bên trái, tab chuyển khung bên phải
   ------------------------------------------------------------------------
   Nằm ngay dưới header, trong cùng vùng dính, và cùng họ với nó: cùng bề
   ngang, viền, bo góc, nền. Hai việc:

   - Bên trái: bộ chọn chain và ba trang của một chain (Blocks / Charts /
     Mempool). Trước đây cụm này nằm TRONG khung, ở góc phải đầu khung —
     tức là mỗi khung một chỗ khác, và khung thứ hai trở đi thì không có.
   - Bên phải: một tab cho mỗi khung của trang. Cuộn vẫn chuyển khung như
     cũ; tab là cách thứ hai, và nó cũng cho biết trang có bao nhiêu khung
     và đang ở khung nào.
   ==================================================================== */

:root:has(.pagebar) { --bar-h: 48px; --bar-sp: calc(var(--bar-h) + var(--frame-gap)); }

.pagebar {
  height: var(--bar-h);
  max-width: var(--measure); margin: var(--frame-gap) auto 0;
  display: flex; align-items: center; gap: var(--s-3);
  padding: 0 var(--s-3) 0 var(--s-4);
  background: var(--bg);
  border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 1px 2px rgb(0 0 0 / .05), 0 8px 24px -14px rgb(0 0 0 / .14);
}
.pb-left { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
.pagebar .chainpick > summary { padding: var(--s-1) var(--s-3); }

/* Ba trang của một chain: một nhóm nút liền nhau. Trang đang xem là chữ,
   không phải link — một link dẫn tới chỗ đang đứng là một link thừa. */
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.seg > a, .seg > span {
  padding: var(--s-1) var(--s-3); font-size: var(--t-sm);
  color: var(--muted); text-decoration: none; white-space: nowrap;
}
.seg > * + * { border-left: 1px solid var(--line); }
.seg > a:hover { color: var(--text); background: var(--soft); }
.seg > .here { color: var(--text); font-weight: 600; background: var(--soft); }

.pb-tabs {
  margin-left: auto; display: flex; gap: var(--s-1);
  overflow-x: auto; scrollbar-width: none; min-width: 0;
}
.pb-tabs::-webkit-scrollbar { display: none; }
.pb-tabs a {
  padding: var(--s-1) var(--s-3); border-radius: 999px;
  font-size: var(--t-sm); color: var(--muted); text-decoration: none;
  white-space: nowrap; max-width: 22ch; overflow: hidden; text-overflow: ellipsis;
  /* Không co: thanh tab cuộn ngang được, còn tab co lại thì trên điện thoại
     chỉ còn "S… Cha… E…" (đo 2026-09-30, trang Explorer API). */
  flex: none;
}
.pb-tabs a:hover { color: var(--text); background: var(--soft); }
.pb-tabs a.on { color: var(--text); font-weight: 600; background: var(--soft); box-shadow: inset 0 0 0 1px var(--line); }

/* Bộ nút NHÓM sản phẩm (vd Node | Explorer) ở đầu pagebar — một segmented
   control views.js dựng; chọn nhóm nào thì chỉ khung của nhóm ấy hiện. */
.pb-groups { display: inline-flex; flex: none; border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; }
.pb-groups > a { padding: var(--s-1) var(--s-3); font-size: var(--t-sm);
  color: var(--muted); text-decoration: none; white-space: nowrap; }
.pb-groups > a + a { border-left: 1px solid var(--line); }
.pb-groups > a:hover { color: var(--text); background: var(--soft); }
.pb-groups > a.on { color: var(--text); font-weight: 600; background: var(--soft); }
/* Khung bị ẩn khi đổi nhóm: .card là display:flex nên phải ép none tường minh. */
.deck > .card[hidden] { display: none; }

/* Màn hẹp: nếu có cả cụm bên trái (chain / nhóm) lẫn tab thì thành hai hàng,
   và chiều cao thanh — thứ mà phép tính chiều cao khung dựa vào — đổi theo. */
@media (max-width: 720px) {
  .pagebar { padding: 0 var(--s-2); gap: var(--s-2); }
  .seg > a, .seg > span, .pb-groups > a { padding: var(--s-1) var(--s-2); }
  :root:has(.pagebar > .pb-left):has(.pagebar > .pb-tabs),
  :root:has(.pagebar > .pb-groups):has(.pagebar > .pb-tabs) { --bar-h: 88px; }
  .pagebar:has(> .pb-left):has(> .pb-tabs),
  .pagebar:has(> .pb-groups):has(> .pb-tabs) {
    flex-wrap: wrap; align-content: center; row-gap: var(--s-2);
  }
  .pagebar:has(> .pb-left) > .pb-tabs,
  .pagebar:has(> .pb-groups) > .pb-tabs { margin-left: 0; width: 100%; }
}

/* ========================================================================
   BẢNG LẤP ĐẦY KHUNG
   ------------------------------------------------------------------------
   Bảng có phân trang đánh dấu data-fit. Các mức CSS ở trên là phương án dự
   phòng khi không có JavaScript. Khi views.js chạy, nó ĐO chỗ còn lại của
   khung và hiện đúng số dòng lấp đủ chỗ đó (thêm class .fitted để tắt các
   mức CSS). Đo thay vì đoán: các mức CSS luôn hoặc thừa một mảng trắng,
   hoặc tràn quá một màn, tuỳ trang có gì đứng trên bảng.
   ==================================================================== */
.card .rows.fitted[data-fit] tbody tr:not([hidden]) { display: table-row; }
.rows tbody tr[hidden] { display: none; }

/* Biểu đồ ăn hết chỗ còn lại của khung. charts.js đo chiều cao phần tử
   này để vẽ, thay vì một chiều cao cố định. */
.card > .chartbox { flex: 1; min-height: 180px; }

/* Trong lúc views.js đưa trang tới khung vừa bấm, snap tạm tắt. Snap bắt
   buộc kéo trang về điểm dính gần nhất sau MỖI lần cuộn bằng lệnh, nên một
   chuyển động gồm nhiều bước nhỏ bị kéo ngược ngay bước đầu — đo được: trang
   trượt tới y=322 rồi quay về 0. views.js dừng đúng một điểm dính rồi mới
   bỏ class này, nên bật snap lại không làm trang xê dịch. */
html.jumping { scroll-snap-type: none; scroll-behavior: auto; }

/* ========================================================================
   MÀN RẤT HẸP (≤ 380px) — rà 2026-09-30 ở 320/360/390
   ==================================================================== */
@media (max-width: 380px) {
  /* Nút chọn chain chỉ còn biểu tượng: tên chain đẩy "Mempool" ra khỏi mép
     màn ở 320px. Tên vẫn có trong danh sách khi mở ra. */
  .pagebar .chainpick > summary .nm { display: none; }
  /* Bảng: lề ô hẹp lại và số dài được xuống dòng, thay vì đẩy bảng rộng
     hơn màn (bảng giao dịch Ethereum rộng 363px trong màn 320px). */
  .rows th, .rows td { padding-left: 4px; padding-right: 4px; }
  .rows td.num { white-space: normal; overflow-wrap: anywhere; }
}

/* --- Trang trạng thái công khai (2026-10-01) -------------------------------- */
.statushead { display:flex; align-items:center; gap:var(--s-2); padding:var(--s-3) var(--s-4);
  border:1px solid var(--line); border-radius:var(--radius); margin-bottom:var(--s-3); font-size:var(--t-lg); }
.statushead .dot { width:12px; height:12px; border-radius:50%; flex:none; }
.statushead.ok { background:var(--ok-bg); } .statushead.ok .dot { background:var(--ok); }
.statushead.bad { background:var(--bad-bg); } .statushead.bad .dot { background:var(--bad); }
.histrip { display:flex; gap:2px; align-items:stretch; height:34px; margin:var(--s-2) 0 2px; }
.histrip .hbar { flex:1; min-width:2px; border-radius:2px; background:var(--line); }
.histrip .hbar.ok { background:var(--ok); } .histrip .hbar.warn { background:var(--warn); }
.histrip .hbar.bad { background:var(--bad); } .histrip .hbar.none { background:var(--line); opacity:.5; }
.histrip-axis { display:flex; justify-content:space-between; margin-bottom:var(--s-3); }
.t-ok { color:var(--ok); } .t-warn { color:var(--warn); } .t-bad { color:var(--bad); } .t-none { color:var(--muted); }

/* Chân trang tối giản cho olenza.io. */
.sitefoot { max-width:var(--measure); margin:var(--s-5) auto 0; padding:var(--s-4) var(--s-4) var(--s-5);
  display:flex; flex-wrap:wrap; gap:var(--s-4); justify-content:center; border-top:1px solid var(--line); font-size:var(--t-sm); }
.sitefoot a { color:var(--muted); text-decoration:none; } .sitefoot a:hover { color:var(--brand); }

/* Thanh "block mới — tải lại" của cập nhật trực tiếp (2026-10-01). */
.livebar { position:fixed; left:50%; transform:translateX(-50%); bottom:calc(var(--s-4) + env(safe-area-inset-bottom,0px)); z-index:60;
  background:var(--brand); color:var(--brand-text); text-decoration:none; font-size:var(--t-sm); font-weight:600;
  padding:var(--s-2) var(--s-4); border-radius:999px; box-shadow:0 6px 20px -6px rgb(0 0 0 / .4); }
.livebar:hover { filter:brightness(1.06); }

/* Nút Watch + danh sách theo dõi (2026-10-01). */
.watchslot { display:inline-flex; align-items:center; gap:var(--s-2); margin-left:var(--s-2); }
.watchbtn { font:600 var(--t-sm)/1 var(--sans); padding:4px 10px; border-radius:999px; cursor:pointer;
  border:1px solid var(--line); background:var(--bg); color:var(--muted); }
.watchbtn:hover { border-color:var(--brand); color:var(--brand); }
.watchbtn.on { border-color:var(--brand); color:var(--brand); background:color-mix(in srgb, var(--brand) 10%, transparent); }
.watchlink { color:var(--link); text-decoration:none; }
