/* ===========================================================================
   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. CUỘN BÌNH THƯỜNG. Mỗi trang là một chồng card; card cao theo nội dung
      của nó, trang cuộn tự do. KHÔNG có thanh cuộn bên trong card — bảng dài
      thì phân trang theo trang của máy chủ (25 dòng…), không cắt theo màn.
      (Bố cục snap "một card = một màn" đã bỏ 2026-10-05 theo lời chủ: trang
      ít nội dung vẫn bị kéo thành nguyên một màn, và snap giật khi 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 {
  /* Cuộn bình thường (không snap, từ 2026-10-05). scroll-padding-top để
     link neo (#mục, tab trên .pagebar) không dừng khuất sau header dính. */
  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 phần của trang, cao theo nội dung
   ------------------------------------------------------------------------
   Không có chiều cao tối thiểu theo màn hình: card ngắn thì ngắn, card dài
   thì trang cuộn qua nó. Trước 2026-10-05 card cao tối thiểu một màn và
   trang snap từng card, nên một card ba dòng vẫn chiếm cả màn trống.
   ==================================================================== */

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

/* .card là KHUNG TRANH: có viền, có mép, cao theo nội dung. */
.card {
  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 / .fill: còn từ bố cục snap; card nay cao theo nội dung nên chúng
   không còn kéo giãn gì. Giữ để template không phải sửa hàng loạt. */
.card.top { justify-content: flex-start; }
.card > .fill { display: flex; flex-direction: column; gap: var(--s-3); }

.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 — hiện đủ mọi dòng máy chủ gửi; dữ liệu dài phân trang ở máy chủ
   ==================================================================== */

.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; }

.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 (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.
   */
.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; }

/* Màn hẹp: đệm card và mép quanh khung nhỏ lại. */
@media (max-width: 560px) {
  .card { padding: var(--s-4); }
  :root { --frame-gap: 8px; }
}

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

/* ========================================================================
   .card.auto — hộp thoại hẹp (đăng nhập, đăng ký, một thông báo)
   ------------------------------------------------------------------------
   Card nào cũng cao theo nội dung; .auto chỉ còn nghĩa "hẹp, nằm giữa theo
   chiều ngang" và cách header một khoảng vừa phải — không căn giữa theo
   chiều cao màn nữa (đó là một mảng trống lớn trên màn cao).
   ==================================================================== */

.deck:has(> .card.auto:only-child) { padding-top: var(--s-7); }
.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 (dùng cho scroll-padding-top) đổ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%; }
}


/* charts.js đo chiều cao phần tử này để vẽ. */
.card > .chartbox { min-height: 180px; }


/* ========================================================================
   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; }
