@import url('https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Roboto:wght@400;500;700&display=swap');@import url('/css/enhancements.css');
:root{--ink:#101111;--paper:#f1eee8;--muted:#9d9b94;--line:#303130;--red:#ee4b3e;--green:#95bd9c;--soft:#171918;--max:1240px;--sans:'Roboto',-apple-system,BlinkMacSystemFont,'Segoe UI',Arial,sans-serif;--serif:var(--sans);--mono:'DM Mono',monospace}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:var(--ink);color:var(--paper);font-family:var(--sans);line-height:1.65}a{color:inherit;text-decoration:none}a:hover{color:var(--red)}::selection{background:var(--red);color:var(--ink)}body:before{content:'';position:fixed;inset:0;pointer-events:none;opacity:.035;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.35'/%3E%3C/svg%3E");z-index:5}.progress{position:fixed;top:0;left:0;height:3px;background:var(--red);width:0;z-index:20}.wrap{width:min(calc(100% - 48px),var(--max));margin:auto}.site-header{border-bottom:1px solid var(--line);position:relative;z-index:10;background:rgba(16,17,17,.92);backdrop-filter:blur(12px)}.header-inner{height:84px;display:flex;align-items:center;justify-content:space-between;gap:24px}.brand{display:flex;align-items:center;gap:12px;font-weight:600;letter-spacing:-.03em}.mark{width:30px;height:30px;border:1px solid var(--red);display:grid;place-items:center;color:var(--red);font-family:var(--mono);font-size:11px}.brand small{font-family:var(--mono);font-size:10px;color:var(--muted);display:block;font-weight:400;letter-spacing:.06em}.nav{display:flex;gap:26px;align-items:center;font-size:13px}.nav a{color:#c9c7c0}.nav a:hover{color:var(--red)}.menu-btn{display:none;background:none;border:1px solid var(--line);color:var(--paper);padding:8px 11px;font-family:var(--mono)}.eyebrow{font-family:var(--mono);font-size:11px;color:var(--red);letter-spacing:.14em;text-transform:uppercase}.hero{padding:110px 0 120px;border-bottom:1px solid var(--line);position:relative;overflow:hidden}.hero:after{content:'01';position:absolute;right:0;bottom:18px;color:#252725;font:500 clamp(100px,18vw,260px)/1 var(--mono);letter-spacing:-.12em}.hero-grid{display:grid;grid-template-columns:1.15fr .85fr;gap:80px;align-items:end}.hero h1{font:500 clamp(58px,8vw,112px)/.9 var(--serif);letter-spacing:-.065em;margin:24px 0 34px;max-width:850px}.hero h1 em{color:var(--red);font-style:normal}.hero-copy{max-width:410px;color:#b1afa8;font-size:16px}.status{font:11px var(--mono);color:var(--green);margin-top:34px}.status i{display:inline-block;width:7px;height:7px;background:var(--green);border-radius:50%;margin-right:8px}.section{padding:76px 0}.section-head{display:flex;justify-content:space-between;align-items:baseline;border-top:1px solid var(--line);padding-top:16px;margin-bottom:32px}.section-head h2{font:500 42px/1 var(--serif);letter-spacing:-.04em;margin:0}.section-head a,.link-arrow{font:11px var(--mono);color:var(--red);text-transform:uppercase;letter-spacing:.08em}.feature{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);border:1px solid var(--line)}.feature-visual{min-height:350px;background:linear-gradient(135deg,#272a28,#151716 65%);padding:24px;display:flex;justify-content:space-between;flex-direction:column}.visual-label{font:11px var(--mono);color:var(--green)}.visual-number{font:clamp(90px,15vw,190px)/.8 var(--serif);color:#353a35;letter-spacing:-.1em}.feature-body{background:var(--soft);padding:46px}.feature-body h3{font:500 clamp(30px,4vw,55px)/1.02 var(--serif);letter-spacing:-.045em;margin:16px 0}.meta{font:11px var(--mono);color:var(--muted);text-transform:uppercase;letter-spacing:.06em}.meta span+span:before{content:' / ';color:var(--line);padding:0 8px}.excerpt{color:#aaa9a2;max-width:520px}.post-list{display:grid;grid-template-columns:repeat(3,1fr);gap:28px}.post-card{border-top:1px solid var(--line);padding-top:18px}.post-card h3{font:500 29px/1.08 var(--serif);letter-spacing:-.035em;margin:15px 0 12px}.post-card p{color:#989790;font-size:14px}.topic-nav{display:flex;flex-wrap:wrap;gap:10px}.topic-nav a{border:1px solid var(--line);padding:8px 13px;font:11px var(--mono);color:#bcbab2}.topic-nav a:hover{border-color:var(--red);color:var(--red)}.page-intro{padding:84px 0 54px;border-bottom:1px solid var(--line)}.page-intro h1{font:500 clamp(52px,8vw,100px)/.9 var(--serif);letter-spacing:-.06em;margin:18px 0}.page-intro p{color:#aaa;max-width:590px}.article-shell{display:grid;grid-template-columns:minmax(0,760px) 220px;gap:80px;padding:72px 0}.article-header h1{font:500 clamp(44px,6vw,78px)/.95 var(--serif);letter-spacing:-.055em;margin:18px 0 25px}.article-header .lede{font-size:19px;color:#bbb;max-width:650px}.article-body{font-family:var(--serif);font-size:19px;color:#d0cec6}.article-body h2,.article-body h3{font-family:var(--sans);letter-spacing:-.035em;color:var(--paper);margin-top:52px}.article-body h2{font-size:28px}.article-body h3{font-size:21px}.article-body p{margin:24px 0}.article-body blockquote{border-left:2px solid var(--red);margin:34px 0;padding:5px 24px;color:#aaa;font-style:italic}.article-body code{font:14px var(--mono);color:#e9a29a;background:#25201f;padding:2px 5px}.article-body pre{background:#0b0c0c;border:1px solid #292b29;padding:20px;overflow:auto;font:13px/1.7 var(--mono);position:relative;color:#d7d7cf}.article-body pre code{padding:0;background:none;color:inherit}.copy-code{position:absolute;right:10px;top:10px;background:#202321;border:1px solid #3b3d3b;color:#aaa;font:10px var(--mono);padding:6px 8px;cursor:pointer}.article-body img{max-width:100%;height:auto;border:1px solid var(--line)}.toc{position:sticky;top:110px;height:max-content;border-left:1px solid var(--line);padding-left:20px;font:11px/1.5 var(--mono);color:#8f9089}.toc strong{display:block;color:var(--red);font-weight:400;text-transform:uppercase;letter-spacing:.08em;margin-bottom:14px}.toc a{display:block;margin:9px 0}.notice{font:12px/1.6 var(--sans);background:#1b201d;border:1px solid #344438;padding:15px 18px;color:#b9c7b9;margin:30px 0}.notice b{color:var(--green)}.archive-row{display:grid;grid-template-columns:110px 1fr 120px;gap:28px;border-top:1px solid var(--line);padding:20px 0;align-items:baseline}.archive-row .date{font:11px var(--mono);color:var(--muted)}.archive-row h2{font:500 26px var(--serif);margin:0}.archive-row .tag{font:11px var(--mono);color:var(--red)}.footer{border-top:1px solid var(--line);padding:40px 0 70px;color:#85847f;font-size:13px}.footer-inner{display:flex;justify-content:space-between;gap:30px}.footer a{color:var(--paper)}.footer-note{font:11px var(--mono);color:var(--green)}.search-box{width:100%;background:transparent;border:0;border-bottom:1px solid var(--line);padding:14px 0;color:var(--paper);font:18px var(--sans);outline:0;margin:30px 0}.search-box:focus{border-color:var(--red)}
figure{margin:2rem 0}figure img{display:block;max-width:100%;height:auto;margin:0 auto;border:1px solid var(--line)}figcaption{margin-top:.65rem;color:var(--muted);font-family:var(--mono);font-size:.78rem;line-height:1.5;text-align:center}@media(max-width:800px){.wrap{width:min(calc(100% - 32px),var(--max))}.header-inner{height:70px}.menu-btn{display:block}.nav{display:none;position:absolute;top:70px;left:0;right:0;padding:18px 16px 24px;background:var(--ink);border-bottom:1px solid var(--line);flex-direction:column;align-items:flex-start}.nav.open{display:flex}.hero{padding:72px 0 86px}.hero-grid,.feature{grid-template-columns:1fr;gap:35px}.hero h1{font-size:68px}.hero:after{font-size:140px}.post-list{grid-template-columns:1fr}.section{padding:56px 0}.feature-body{padding:28px}.article-shell{grid-template-columns:1fr;padding:48px 0}.toc{position:relative;top:auto;order:-1}.archive-row{grid-template-columns:75px 1fr}.archive-row .tag{display:none}.footer-inner{flex-direction:column}}

/* ============================================================
   RESPONSIVE FIXES — loaded last so it overrides the rules above
   1. grid blowout  2. code blocks  3. tables  4. long tokens
   5. tablet breakpoint  6. phone breakpoint  7. tap targets
   ============================================================ */

/* --- 1. Stop wide children from blowing out the grid column --- */
.article-shell{grid-template-columns:minmax(0,760px) minmax(0,220px)}
.article-shell>article{min-width:0}

/* --- 2. Code blocks: figure.highlight is the real box, table scrolls inside --- */
.article-body figure.highlight{position:relative;margin:26px 0;max-width:100%;background:#0b0c0c;border:1px solid #292b29;overflow:hidden}
.article-body figure.highlight table{display:block;width:100%;max-width:100%;margin:0;overflow-x:auto;border-collapse:collapse;-webkit-overflow-scrolling:touch}
.article-body figure.highlight td{padding:0;border:0;vertical-align:top}
.article-body figure.highlight td.gutter{width:1%;white-space:nowrap;text-align:right;background:#0f100f;border-right:1px solid #232523;user-select:none;-webkit-user-select:none}
.article-body figure.highlight td.gutter pre{padding:16px 10px;color:#4d504d}
.article-body figure.highlight td.code{width:100%}
.article-body figure.highlight pre{margin:0;padding:16px 18px;border:0;background:none;overflow:visible}
.article-body figure.highlight>.copy-code{z-index:3;right:8px;top:8px}
.article-body figure.highlight .line{white-space:pre}

/* --- 3. Markdown tables: styled + horizontally scrollable --- */
.article-body>table{display:block;width:100%;max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;border-collapse:collapse;margin:28px 0;font-family:var(--sans);font-size:14px;line-height:1.55}
.article-body>table th,.article-body>table td{border:1px solid var(--line);padding:10px 13px;text-align:left;vertical-align:top}
.article-body>table th{background:#191b1a;color:var(--paper);font:600 11px/1.4 var(--mono);text-transform:uppercase;letter-spacing:.07em;white-space:nowrap}
.article-body>table td{color:#c2c0b8}
.article-body>table tbody tr:nth-child(even){background:rgba(255,255,255,.022)}
.article-body>table code{font-size:12.5px}

/* --- 4. Long tokens (CVSS vectors, URLs, paths) must not overflow --- */
.article-body{overflow-wrap:break-word}
.article-body a,.article-body code,.toc a{overflow-wrap:anywhere}
.article-body>table td,.article-body>table th{overflow-wrap:break-word}
.meta{overflow-wrap:anywhere}
.meta span:before{content:' / ';color:var(--line);padding:0 8px}
.meta span+span:before{content:' / '}

/* --- 5. Tablet / small laptop: stack the TOC instead of squeezing the column --- */
@media(max-width:1024px){
  .article-shell{grid-template-columns:minmax(0,1fr);gap:0;padding:52px 0}
  .toc{position:relative;top:auto;order:-1;max-width:100%;border-left:0;border-top:1px solid var(--line);padding:16px 0 0;margin-bottom:34px}
  .toc ol{padding-left:18px}
  .article-header .lede{max-width:none}
}

/* --- 6. Phones --- */
@media(max-width:600px){
  .wrap{width:calc(100% - 28px)}
  .hero{padding:56px 0 64px}
  .hero h1{font-size:clamp(40px,11.5vw,62px)}
  .hero:after{font-size:104px;bottom:8px}
  .hero-copy{font-size:15px}
  .section{padding:44px 0}
  .section-head{flex-direction:column;align-items:flex-start;gap:6px}
  .section-head h2{font-size:30px}
  .page-intro{padding:56px 0 38px}
  .page-intro h1{font-size:clamp(34px,11vw,54px)}
  .article-shell{padding:36px 0}
  .article-header h1{font-size:clamp(28px,8.6vw,42px);margin:14px 0 18px}
  .article-header .lede{font-size:16.5px}
  .article-body{font-size:17px}
  .article-body h2{font-size:23px;margin-top:38px}
  .article-body h3{font-size:19px;margin-top:32px}
  .article-body blockquote{margin:26px 0;padding:4px 16px}
  .article-body figure.highlight pre{font-size:12px;padding:13px 14px}
  .article-body figure.highlight td.gutter{display:none}
  .article-body>table{font-size:13px}
  .article-body>table th,.article-body>table td{padding:8px 10px}
  .post-card h3{font-size:24px}
  .feature-body{padding:22px}
  .feature-visual{min-height:200px}
  .archive-row{grid-template-columns:1fr;gap:4px;padding:16px 0}
  .footer{padding:32px 0 48px}
  .search-control input{padding:14px}
  .search-result h3{font-size:1.35rem}
  .lightbox-close{position:fixed;right:12px;top:12px}
}

@media(max-width:380px){
  .wrap{width:calc(100% - 20px)}
  .brand small{display:none}
  .article-body{font-size:16px}
  .article-body figure.highlight pre{font-size:11.5px}
}

/* --- 7. Tap targets (WCAG 2.5.8 ~24px min; aiming for 44px) --- */
@media(max-width:800px){
  .menu-btn{min-height:44px;min-width:44px}
  .nav{gap:0}
  .nav a{display:block;width:100%;padding:11px 0}
  .topic-nav a,.topic-filter{min-height:40px;display:inline-flex;align-items:center}
  .copy-code{padding:9px 11px}
}

/* --- 8. Collapsible TOC (expanded on desktop, collapsed on small screens) --- */
.toc-details>summary{list-style:none;cursor:default}
.toc-details>summary::-webkit-details-marker{display:none}
@media(max-width:1024px){
  .toc-details>summary{cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:44px}
  .toc-details>summary:after{content:'+';color:var(--red);font:400 15px var(--mono)}
  .toc-details[open]>summary:after{content:'\2013'}
  .toc-details>summary strong{margin-bottom:0}
  .toc-details[open] ol{margin-top:12px}
}

/* --- 9. Copy button: fade in on pointer devices, always visible on touch --- */
@media(hover:hover){
  .copy-code{opacity:0;transition:opacity .15s}
  figure.highlight:hover>.copy-code,pre:hover>.copy-code,.copy-code:focus-visible{opacity:1}
}

/* ============================================================
   TYPOGRAPHY — Roboto (theo gatari.dev). Đặt cuối cùng để thắng
   các rule ở trên. Roboto có x-height lớn hơn Newsreader nên cỡ
   chữ giảm xuống và tracking âm nới ra để không bị dính nét.
   ============================================================ */
body{line-height:1.7}

.hero h1{font:700 clamp(52px,7.6vw,104px)/1 var(--sans);letter-spacing:-.04em}
.page-intro h1{font:700 clamp(46px,7.4vw,92px)/1.02 var(--sans);letter-spacing:-.035em}
.article-header h1{font:700 clamp(38px,5.2vw,64px)/1.08 var(--sans);letter-spacing:-.03em}
.section-head h2{font:700 34px/1.1 var(--sans);letter-spacing:-.025em}
.feature-body h3{font:700 clamp(27px,3.4vw,44px)/1.12 var(--sans);letter-spacing:-.028em}
.post-card h3{font:500 24px/1.25 var(--sans);letter-spacing:-.02em;margin:13px 0 10px}
.archive-row h2{font:500 21px/1.3 var(--sans);letter-spacing:-.015em}
.search-result h3{font:500 1.3rem/1.3 var(--sans);letter-spacing:-.015em}
.visual-number{font:700 clamp(80px,13vw,170px)/.85 var(--sans);letter-spacing:-.05em}

.article-header .lede{font-size:18px;line-height:1.65}
.article-body{font-family:var(--sans);font-size:17px;line-height:1.8}
.article-body h2{font-size:26px;letter-spacing:-.02em}
.article-body h3{font-size:20px;letter-spacing:-.015em}
.article-body blockquote{font-style:normal;border-left-width:3px}
.article-body strong{font-weight:500;color:var(--paper)}

@media(max-width:600px){
  .hero h1{font-size:clamp(36px,10.5vw,56px)}
  .page-intro h1{font-size:clamp(32px,10vw,48px)}
  .article-header h1{font-size:clamp(26px,7.6vw,38px)}
  .section-head h2{font-size:27px}
  .feature-body h3{font-size:25px}
  .post-card h3{font-size:21px}
  .article-header .lede{font-size:16.5px}
  .article-body{font-size:16px;line-height:1.78}
  .article-body h2{font-size:21px}
  .article-body h3{font-size:18px}
}
@media(max-width:380px){
  .article-body{font-size:15.5px}
}

/* --- Hero: giữ nội dung nằm trên watermark "01" (absolute nên vốn vẽ đè) --- */
.hero-grid{position:relative;z-index:1}
.feature-visual .visual-label,.feature-visual .visual-number{position:relative}

/* ============================================================
   TOC — sửa 3 lỗi:
   a) Hexo toc() xuất <ol class="toc">, trùng class với <aside class="toc">
      nên style wrapper bị áp 2 lần (sticky lồng sticky, 2 border, thụt lề đôi)
   b) TOC cao 1200px trong khe 790px -> các mục cuối không bao giờ với tới
   c) không có trạng thái "đang đọc"
   ============================================================ */

/* a) trả <ol class="toc"> về đúng vai trò danh sách */
aside.toc ol.toc{position:static;top:auto;border-left:0;padding-left:24px;margin:0}

/* b) khung TOC tự cuộn, không còn mục nào bị cắt */
@media(min-width:1025px){
  aside.toc{max-height:calc(100vh - 132px);overflow-y:auto;overscroll-behavior:contain;padding-left:26px;padding-right:12px;scrollbar-width:thin;scrollbar-color:#3a3c3a transparent}
  aside.toc::-webkit-scrollbar{width:6px}
  aside.toc::-webkit-scrollbar-thumb{background:#3a3c3a;border-radius:3px}
  aside.toc::-webkit-scrollbar-track{background:transparent}
  .article-shell{gap:92px}
}

/* c) mục đang đọc */
aside.toc .toc-link{display:block;margin:9px 0;transition:color .15s ease}
aside.toc .toc-link:hover{color:var(--paper)}
aside.toc .toc-link.is-active{color:var(--red)}
.article-body h2,.article-body h3{scroll-margin-top:26px}

/* thêm khoảng thở cho thanh "in this post" trên mobile */
@media(max-width:1024px){
  aside.toc{padding:20px 0 0;margin-bottom:48px}
  aside.toc ol.toc{padding-left:22px}
  .toc-details[open]{padding-bottom:8px}
}

/* ============================================================
   TECHNICAL-DOCUMENT LAYER
   Ported from the adverserial.ai study, dark palette kept.
   Appended last so it overrides the base rules above.
   ============================================================ */

/* --- Tokens. Wider frame + viewport-scaled gutter, so the page
       fills a 1920 screen instead of boxing into 1240. --- */
:root{
  --max:1680px;
  --pad:clamp(20px,5vw,84px);
  --grid:rgba(241,238,232,.045);
  --rule-dim:#232524;
  --mark:14px;
}
.wrap{width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--pad)}

/* --- Reading measure. The wider frame must NOT widen prose. --- */
.article-shell{max-width:calc(1100px + var(--pad) * 2);margin-inline:auto}
.section>.article-body{max-width:68ch}
.section>.archive-row{max-width:1100px}

/* --- Crop marks: two diagonal corners, framing without boxing.
       Used on evidence (figures, the featured exhibit). --- */
.marks{position:relative}
.marks:before,.marks:after{content:'';position:absolute;width:var(--mark);height:var(--mark);pointer-events:none}
.marks:before{top:var(--inset,10px);left:var(--inset,10px);border-top:1px solid var(--red);border-left:1px solid var(--red)}
.marks:after{bottom:var(--inset,10px);right:var(--inset,10px);border-bottom:1px solid var(--red);border-right:1px solid var(--red)}

/* --- Hero: graph paper + a single red sweep. The one moving thing. --- */
.hero-paper{position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(var(--grid) 1px,transparent 1px),linear-gradient(90deg,var(--grid) 1px,transparent 1px);
  background-size:58px 58px;
  -webkit-mask-image:radial-gradient(ellipse 70% 65% at 35% 45%,#000,transparent 72%);
          mask-image:radial-gradient(ellipse 70% 65% at 35% 45%,#000,transparent 72%)}
.scanline{position:absolute;left:0;right:0;top:0;height:1px;pointer-events:none;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(238,75,62,.75) 18%,rgba(238,75,62,.95) 50%,rgba(238,75,62,.75) 82%,transparent);
  box-shadow:0 0 22px rgba(238,75,62,.45);
  animation:scan 9s cubic-bezier(.45,0,.25,1) infinite}
@keyframes scan{
  0%{transform:translateY(60px);opacity:0}
  12%{opacity:.9}
  88%{opacity:.9}
  100%{transform:translateY(440px);opacity:0}
}
.hero{padding:104px 0 112px}
.hero:after{right:var(--pad)}
.hero-grid{position:relative;z-index:2;gap:clamp(40px,6vw,110px)}
.hero h1{font-size:clamp(58px,7.4vw,132px);max-width:14ch}
.hero-copy{max-width:46ch;font-size:clamp(16px,1.05vw,18px)}

/* --- Section head carrying real data, not an empty 01/02/03. --- */
.rule-head{display:flex;justify-content:space-between;align-items:baseline;gap:24px;
  border-top:1px solid var(--line);padding-top:14px;margin-bottom:34px;
  font:11px var(--mono);letter-spacing:.1em;text-transform:uppercase}
.rule-head .lhs{color:var(--red)}
.rule-head .lhs b{color:var(--muted);font-weight:400}
.rule-head .rhs{color:var(--muted)}
.rule-head a.rhs:hover{color:var(--red)}

/* --- Homepage rhythm only. The base .section padding is shared
       by archive/category/tag/page/search, so it stays untouched. --- */
.section.home{padding:0 0 72px}
.section.home:first-of-type{padding-top:72px}
.section.home h2{font:500 clamp(32px,3.2vw,48px)/1.02 var(--serif);
  letter-spacing:-.045em;margin:0 0 38px;max-width:15ch}

/* --- Featured exhibit --- */
.feature{transition:border-color .18s}
.feature:hover{border-color:#4a3330}
.feature:hover .meta{color:var(--red)}
.feature-visual{background:linear-gradient(135deg,#232624,#141615 70%);padding:26px;gap:18px;--mark:16px}
.visual-id{position:relative;z-index:2}
.visual-id b{display:block;font:500 clamp(30px,2.9vw,52px)/.95 var(--mono);letter-spacing:-.05em;color:#e4e1d9}
.visual-id span{display:block;margin-top:10px;font:11px var(--mono);color:var(--muted);letter-spacing:.08em}

/* --- Coverage: the notebook's real shape, from build-time counts. --- */
.coverage-grid{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(40px,5vw,90px);align-items:start}
.coverage-grid>div{min-width:0}
.tally{display:flex;gap:clamp(28px,3vw,54px);flex-wrap:wrap;margin:0}
.tally div{min-width:104px}
.tally dt{font:11px var(--mono);color:var(--muted);letter-spacing:.1em;text-transform:uppercase;margin-bottom:6px}
.tally dd{margin:0;font:500 clamp(46px,5vw,76px)/.85 var(--serif);letter-spacing:-.06em}
.tally dd small{display:block;margin-top:9px;font:11px var(--mono);letter-spacing:.08em;
  color:var(--muted);text-transform:uppercase;font-weight:400}
.matrix{border-top:1px solid var(--rule-dim);margin:0;min-width:0}
.matrix-row{--pitch:11px;--sq:7px;
  display:grid;grid-template-columns:minmax(150px,210px) minmax(0,1fr) 42px;gap:20px;
  align-items:center;border-bottom:1px solid var(--rule-dim);padding:13px 0}
.matrix-row dt{font:12px var(--mono);color:#b6b4ac;letter-spacing:.02em}
.matrix-row .bar{height:9px;min-width:0;
  background-image:linear-gradient(90deg,var(--red) 0 var(--sq),transparent var(--sq) var(--pitch));
  background-repeat:repeat-x;background-size:var(--pitch) 9px;
  width:min(calc(var(--n) * var(--pitch)),100%)}
.matrix-row.dim .bar{background-image:linear-gradient(90deg,#3f4440 0 var(--sq),transparent var(--sq) var(--pitch))}
.matrix-row dd{margin:0;font:12px var(--mono);color:var(--muted);text-align:right}

/* --- Post cards: hover changes state, it does not move the box.
       subgrid keeps meta/title/excerpt on a shared baseline. --- */
.post-card{transition:border-color .18s}
.post-card:hover{border-color:var(--red)}
.post-card:hover .meta{color:var(--red)}
.post-card h3{font:500 clamp(22px,1.4vw,27px)/1.14 var(--serif);
  letter-spacing:-.035em;margin:14px 0 14px;text-wrap:balance}
@supports(grid-template-rows:subgrid){
  .post-list{grid-template-rows:auto auto auto}
  .post-card{display:grid;grid-template-rows:subgrid;grid-row:span 3;row-gap:0}
  .post-list .post-card p{margin-top:0;align-self:start}
}

@media(min-width:1700px){
  .post-list{grid-template-columns:repeat(4,1fr)}
  .matrix-row{grid-template-columns:minmax(200px,260px) minmax(0,1fr) 50px}
}
@media(max-width:900px){
  .coverage-grid{grid-template-columns:1fr;gap:38px}
  .hero{padding:68px 0 80px}
}
@media(max-width:620px){
  .matrix-row{grid-template-columns:1fr auto;gap:8px 14px;--pitch:9px;--sq:6px;padding:14px 0}
  .matrix-row dt{grid-column:1;font-size:11px}
  .matrix-row dd{grid-column:2;grid-row:1}
  .matrix-row .bar{grid-column:1/-1;grid-row:2}
}
@media(prefers-reduced-motion:reduce){
  .scanline{animation:none!important;opacity:0}
}

/* --- Phone fixes. Measured on a 390px viewport against the real content,
       not assumed from the desktop layout shrinking down. --- */
@media(max-width:620px){
  /* The ghost numeral has no room beside the copy once the hero is one
     column; it crowded the status line. Decoration goes first. */
  .hero:after{display:none}
  .hero{padding:56px 0 64px}

  /* The exhibit id was flush to both panel edges with zero slack, so one
     extra character would have overflowed. Scale it with the viewport
     and let it break rather than push out. */
  .visual-id b{font-size:clamp(22px,7vw,52px);overflow-wrap:anywhere}
  .feature-visual{min-height:auto;padding:22px;gap:34px}

  /* Three stats wrapped 2 + 1, leaving an orphan. Lock them to one row. */
  .tally{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
  .tally div{min-width:0}
  .tally dt{font-size:9px;letter-spacing:.06em}
  .tally dd{font-size:clamp(32px,9vw,46px)}
  .tally dd small{font-size:9px;margin-top:6px}

  /* The widest bar ate 216 of 350px. Tighten the unit so the row reads
     as label + bar + count, not as one long stripe. */
  .matrix-row{--pitch:8px;--sq:5px}
}

/* --- Tablet / stacked range (621-900px). The base theme groups
       .hero-grid and .feature in one gap:35px rule when stacking, but
       .feature draws its divider as a 1px gap over a --line background:
       widening the gap turns that hairline into a 35px grey slab. --- */
@media(max-width:900px){
  .feature{gap:1px}
  .feature-visual{min-height:200px}
  /* The ghost numeral crowds the status line well before phone widths. */
  .hero:after{display:none}
}
@media(min-width:621px) and (max-width:900px){
  /* One 690px-wide card per row reads as a stranded block; two is denser
     and keeps the excerpt measure sane. */
  .post-list{grid-template-columns:repeat(2,1fr)}
}
