/* sardine.css — framework additions on top of the ph7x sheets.
   Only what the original site does not have: the search island's result list
   and small chrome glue. Tokens come from the design system. */
site-search{display:block}
.site-search-count{color:var(--faint);font-size:.8rem;margin-top:10px}
.site-search-results{list-style:none;padding:0;margin:14px 0 0}
.site-search-results li{padding:14px 0;border-bottom:1px solid var(--line)}
.site-search-results a{font-family:var(--serif);font-size:1.15rem;color:var(--head)}
.site-search-results a:hover{color:var(--accent)}
.site-search-results p{color:var(--muted);font-size:.9rem;margin:6px 0 0}
.fl a{transition:color .3s}

/* Cards/list toggle — the original drives .b-views with JS; here two radio
   inputs restyle the grid through :has(), so the page needs no script and
   works as plain cards when :has() is unsupported (ADR-0010). */
.b-views label.bv{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;background:transparent;border:1px solid var(--line-2);border-radius:8px;color:var(--muted);cursor:pointer;transition:color .3s,border-color .3s,background .3s}
.b-views label.bv svg{width:17px;height:17px}
.b-views label.bv:hover{color:var(--head);border-color:var(--faint)}
.b-views label.bv:has(input:checked){color:var(--head);border-color:var(--faint);background:var(--panel)}
.b-views label.bv input{position:absolute;width:1px;height:1px;opacity:0}
.b-views label.bv:has(input:focus-visible){outline:2px solid var(--accent);outline-offset:2px}
main:has(#bv-list:checked) .b-grid{grid-template-columns:minmax(0,1fr);gap:14px}
main:has(#bv-list:checked) .b-card{flex-direction:row;align-items:stretch}
main:has(#bv-list:checked) .b-thumb{flex:0 0 32%;max-width:250px;aspect-ratio:auto}
main:has(#bv-list:checked) .b-cbody{padding:20px 26px}
main:has(#bv-list:checked) .b-card h3{margin-top:6px;font-size:1.26rem}
@media(max-width:820px){
  main:has(#bv-list:checked) .b-card{flex-direction:column}
  main:has(#bv-list:checked) .b-thumb{flex:none;max-width:none}
}

/* Constellation field — the original hero draws a particle net on a canvas;
   the static equivalent is an inline-SVG star layer, no JavaScript. */
.hero::after,.b-hero::after{content:"";position:absolute;inset:0;pointer-events:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 800'%3E%3Cg stroke='%23aab4c8' stroke-width='.6' opacity='.14'%3E%3Cpath d='M120 140L310 90M310 90L470 210M470 210L640 120M780 320L960 240M960 240L1110 350M240 520L420 610M900 560L1060 640'/%3E%3C/g%3E%3Cg fill='%23cfd6e4'%3E%3Ccircle cx='120' cy='140' r='1.4' opacity='.7'/%3E%3Ccircle cx='310' cy='90' r='1' opacity='.5'/%3E%3Ccircle cx='470' cy='210' r='1.6' opacity='.8'/%3E%3Ccircle cx='640' cy='120' r='1' opacity='.45'/%3E%3Ccircle cx='780' cy='320' r='1.2' opacity='.6'/%3E%3Ccircle cx='960' cy='240' r='1.5' opacity='.75'/%3E%3Ccircle cx='1110' cy='350' r='1' opacity='.5'/%3E%3Ccircle cx='240' cy='520' r='1.1' opacity='.5'/%3E%3Ccircle cx='420' cy='610' r='1.4' opacity='.65'/%3E%3Ccircle cx='900' cy='560' r='1.2' opacity='.55'/%3E%3Ccircle cx='1060' cy='640' r='1' opacity='.45'/%3E%3Ccircle cx='560' cy='430' r='.9' opacity='.4'/%3E%3Ccircle cx='700' cy='540' r='1' opacity='.5'/%3E%3Ccircle cx='180' cy='330' r='.9' opacity='.4'/%3E%3Ccircle cx='1020' cy='120' r='1.1' opacity='.55'/%3E%3Ccircle cx='840' cy='90' r='.9' opacity='.4'/%3E%3C/g%3E%3C/svg%3E");background-size:1200px 800px;opacity:.8}
.b-hero{position:relative}
.hero .wrap,.b-hero>*{position:relative;z-index:1}
.story img{width:100%;height:auto;margin-top:40px;border:1px solid var(--line);border-radius:6px}

/* WCAG AA: nav links need >=4.5:1 on the navy header; the token --muted
   (#7b7e88) sits just under it there. One shade up, only in the header. */
#hdr .lk a{color:#9aa0ad}
#hdr .lang a{color:#8b909c}
.exp .row .no{color:#8b909c}
.b-ctag{color:#8b909c}
.b-cmeta{color:#8b909c}
.b-by{color:#8b909c}
.pagination span{color:#8b909c}
.b-pager span{color:#8b909c}
.b-pager a{color:#9aa0ad}
/* The original dims the admin link with opacity; that fails AA on our gate,
   so dim via an AA-passing color at full opacity instead. */
.fl-adm{opacity:1;color:#8b909c}
.b-card h3{font-family:var(--serif);font-size:1.42rem;font-weight:400;line-height:1.28;color:var(--head);margin:12px 0 10px;overflow-wrap:break-word}

/* Motion polish — all scroll-driven or time-based CSS, zero JavaScript.
   Without animation-timeline support the page is simply static (complete
   either way); prefers-reduced-motion kills everything via site.css. */
@supports (animation-timeline: scroll()) {
  .top{animation:sar-top-appear linear both;animation-timeline:scroll();animation-range:300px 700px}
}
@keyframes sar-top-appear{to{opacity:1;visibility:visible;transform:none}}
.top:hover{color:var(--head);border-color:var(--faint)}
@supports (animation-timeline: view()) {
  .b-card,.exp .row{animation:sar-rise linear both;animation-timeline:view();animation-range:entry 0% entry 45%}
}
@keyframes sar-rise{from{transform:translateY(18px)}to{transform:none}}
.hero::after{animation:sar-twinkle 8s ease-in-out infinite alternate}
@keyframes sar-twinkle{from{opacity:.55}to{opacity:.95}}
