/* Stakes marketing site: the library's shared parts, linked after base.css by every page that shows
   the library (index.html: the wall, cards.html: the full table).

   Two pieces live here and are built by library.js:
     * the BOOK FILTER BAR (`.filters`): All, Book One, Book Two, Book Three, Universal, each a square
       button with the Book's hue beside its word, the pressed one filled gold;
     * the OPENED CARD (`dialog.cv`): the card's splash art in a framed panel, the full card face, its
       Book, Gold, Power and Health, keywords and effect text. Full screen and scrolling on a phone.
   A page's own sections stay in its own sheet (landing.css, cards.css).

   The look law: docs/website/site-look.md. No rounded or oval shape except a card's small corner. */
.filters { display:flex; flex-wrap:wrap; justify-content:center; gap:6px; }
.filters button { display:inline-flex; align-items:center; gap:8px; min-height:44px; padding:0 14px; font:800 .68rem/1 var(--ui); letter-spacing:.16em; text-transform:uppercase;
  color:var(--faded); border:1px solid var(--line-soft); background:rgba(10,11,15,.9); transition:color .2s, border-color .2s, background .2s; }
.filters button::before { content:''; width:9px; height:9px; background:var(--hue,transparent); border:1px solid var(--hue,var(--gold-dim)); }
.filters button[aria-pressed="true"] { color:#1a1207; background:var(--gold); border-color:var(--gold-hi); }
.filters button:hover { color:var(--gold-hi); border-color:var(--gold); }
.filters button[aria-pressed="true"]:hover { color:#1a1207; }

/* ---- the opened card: splash art and the full card over the dimmed wall ----
   THE LAYOUT LAW: A STILL FRAME, ONE SCROLL. The dialog is a fixed, full-screen box (and the size
   container every length below counts from: `cqw`, `cqh`). It holds three layers, and only the middle
   one ever moves:
     * the FRAME (`.cv-frame`): the panel's metal edge, its fill, its inner line and the splash art;
     * the SCROLL (`.cv-scroll`): the one scroller, as large as the dialog, so a wheel, a trackpad, a
       finger and the keys move it from anywhere over the dialog, the art and the dim included. Inside
       it the text is laid out in the panel's shape (`.cv-panel`, see-through) right over the frame;
     * the BAR (`.cv-bar`): the Close tab in the frame's top-right corner, above both.
   Nothing is sticky and nothing is fixed inside the scroller: the frame and the bar are its siblings,
   so no browser's async scrolling can leave one of them a frame behind the text, and the art meets the
   frame's padding at its top and its foot at every moment. The panel takes its content's height and is
   never capped; library.js measures it into --cv-ph, and the frame is that tall up to the screen's
   height. A panel shorter than the screen centres, the frame exactly round it; a taller one pins to the
   top and its text scrolls inside the still frame, its top and its foot both reachable. A short card
   keeps a framed panel at least 664px tall. The frame and the panel share one width, taken from the
   dialog rather than the scroller, and the scroller keeps a gutter on both edges, so a scrollbar never
   moves the text off the frame. */
.cv[open] { --cv-y:clamp(10px,2.2vh,28px); --cv-x:clamp(16px,3vw,40px); --cv-tab:32px; --cv-fade:48px; --cv-s:0; --cv-d:0; --cv-ph:664px;
  --fill:rgba(9,10,14,.97); --cv-aw:clamp(280px,29vw,420px);
  --cv-fw:min(1240px, 100cqw - 2 * var(--cv-x)); --cv-fh:min(var(--cv-ph), 100cqh - 2 * var(--cv-y)); --cv-ft:calc((100cqh - var(--cv-fh)) / 2);
  --cv-wt:calc(var(--cv-ft) + 12px + var(--cv-tab)); --cv-wb:calc(100cqh - var(--cv-ft) - 12px); --cv-mr:max(50cqw - 620px, var(--cv-x));
  position:fixed; inset:0; width:100%; height:100%; max-width:none; max-height:none; margin:0; padding:0;
  border:0; background:transparent; color:var(--text); overflow:hidden; container-type:size; }
/* the dim is dense and blurred, so nothing on the page (the pressed filter's gold included) reads through it */
.cv::backdrop { background:rgba(4,5,8,.92); -webkit-backdrop-filter:blur(6px) saturate(.6); backdrop-filter:blur(6px) saturate(.6); }
/* the page behind does not scroll, and its scrollbar's gutter stays, so the wall does not jump sideways when a card opens */
html:has(.cv[open]) { overflow:hidden; scrollbar-gutter:stable; }
/* The frame: the panel's chamfered metal edge and fill (base.css `.frame`), the splash art standing inside
   its 12px padding, so the edge and the inner line run round the art too. The art is as tall as the
   frame, so a short card's art fills its frame and a long card's holds still, whole, beside the text. */
.cv-frame { --cut:22px; position:absolute; z-index:0; left:0; right:0; top:var(--cv-ft); width:var(--cv-fw); height:var(--cv-fh); margin:0 auto; }
.cv-art { --cut:16px; position:absolute; z-index:1; left:12px; top:12px; bottom:12px; width:var(--cv-aw);
  overflow:hidden; background:#0b0d12; clip-path:polygon(var(--cut) 0, 100% 0, 100% 100%, var(--cut) 100%, 0 calc(100% - var(--cut)), 0 var(--cut)); }
.cv-art img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
.cv-art::after { content:''; position:absolute; inset:0; pointer-events:none; background:linear-gradient(90deg,transparent 72%,rgba(9,10,14,.55)), linear-gradient(0deg,rgba(9,10,14,.35),transparent 30%); }
/* The scroll. It takes focus itself when the card opens (library.js), so Space, the arrows, the Page keys,
   Home and End scroll it at once, and Space never presses Close by surprise. It is the scroll surface,
   not a control: a ring round the whole screen would point at nothing, and Tab never lands on it (Close
   is the first stop). Its scroll padding keeps a focused link or a Page step clear of the cut.
   THE CUT IS A FADE INTO THE FRAME. The text shows only inside the frame's window: under the Close row
   and above the frame's padding at the foot. Where it runs on past that window it fades out into it.
   The fade is a mask on the scroller, so what shows through it is exactly the frame behind, never a
   painted band of any colour. Each edge's fade follows the scroll: library.js sets --cv-s from the
   distance scrolled and --cv-d from the distance left, each full after 48px, so a card that fits shows
   none, and the text's own first and last lines are crisp at the top and the end. The strip right of
   the frame (the scrollbar's) is never masked. */
.cv-scroll { position:absolute; z-index:1; inset:0; display:flex; padding:var(--cv-y) 0; overflow:auto; overscroll-behavior:contain;
  scrollbar-gutter:stable both-edges; scrollbar-color:var(--gold-dim) transparent;
  scroll-padding:calc(var(--cv-wt) + var(--cv-fade)) 0 calc(100cqh - var(--cv-wb) + var(--cv-fade));
  -webkit-mask:linear-gradient(180deg, transparent var(--cv-wt), rgb(0 0 0 / calc(1 - var(--cv-s))) var(--cv-wt), #000 calc(var(--cv-wt) + var(--cv-fade)),
      #000 calc(var(--cv-wb) - var(--cv-fade)), rgb(0 0 0 / calc(1 - var(--cv-d))) var(--cv-wb), transparent var(--cv-wb)) 0 0 / calc(100% - var(--cv-mr)) 100% no-repeat,
    linear-gradient(#000, #000) 100% 0 / var(--cv-mr) 100% no-repeat;
  mask:linear-gradient(180deg, transparent var(--cv-wt), rgb(0 0 0 / calc(1 - var(--cv-s))) var(--cv-wt), #000 calc(var(--cv-wt) + var(--cv-fade)),
      #000 calc(var(--cv-wb) - var(--cv-fade)), rgb(0 0 0 / calc(1 - var(--cv-d))) var(--cv-wb), transparent var(--cv-wb)) 0 0 / calc(100% - var(--cv-mr)) 100% no-repeat,
    linear-gradient(#000, #000) 100% 0 / var(--cv-mr) 100% no-repeat; }
.cv-scroll:focus-visible { outline:none; }
/* The panel: the text laid out in the frame's shape, see-through, so the frame shows behind it. Two
   columns, the first the art's (empty here: the art is the frame's), and on the right a slim top row
   kept for the Close tab, then the text. It clips what overflows it, so the motion inside it (the card
   flying in from the wall, the text rising into place) never stretches the scroll or flashes a
   scrollbar. */
.cv-panel { flex:none; margin:auto; overflow:clip; width:var(--cv-fw); min-height:min(664px, 100cqh - 2 * var(--cv-y));
  display:grid; grid-template-columns:var(--cv-aw) minmax(0,1fr); grid-template-rows:var(--cv-tab) minmax(0,1fr); padding:12px 0 12px 12px; }
/* The text fills the panel's second row and is centred in it when the panel is taller than the text (a
   short card in its 664px frame). It ends on its own bottom padding, clear of the frame. */
.cv-body { grid-column:2; grid-row:2; position:relative; z-index:1; display:flex; flex-direction:column; justify-content:safe center; gap:18px;
  padding:clamp(14px,1.6vw,22px) clamp(24px,3vw,44px) clamp(28px,3vw,40px); }
.cv-head { display:grid; grid-template-columns:clamp(132px,11vw,160px) minmax(0,1fr); gap:clamp(18px,2.2vw,30px); align-items:end; }
.cv-face .card { --card-r:10px; }
.cv-id { display:flex; flex-direction:column; align-items:flex-start; gap:14px; min-width:0; }
.cv-id h3 { font:900 clamp(2.2rem,4vw,3.8rem)/.92 var(--display); letter-spacing:.03em; text-transform:uppercase; color:var(--parchment); text-shadow:0 2px 0 rgba(0,0,0,.6); overflow-wrap:anywhere; }
.chip { display:inline-flex; align-items:center; gap:8px; min-height:30px; padding:0 10px; font:800 .66rem/1 var(--ui); letter-spacing:.16em; text-transform:uppercase; color:var(--parchment);
  background:rgba(6,7,10,.8); border:1px solid color-mix(in srgb, var(--hue,#a6a194) 70%, transparent); }
.chip::before { content:''; width:10px; height:10px; background:var(--hue,#a6a194); flex:none; }
.stats { display:flex; gap:8px; }
.stat { min-width:84px; padding:10px 12px 8px; border:1px solid var(--line-soft); background:rgba(6,7,10,.7); }
.stat span { display:block; font:800 .6rem/1 var(--ui); letter-spacing:.18em; text-transform:uppercase; color:var(--faded); }
.stat b { display:block; font:800 2.1rem/1.05 var(--display); margin-top:4px; }
.stat-gold b { color:#ffd25a; } .stat-power b { color:var(--stk-stat-power); } .stat-health b { color:var(--stk-stat-health); }
.kws { display:flex; flex-wrap:wrap; gap:6px; }
.kws[hidden] { display:none; }
.kws .kw { font-size:.7rem; padding:7px 9px; }
.skills { display:grid; gap:12px; font-size:1rem; line-height:1.55; color:var(--text); padding-top:16px; border-top:1px solid var(--line-soft); }
.skills .sk-chip { display:inline-block; margin-right:8px; padding:3px 7px 2px; font:800 .62rem/1.3 var(--ui); letter-spacing:.14em; text-transform:uppercase; color:#1a1207; background:var(--gold); vertical-align:2px; }
.skills i { font-style:normal; color:var(--faded); }
/* ---- the Close tab: part of the frame's top-right corner ----
   A plaque hung in the panel's chamfered corner, in the frame's own metal: its outer edge is the same
   gold gradient as the frame's line and its top-right cut is the frame's own 22px, so it reads as the
   corner thickening into a tab rather than a button laid on the card. It lives in the bar, above the
   scroller and outside it, so it never moves and stays in reach however far the text has scrolled; the
   text passes under its row only inside the cut, where the fade has already taken it. The word stays
   beside the cross (the cross alone would be a read with no label), the target is 44px tall, and every
   corner is cut, none rounded. A wheel or a scroll key on it still scrolls the card (library.js).
   Focus thickens the plaque's rim inward (base.css, THE FOCUS RIM). */
.cv-bar { position:absolute; z-index:2; left:0; right:0; top:var(--cv-ft); width:var(--cv-fw); height:calc(var(--cv-tab) + 12px); margin:0 auto;
  display:flex; justify-content:flex-end; align-items:flex-start; pointer-events:none; }
.cv-close { --tab-cut:22px; --rim:1px; --tab-poly:polygon(0 12px, 12px 0, calc(100% - var(--tab-cut)) 0, 100% var(--tab-cut), 100% 100%, 14px 100%, 0 calc(100% - 14px));
  --tab-poly-in:polygon(0 calc(12px - var(--rim) * .59), calc(12px - var(--rim) * .59) 0, calc(100% - var(--tab-cut) + var(--rim) * .59) 0, 100% calc(var(--tab-cut) - var(--rim) * .59), 100% 100%, calc(14px - var(--rim) * .59) 100%, 0 calc(100% - 14px + var(--rim) * .59));
  position:relative; isolation:isolate; pointer-events:auto; display:inline-flex; align-items:center; gap:10px; height:44px; min-width:44px; padding:0 22px 0 18px;
  font:800 .7rem/1 var(--ui); letter-spacing:.18em; text-transform:uppercase; color:var(--gold-hi); border:0; background:var(--metal-edge); clip-path:var(--tab-poly); transition:color .2s; }
.cv-close::before { content:''; position:absolute; inset:var(--rim); z-index:-1; clip-path:var(--tab-poly-in); background:linear-gradient(180deg,#1c1409,#0b0d12); transition:background .2s; }
.cv-close:hover { color:var(--parchment); }
.cv-close:hover::before { background:linear-gradient(180deg,#2e2008,#140f08); }
.cv-close i { position:relative; width:12px; height:12px; flex:none; }
.cv-close i::before, .cv-close i::after { content:''; position:absolute; left:-1px; right:-1px; top:5px; height:2px; background:currentColor; transform:rotate(45deg); }
.cv-close i::after { transform:rotate(-45deg); }
@media (max-width:860px) {
  /* full screen: no frame, so no metal edge left showing down the screen's sides. The sheet scrolls whole
     under the Close bar: an opaque strip with a gold line under it, above the scroller and outside it,
     so the text that scrolls up passes beneath the bar and never under the tab. A finger on the bar's
     empty part still drags the sheet (the bar lets it through); the bar stops short of a scrollbar. */
  .cv-frame { display:none; }
  .cv-scroll { padding:56px 0 0; scrollbar-gutter:auto; scroll-padding:72px 0 16px; background:var(--fill); -webkit-mask:none; mask:none; }
  .cv-panel { margin:0; align-self:flex-start; width:100%; min-height:100%; grid-template-columns:1fr; grid-template-rows:auto; align-content:start; padding:0; }
  .cv-bar { top:0; right:var(--cv-sb,0px); width:auto; height:56px; margin:0; align-items:center; padding:0 12px; background:#090a0e; border-bottom:1px solid var(--line-soft); }
  .cv-close { --tab-cut:12px; }
  /* the art is the sheet's (library.js moves it in): cropped short enough that the card's text starts above the fold, and scrolls with the sheet */
  .cv-art { grid-column:1; grid-row:1; position:relative; z-index:auto; inset:auto; height:min(calc(100vw * 1.5), 52vh); height:min(calc(100vw * 1.5), 52svh); width:100%; clip-path:none; }
  .cv-art::after { background:linear-gradient(0deg,rgba(9,10,14,1),rgba(9,10,14,.4) 16%,transparent 34%); }
  .cv-body { grid-column:1; grid-row:2; justify-content:flex-start; padding:0 16px 40px; margin-top:-96px; }
  .cv-head { grid-template-columns:clamp(124px,36vw,170px) minmax(0,1fr); gap:16px; }
  .cv-id { gap:10px; }
  .cv-id h3 { font-size:clamp(1.7rem,8vw,2.4rem); }
  .cv-id .stats { flex-wrap:wrap; gap:6px; }
  .cv-id .stat { min-width:0; padding:8px 9px 6px; }
  .cv-id .stat b { font-size:1.6rem; }
}
