/* ==========================================================================
   mcprush — skills.css
   The second product line. Three things live here:
     1. the skill card, which skills.html, index.html and server.html all render
        through skillCard() and which therefore must not depend on any page id;
     2. the catalogue chrome (packs, pairings, table, filter tint);
     3. the context budget tray.
   Every rule below reads --skill / --skill-soft / --skill-line and nothing
   names a colour of its own. That was written when skills had a hue to
   themselves; --skill is an alias of --accent now, so the same rules carry the
   scheme's one accent instead — and both the dark theme and every colour
   scheme still cost nothing.
   ========================================================================== */

/* =============== shared: skill card ====================================== */
.kcard {
  display: flex; flex-direction: column; gap: 11px; padding: 16px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r3);
  box-shadow: var(--sh1); transition: border-color .16s, box-shadow .16s, transform .16s;
  position: relative; min-width: 0;
}
.kcard:hover { border-color: var(--line-2); box-shadow: var(--sh2); transform: translateY(-2px); }
.kcard-top { display: flex; gap: 12px; align-items: flex-start; }
/* the selection box sits over the top-right corner, so a card that carries one
   has to keep its name clear of it — 34px is the 40px target minus the padding
   the card already has on that side */
.kcard:has(.kcard-sel) .kcard-top { padding-right: 34px; }
/* ИМЯ КАРТОЧКИ — ДВЕ СТРОКИ, ДАЛЬШЕ МНОГОТОЧИЕ.
   Имя приходит от автора, и оно бывает не именем, а объявлением: у одного
   импортированного скилла заголовок в четыре строки капсом занял столько же
   места, сколько вся остальная карточка, и ряд поехал. Ограничение стоит
   здесь, а не в разметке: карточку рисуют три разных места (каталог, полка
   на главной, профиль автора), и правило должно быть одно.
   `display: flex` заменён на `-webkit-box` ради самого обрезания; галочка
   проверенного автора рядом с именем остаётся строчным элементом. */
.kcard-name { font-size: 15px; font-weight: 600; letter-spacing: -.02em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere; }
.kcard-name > * { vertical-align: middle; }
.kcard-name:hover { color: var(--skill); }
.kcard-pub { font-size: 12.5px; color: var(--ink-3); display: flex; align-items: center; gap: 4px; margin-top: 1px; flex-wrap: wrap; }
.kcard-desc { font-size: 13.5px; line-height: 1.5; color: var(--ink-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* the signature line: a server card shows a spec, a skill card shows the
   sentence you say to it. One line, always — two would read as prose. */
.kcard-trig {
  font: 400 12.5px/1.4 var(--mono); color: var(--skill);
  background: var(--skill-soft); border: 1px solid var(--skill-line);
  border-radius: var(--r1); padding: 6px 9px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* added by the catalogue, not by skillCard: which servers the skill calls */
.kcard-needs { display: flex; align-items: center; gap: 6px; min-width: 0; font: 400 12px/1.4 var(--mono); color: var(--ink-3); }
.kcard-needs svg { width: 12px; height: 12px; flex: none; }
.kcard-needs span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.kcard-meta { display: flex; align-items: center; gap: 12px; font: 400 12px/1 var(--mono); color: var(--ink-3); flex-wrap: wrap; }
.kcard-meta b { color: var(--ink-2); font-weight: 500; }
.kcard-meta svg { width: 12px; height: 12px; vertical-align: -2px; }
.kcard-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 12px; border-top: 1px solid var(--line); margin-top: auto; }
/* The pick box is the card's primary control and the checkbox itself is 15px.
   The label carries a 40px target and the box floats in the middle of it, so
   the hit area is thumb-sized without the tick growing into a toggle. */
.kcard-sel { position: absolute; top: 2px; right: 2px; width: 40px; height: 40px; padding: 0; display: grid; place-items: center; }
.kcard.picked { border-color: var(--skill); box-shadow: 0 0 0 3px var(--skill-soft); }

.kgrid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 14px; }

/* =============== page hue ================================================= */
/* Everything under .kpage swaps the emerald affordances for the skill blue.
   Scoped rather than global because the header, footer and role switcher stay
   on the marketplace green. */
.kpage .spec::before { background: var(--skill); }
.kpage .check input:checked { background-color: var(--skill); border-color: var(--skill); }
.kpage .check input[type="radio"] { border-radius: 50%; }
.kpage .check input[type="radio"]:checked { background-image: none; box-shadow: inset 0 0 0 3px var(--surface); }
.kpage .field:focus-within { border-color: var(--skill); box-shadow: 0 0 0 3px var(--skill-soft); }
.kpage input[type="range"]::-webkit-slider-thumb { border-color: var(--skill); }
.kpage .chip { border-color: var(--skill-line); background: var(--skill-soft); color: var(--skill); }
.kpage .btn.on { color: var(--skill); border-color: var(--skill-line); background: var(--skill-soft); }
.kpage .btn.on:hover { border-color: var(--skill); background: var(--skill-soft); }

/* =============== header =================================================== */
.khead { display: flex; align-items: flex-start; justify-content: space-between; gap: 32px; flex-wrap: wrap; padding-block: 2px 22px; }
.khead-t { min-width: 0; }
.khead-t h1 { max-width: 22ch; }
.khead .lead { margin-top: 12px; max-width: 74ch; }
.khead-acts { display: flex; gap: 8px; flex: none; padding-top: 6px; }

/* =============== sections ================================================= */
.ksec { padding-block: 26px 4px; }
.ksec .section-head { margin-bottom: 16px; }

/* packs */
.packs { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 14px; }
.pack { display: flex; flex-direction: column; gap: 12px; padding: 18px; min-width: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r3); }
.pack:hover { border-color: var(--line-2); box-shadow: var(--sh1); }
.pack-desc { font-size: 13.5px; line-height: 1.55; color: var(--ink-2); }
.pack-items { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r2); overflow: hidden; }
.pack-item { display: flex; align-items: center; gap: 9px; padding: 8px 11px; background: var(--surface); font-size: 13px; min-width: 0; }
.pack-item .tile { width: 22px; height: 22px; font-size: 10px; border-radius: 6px; }
.pack-item .n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pack-item .t { margin-left: auto; flex: none; font: 400 11.5px/1 var(--mono); color: var(--ink-3); }
.pack-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line); }

/* pairings with the reader's library */
.pairs { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px; }
.pair { display: flex; align-items: center; gap: 12px; min-width: 0; padding: 12px 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r2); }
.pair:hover { border-color: var(--line-2); }
.pair-b { min-width: 0; flex: 1 1 auto; }
.pair-name { display: block; font-size: 14px; font-weight: 600; letter-spacing: -.015em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pair-name:hover { color: var(--skill); }
.pair-why { font-size: 12.5px; color: var(--ink-3); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pair-why b { color: var(--ink-2); font-weight: 550; }
.pair-ctx { flex: none; font: 400 12px/1 var(--mono); color: var(--ink-3); }

/* =============== filters ================================================== */
.fnote { font-size: 12px; line-height: 1.45; color: var(--ink-3); margin-top: 9px; }
.fgroup .check[title] { cursor: help; }
/* .filters, .filters-head/-body, .fscroll and the whole phone sheet are shared
   with catalog.html and live in views.css; this page opts in with
   <body data-filter-sheet>. Only the hue is ours — the facet counter is painted
   in the marketplace emerald by default and this page is the blue line. */
.kpage .cat-filter-n { background: var(--skill); }
[data-theme="dark"] .kpage .cat-filter-n { color: #0B1024; }

/* =============== results meta ============================================= */
.kmeta { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 14px; }

/* =============== table view =============================================== */
.ktbl-wrap { overflow-x: auto; }
.ktbl { min-width: 860px; width: 100%; }
.ktbl .nm { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ktbl .nm .tile { width: 28px; height: 28px; font-size: 12px; border-radius: 7px; }
/* the verified tick belongs on the name's line: auto table layout will happily
   break between the two and leave a tick stranded on a line of its own */
.ktbl .nm .t { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ktbl .sel { flex: none; padding: 0; }
.ktbl .needs { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ktbl tbody tr.picked { background: var(--skill-soft); }

/* =============== context budget tray ====================================== */
/* Extends .tray from views.css — same dark panel and slide-up — but it counts
   context rather than collecting things to compare. `bottom` is deliberately
   not set here: roles.css lifts every .tray to 82px to clear the role switcher,
   and re-declaring it would put the two controls back on top of each other. */
.tray-budget { align-items: center; gap: 16px; padding: 12px 14px 12px 16px; width: min(780px, calc(100% - 32px)); }
.tb-ic { display: grid; place-items: center; width: 32px; height: 32px; flex: none;
  border-radius: 8px; background: var(--panel-2); border: 1px solid var(--panel-line); color: var(--panel-ink2); }
.tb-ic svg { width: 16px; height: 16px; }
.tb-main { flex: 1 1 auto; min-width: 0; display: grid; gap: 7px; }
.tb-line { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.tb-line b { font-size: 13.5px; font-weight: 600; }
.tb-num { font: 500 12.5px/1 var(--mono); color: var(--panel-ink2); }
.tb-bar { height: 5px; border-radius: 3px; background: var(--panel-line); overflow: hidden; }
.tb-bar i { display: block; height: 100%; border-radius: 3px; background: var(--panel-ink); transition: width .22s; }
.tray-budget.warn .tb-bar i { background: var(--warn); }
.tray-budget.heavy .tb-bar i { background: var(--risk); }
.tb-note { font-size: 12px; line-height: 1.45; color: var(--panel-ink2); }
.tb-acts { display: flex; align-items: center; gap: 8px; flex: none; }
.tray-budget .btn-quiet { color: var(--panel-ink2); }
.tray-budget .btn-quiet:hover { color: var(--panel-ink); background: var(--panel-2); }
/* the folded bar: hidden until the tray is narrow enough to need folding */
.tb-toggle { display: none; }

/* =============== responsive =============================================== */
@media (max-width: 1180px) {
  .kgrid { grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (max-width: 1080px) {
  .packs { grid-template-columns: repeat(2, minmax(0,1fr)); }
}

/* ---- the filter rail becomes a sheet ------------------------------------- */
/* The sheet itself is views.css's, shared with catalog.html and switched on by
   <body data-filter-sheet>. Only the hue is ours below 620px — core.css sizes
   every .check and every range there, and catalog.html renders the identical
   sheet from the identical markup, so anything declared here would be one
   catalogue's rows six pixels taller than the other's for no reason a reader
   could name. Measured before this rule was narrowed: 45 rows at 44px on
   skills.html against 41 rows at 38px on catalog.html.

   Between 621 and 1000 the sheet is already in use and core's phone scale is
   not, so the rail's mouse-sized 27px row still has to be lifted for a tablet
   thumb — that, and only that, is what is left here. */
@media (min-width: 621px) and (max-width: 1000px) {
  .kpage .filters .check { min-height: 44px; padding: 4px 0; }
  .kpage .filters .check input { width: 20px; height: 20px; }
  .kpage .filters .check input:checked { background-size: 14px; }
  .kpage .filters input[type="range"] { height: 44px; }
}

@media (max-width: 900px) {
  .pairs { grid-template-columns: 1fr; }
  .khead-acts { width: 100%; }
  /* the reassurance line drops below the count instead of fighting it for the
     same line and losing half its words to a squeeze. The tick stays on the
     first line of the sentence: .row would otherwise wrap it onto a line of its
     own, which reads as a bullet with nothing after it. */
  .kmeta { flex-wrap: wrap; gap: 6px 16px; }
  /* nowrap is load-bearing, not decoration: core.css now wraps every .row under
     620px, which put the tick on a line by itself with the sentence beneath it
     — a bullet with nothing after it. Held on one flex line, the tick keeps the
     sentence's first line and the text wraps inside its own item. */
  .kmeta-note { align-items: flex-start; flex-wrap: nowrap; min-width: 0; }
  .kmeta-note [data-icon] { flex: none; margin-top: 3px; }
}

/* ---- the skills table is not the servers table --------------------------- */
/* views.css pins the first two columns of any .results-tbl under 860px and
   gives column one a fixed 44px, because on catalog.html column one is a
   compare tick. Here column one is the whole name block — tick, mark, name and
   publisher — so the same rule crushes it to 44px and the row is unreadable.
   Below 860px this table scrolls its wrapper instead, and below 720px it stops
   being a table at all. */
@media (max-width: 860px) {
  .kpage .results-tbl { overflow: hidden; }
  .kpage .results-tbl .ktbl th:nth-child(-n+2),
  .kpage .results-tbl .ktbl td:nth-child(-n+2) {
    position: static; left: auto; width: auto; min-width: 0;
    box-shadow: none; padding-left: 12px; padding-right: 12px;
  }
}

@media (max-width: 720px) {
  /* 720px is where the grid becomes a list, i.e. where the page stops being
     something you scan and becomes something you read top to bottom. The two
     buttons move below the catalogue: "Browse MCP servers" and "Publish a
     skill" are both one tap away in the header, and at 390px they were 104px
     of chrome sitting directly on top of the toolbar, pushing the first card
     to 707px on a 780px screen.

     display:contents dissolves .khead's own box so its two halves become
     children of .kpage and can be ordered separately. The title and the lede
     stay on top — they say what the page is, and the lede is now one sentence
     on a phone, so it no longer needs the three-line clamp the long one had.
     The four stat tiles that used to land here went with the block. */
  .kpage { display: flex; flex-direction: column; }
  .khead { display: contents; }
  .khead-t { order: 1; padding-block: 2px 22px; }
  #cat { order: 2; }
  .khead-acts { order: 3; margin-top: 22px; padding-top: 0; }

  /* The promoted disclosure in the table view kept the desktop treatment views
     .css gives it beside a name: 68x18 in 10px type. Both numbers are below the
     floor, and it is the one control that answers "why am I seeing this". */
  .kpage .promo-tag.inline {
    display: flex; align-items: center; width: fit-content; min-height: 40px;
    margin: 3px 0 1px; padding: 0 9px; font-size: 12px;
  }

  .kgrid, .packs { grid-template-columns: 1fr; }
  /* One column means the card IS the column, so the 16px it holds on each side
     is 9% of a 358px screen spent on air, six times over between its six rows.
     14px and 9px are what core.css gives .card-body and .grid at this width;
     the card carries the same numbers, so a skill card and a server card read
     as one object whichever list they turn up in. */
  .kcard { padding: 14px; gap: 9px; }
  .kcard-foot { padding-top: 10px; }
  /* The two buttons share the row and the basis is what lets them fall onto
     two lines rather than squeeze their labels to nothing when the column can
     no longer hold both. The height is core.css's — a page action is 40px on
     this site, and 38 was this page alone disagreeing with that. */
  .kpage .khead-acts { flex-wrap: wrap; }
  .kpage .khead-acts .btn { flex: 1 1 140px; }
  /* a chip's x was a 16px square in a 26px chip */
  .kpage .chip { height: 34px; padding: 0 4px 0 10px; }
  .kpage .chip button { width: 26px; height: 26px; }

  /* ---- list view: two lines a skill --------------------------------------
     Eight columns at a 860px minimum is 2.4 screens of sideways drag, so the
     first version of this folded every cell into a label/value pair — and
     produced a 700px block per skill: six mono labels, a Details button, and
     more furniture than content. A list is not a record.

     Two lines instead, the same shape the server catalogue uses: the tick, the
     mark, the name and its publisher, then one quiet line of type, context and
     rating with the price closing it on the right. Installs and dependencies
     leave the list — both are on the skill's own page, and neither decides
     which row to open — and so does the Details button, because on a phone the
     row is the link. */
  .kpage .ktbl-wrap { overflow-x: visible; }
  .kpage .ktbl { min-width: 0; }
  .kpage .ktbl thead { display: none; }
  .kpage .ktbl, .kpage .ktbl tbody, .kpage .ktbl tr, .kpage .ktbl td { display: block; }
  .kpage .ktbl tr {
    display: flex; flex-wrap: wrap; align-items: center; gap: 3px 8px;
    padding: 10px 12px; border-bottom: 1px solid var(--line);
  }
  .kpage .ktbl tbody tr:last-child { border-bottom: 0; }
  .kpage .ktbl td {
    padding: 0; border: 0; min-height: 0; text-align: left;
    white-space: normal; min-width: 0;
  }
  .kpage .ktbl td::before { content: none; }
  .kpage .ktbl td.cell-nm { order: 1; flex: 1 1 auto; }
  .kpage .ktbl .nm { align-items: flex-start; gap: 8px; }
  .kpage .ktbl .nm .t { min-width: 0; }
  .kpage .ktbl .sel { width: 32px; height: 32px; margin: -6px 0 -6px -6px; display: grid; place-items: center; flex: none; }
  /* the line break: a flex item that can hold nothing but a line */
  .kpage .ktbl tr::after { content: ''; order: 2; flex: 1 0 100%; height: 0; }
  .kpage .ktbl td[data-l="Type"], .kpage .ktbl td[data-l="Context"],
  .kpage .ktbl td[data-l="Rating"] {
    order: 3; flex: none; font-size: 11.5px; color: var(--ink-3);
  }
  .kpage .ktbl td[data-l="Type"] { margin-left: 38px; }
  .kpage .ktbl td[data-l="Context"]::before { content: "· "; }
  .kpage .ktbl td[data-l="Context"]::after { content: " ctx"; }
  .kpage .ktbl td[data-l="Rating"]::before { content: "· \2605 "; }
  .kpage .ktbl td[data-l="Price"] {
    order: 4; flex: none; margin-left: auto; align-self: baseline;
    font-size: 12px; color: var(--ink); white-space: nowrap;
  }
  .kpage .ktbl td[data-l="Needs"], .kpage .ktbl td[data-l="Installs"],
  .kpage .ktbl td.cell-go { display: none; }
}

/* ---- context budget tray: one folded bar --------------------------------- */
/* 620px is where views.css takes the compare tray full-bleed (left/right 16,
   transform reset); matching it keeps one fixed-bar geometry for both trays.
   The `body` prefix is only there to out-specify roles.css, which loads after
   this file and sets a bottom offset on every .tray.

   That offset used to be the whole reason this rule declared one: the role
   switcher floated over the bottom of every phone screen and both trays had to
   clear it. It is hidden below 721px now, so roles.css rests every tray on
   12px and this one does the same — a 48px stripe of paper under a fixed bar
   reads as a bar that has come loose. */
@media (max-width: 620px) {
  /* the toggle sits beside 44px controls; a 20px target next to them reads as
     decoration and misses under a thumb */
  .cat-toolbar .seg { align-self: stretch; align-items: stretch; }
  .cat-toolbar .seg button { min-height: 34px; }

  body .tray-budget {
    bottom: 12px;
    flex-direction: column; align-items: stretch; gap: 0; padding: 0;
    border-radius: 12px; overflow: hidden;
  }
  .tb-ic { display: none; }
  /* The folded tray is one line of summary and a chevron that opens it, so it
     is a button and it takes a button's 40px. At 48 it was the tallest control
     on a page whose other thirty-odd controls run 34 to 42, and it sits fixed
     over them where the difference is easiest to see. */
  .tb-toggle {
    display: flex; align-items: center; gap: 10px; width: 100%;
    min-height: 40px; padding: 0 10px 0 14px; text-align: left; color: var(--panel-ink);
  }
  .tb-tic { flex: none; display: grid; place-items: center; color: var(--panel-ink2); }
  .tb-tic svg { width: 16px; height: 16px; }
  .tb-sum { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13.5px; }
  .tb-sum b { font-weight: 600; }
  .tb-sum .n { font: 500 12.5px/1 var(--mono); color: var(--panel-ink2); }
  .tb-chev { flex: none; display: grid; place-items: center; width: 34px; height: 34px; color: var(--panel-ink2); transition: transform .18s; }
  .tb-chev svg { width: 15px; height: 15px; }
  .tray-budget.open .tb-chev { transform: rotate(180deg); }

  .tb-main, .tb-acts { display: none; }
  .tray-budget.open .tb-main { display: grid; padding: 2px 14px 12px; }
  .tray-budget.open .tb-acts { display: grid; padding: 0 14px 14px; }
  .tb-line { display: none; }            /* the folded bar already says all of it */
  /* 128px is three 34px chips and their gaps: three fit whole, a fourth shows
     as a half row, which is the only honest way to say "this scrolls" */
  .tray-budget .items { max-height: 128px; overflow-y: auto; overscroll-behavior: contain; }
  .tray .ti { min-height: 34px; }
  /* Dropping one pick is the only thing this x does — Clear drops all of them —
     so it takes the same 36px box the compare tray's x takes on stacks.html.
     The negative margin spends the chip's own padding on the target instead of
     adding to it, so the chip stays 40 rather than growing to 46. */
  .tray .ti button { width: 36px; height: 36px; margin: -6px -6px -6px 0; flex: none; }

  .tb-acts { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  body .tray-budget #tbCopy { height: 40px; font-size: 14px; }
  /* Clear sits above the primary, left-aligned and hugging its own label. Two
     full-width buttons 8px apart would put the destructive one exactly where
     the thumb lands for the safe one. It keeps .btn-sm's own 34px rather than
     a height of its own: secondary is said by the position and the width. */
  body .tray-budget #tbClear { order: -1; justify-self: start; padding: 0 10px; margin-left: -10px; }
}
