/* ==========================================================================
   specs.css — the specification explorer (block prefix: sx-).
   Owned by the spec-explorer builder.

   Authored against --fg / --bg / --rule-c so the block is correct on either
   ground. Tokens only: no raw colour, font stack, duration or easing here.
   ========================================================================== */

.sx {
  --sx-row-y: var(--s-4);
  --sx-k-col: 15rem;
  --sx-toolbar-h: 0px;
  --sx-stick: var(--nav-h, 0px);
  display: block;
}

.sx[data-density='compact'] {
  --sx-row-y: var(--s-2);
}

/* --------------------------------------------------------------------------
   1. Key figures — the two-second read.
   -------------------------------------------------------------------------- */

.sx__figures {
  display: grid;
  gap: var(--s-3);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9.5rem), 1fr));
  margin-block-end: var(--s-8);
}

.sx-kf {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  min-block-size: var(--tap);
  padding: var(--s-4);
  border: var(--hairline) solid var(--rule-c);
  border-radius: var(--r-md);
  background: var(--bg-2);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out),
              transform var(--dur-2) var(--ease-out);
}

.sx-kf:hover {
  border-color: var(--fg);
  background: var(--bg);
  transform: translateY(-2px);
}

.sx-kf:active { transform: translateY(0); }

.sx-kf__cap {
  font-family: var(--font-mono);
  font-size: var(--fs-nano);
  font-weight: 500;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--fg-3);
}

.sx-kf__val {
  font-family: var(--font-mono);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  line-height: 1.15;
  color: var(--fg);
  overflow-wrap: anywhere;
}

.sx-kf[data-size='lg'] .sx-kf__val { font-size: clamp(1.5rem, 4vw, 2rem); }
.sx-kf[data-size='md'] .sx-kf__val { font-size: clamp(1.1rem, 2.6vw, 1.45rem); }
.sx-kf[data-size='sm'] .sx-kf__val { font-size: clamp(0.95rem, 2vw, 1.15rem); }

.sx-kf__src {
  margin-block-start: var(--s-1);
  font-family: var(--font-mono);
  font-size: var(--fs-nano);
  line-height: 1.5;
  color: var(--fg-2);
  overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   2. Toolbar — search, chips, density, copy. Sticky under the nav.
   -------------------------------------------------------------------------- */

.sx__toolbar {
  display: grid;
  gap: var(--s-3);
  padding-block-end: var(--s-3);
  margin-block-end: var(--s-4);
  border-block-end: var(--hairline) solid var(--rule-c);
}

.sx-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
}

/* Mobile: only the search row follows the reader. The chips scroll away so
   the sticky furniture never eats more than one row of the viewport. */
.sx-bar--search {
  position: sticky;
  top: var(--sx-stick);
  z-index: var(--z-sticky);
  padding-block: var(--s-3);
  background: var(--bg);
}

/* bleed the ground out to the gutter edges so rows do not show through.
   Only ever applied to an element that is itself positioned (sticky), so the
   pseudo-element can never escape to the band and widen the page. */
.sx-bar--search::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline: calc(var(--gutter) * -1);
  background: var(--bg);
  z-index: -1;
}

/* --- search ------------------------------------------------------------- */

.sx-search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 10rem;
  min-inline-size: 0;
  gap: var(--s-2);
  padding-inline: var(--s-3);
  min-block-size: var(--tap);
  background: var(--bg-2);
  border: var(--hairline) solid var(--rule-c);
  border-radius: var(--r-pill);
  transition: border-color var(--dur-1) var(--ease-out);
}

.sx-search:focus-within { border-color: var(--fg); }

.sx-search__icon {
  flex: none;
  inline-size: 1rem;
  block-size: 1rem;
  color: var(--fg-3);
}

.sx-search__input {
  flex: 1 1 auto;
  min-inline-size: 0;
  border: 0;
  background: none;
  outline: none;
  padding-block: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg);
}

.sx-search__input::placeholder { color: var(--fg-3); opacity: 1; }
.sx-search__input::-webkit-search-cancel-button { display: none; }

.sx-search__kbd {
  flex: none;
  padding: 0.1em 0.45em;
  border: var(--hairline) solid var(--rule-c);
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: var(--fs-nano);
  color: var(--fg-3);
}

.sx-search[data-filled='true'] .sx-search__kbd { display: none; }

.sx-search__clear {
  flex: none;
  display: none;
  place-items: center;
  inline-size: var(--tap);
  block-size: var(--tap);
  margin-inline-end: calc(var(--s-3) * -1);
  border-radius: 50%;
  color: var(--fg-2);
}

.sx-search[data-filled='true'] .sx-search__clear { display: grid; }
.sx-search__clear:hover { color: var(--fg); }

/* --- live count --------------------------------------------------------- */

.sx-count {
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.04em;
  color: var(--fg-2);
  font-variant-numeric: tabular-nums;
}

.sx-count[data-filtered='true'] { color: var(--fg); }

/* --- chips -------------------------------------------------------------- */

.sx-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  flex: 1 1 auto;
  min-inline-size: 0;
}

.sx-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-block-size: 36px;
  padding: var(--s-2) var(--s-4);
  border-radius: var(--r-pill);
  border: var(--hairline) solid var(--rule-c);
  background: transparent;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.05em;
  text-align: start;
  color: var(--fg-2);
  cursor: pointer;
  overflow-wrap: anywhere;
  transition: background-color var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out);
}

.sx-chip:hover { border-color: var(--fg); color: var(--fg); }

.sx-chip[aria-pressed='true'] {
  background: var(--fg);
  border-color: var(--fg);
  color: var(--bg);
}

.sx-chip__n {
  font-size: var(--fs-nano);
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

.sx-chip[data-empty='true'] { opacity: 0.4; }

/* --- tools cluster ------------------------------------------------------ */

.sx-tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin-inline-start: auto;
}

.sx-tool {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-block-size: 36px;
  padding: var(--s-2) var(--s-4);
  border-radius: var(--r-pill);
  border: var(--hairline) solid var(--rule-c);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.05em;
  color: var(--fg-2);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--dur-2) var(--ease-out),
              color var(--dur-2) var(--ease-out);
}

.sx-tool:hover { border-color: var(--fg); color: var(--fg); }
.sx-tool[aria-pressed='true'] {
  border-color: var(--fg);
  color: var(--fg);
  box-shadow: inset 0 0 0 1px var(--fg);
}
.sx-tool[data-done='true'] { border-color: var(--ok); color: var(--ok); }

.sx-tool__ico { inline-size: 0.9rem; block-size: 0.9rem; flex: none; }

/* --------------------------------------------------------------------------
   3. The sheet
   -------------------------------------------------------------------------- */

.sx__sheet { display: block; }

.sx-group + .sx-group { margin-block-start: var(--s-10); }

.sx-group__head {
  position: static;
  z-index: 1;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block: var(--s-3);
  margin-block-end: var(--s-1);
  background: var(--bg);
  border-block-end: var(--hairline) solid var(--fg);
  font-size: var(--fs-h4);
  font-weight: 700;
  letter-spacing: var(--ls-head);
}

.sx-group__n {
  font-family: var(--font-mono);
  font-size: var(--fs-nano);
  font-weight: 400;
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--fg-3);
  white-space: nowrap;
}

/* --- rows --------------------------------------------------------------- */

.sx-rows { display: block; }

.sx-row {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    'k copy'
    'v v';
  column-gap: var(--s-3);
  row-gap: var(--s-1);
  padding-block: var(--sx-row-y);
  border-block-end: var(--hairline) solid var(--rule-c);
  scroll-margin-block-start: calc(var(--sx-stick) + var(--sx-toolbar-h) + var(--s-6));
}

.sx-row:last-child { border-block-end: 0; }

.sx-row__k {
  grid-area: k;
  align-self: center;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-3);
  overflow-wrap: anywhere;
}

.sx-row__v {
  grid-area: v;
  margin: 0;
  min-inline-size: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.sx-row__val { display: block; }

.sx-row__items {
  display: grid;
  gap: var(--s-1);
  margin-block-start: var(--s-2);
  padding: 0;
  list-style: none;
}

.sx-row__item {
  position: relative;
  padding-inline-start: var(--s-4);
  color: var(--fg-2);
}

.sx-row__item::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.62em;
  inline-size: var(--s-2);
  block-size: 1px;
  background: var(--fg-3);
}

/* a nested continuation line ("Measuring capacity:") reads as a sub-heading */
.sx-row__item[data-lead='true'] {
  color: var(--fg);
  padding-inline-start: 0;
  margin-block-start: var(--s-1);
}
.sx-row__item[data-lead='true']::before { content: none; }

.sx-row:hover { background: color-mix(in srgb, var(--fg) 3%, transparent); }

/* --- per-row copy ------------------------------------------------------- */

.sx-copy {
  grid-area: copy;
  align-self: center;
  display: grid;
  place-items: center;
  inline-size: var(--tap);
  block-size: var(--tap);
  margin-block: calc(var(--s-2) * -1);
  border-radius: var(--r-sm);
  color: var(--fg-3);
  opacity: 0;
  transition: opacity var(--dur-1) var(--ease-out),
              color var(--dur-1) var(--ease-out);
}

.sx-copy__ico { inline-size: 1rem; block-size: 1rem; }

.sx-row:hover .sx-copy,
.sx-row:focus-within .sx-copy,
.sx-copy:focus-visible { opacity: 1; }

.sx-copy:hover { color: var(--fg); }
.sx-copy[data-done='true'] { opacity: 1; color: var(--ok); }

@media (hover: none) {
  .sx-copy { opacity: 0.55; }
}

/* --- search highlight --------------------------------------------------- */

.sx mark {
  background: var(--lcd);
  color: var(--lcd-seg);
  border-radius: 2px;
  padding-inline: 0.1em;
}

/* --- filtered-out --------------------------------------------------------
   A class, never [hidden], so the print block can simply put it back.
   ------------------------------------------------------------------------ */

.sx-is-out { display: none; }

/* --- target flash ------------------------------------------------------- */

.sx-row.is-flash {
  animation: sx-flash var(--dur-4) var(--ease-out) 1;
}

@keyframes sx-flash {
  from { background: var(--lcd); }
  to { background: transparent; }
}

/* --------------------------------------------------------------------------
   4. States: skeleton, empty, error
   -------------------------------------------------------------------------- */

.sx-skeleton { display: grid; gap: var(--s-6); }

.sx-skeleton__grid {
  display: grid;
  gap: var(--s-3);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9.5rem), 1fr));
}

.sx-bone {
  border-radius: var(--r-sm);
  background: linear-gradient(
    90deg,
    var(--bg-2) 0%,
    var(--bg-3) 45%,
    var(--bg-2) 90%
  );
  background-size: 300% 100%;
  animation: sx-shimmer var(--dur-4) linear infinite;
  block-size: 0.85rem;
}

.sx-bone--card { block-size: 5.25rem; border-radius: var(--r-md); }
.sx-bone--head { block-size: 1.35rem; inline-size: 42%; }
.sx-bone--row { block-size: 2.6rem; }
.sx-skeleton__rows { display: grid; gap: var(--s-3); margin-block-start: var(--s-4); }

@keyframes sx-shimmer {
  from { background-position: 150% 0; }
  to { background-position: -150% 0; }
}

.sx-empty {
  padding-block: var(--s-12);
  text-align: center;
  display: grid;
  gap: var(--s-4);
  justify-items: center;
}

.sx-empty__msg {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  color: var(--fg-2);
  max-inline-size: 46ch;
}

.sx-empty__term {
  color: var(--fg);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.sx-error {
  display: grid;
  gap: var(--s-3);
  justify-items: start;
  padding: var(--s-6);
  border: var(--hairline) solid var(--alert-c);
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--alert-c) 6%, transparent);
}

.sx-error__t {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  font-weight: 700;
  color: var(--alert-c);
}

.sx-error__p {
  font-size: var(--fs-small);
  color: var(--fg-2);
  max-inline-size: var(--measure);
}

/* app.js flips [data-state] on [data-requires-facts] when facts.json fails.
   The mount is emptied so only the error shows. */
[data-component='specs'][data-state='error'] [data-specs-skeleton] { display: none; }

/* --------------------------------------------------------------------------
   5. No-JS baseline (rendered inside <noscript>)
   -------------------------------------------------------------------------- */

.sx-baseline .sx-group__head { position: static; }
.sx-baseline .sx-row { grid-template-areas: 'k k' 'v v'; }

/* --------------------------------------------------------------------------
   6. Up-scaling
   -------------------------------------------------------------------------- */

@media (min-width: 48rem) {
  /* Desktop: the whole toolbar is sticky, so filters stay reachable while
     the sheet scrolls; group headers offset themselves beneath it. */
  .sx__toolbar {
    position: sticky;
    top: var(--sx-stick);
    z-index: var(--z-sticky);
    padding-block: var(--s-3);
    background: var(--bg);
  }

  .sx__toolbar::before {
    content: '';
    position: absolute;
    inset-block: 0;
    inset-inline: calc(var(--gutter) * -1);
    background: var(--bg);
    z-index: -1;
  }

  .sx-bar--search {
    position: static;
    padding-block: 0;
    background: none;
  }

  .sx-bar--search::before { content: none; }
}

@media (min-width: 48rem) {
  .sx__figures { gap: var(--s-4); margin-block-end: var(--s-10); }

  .sx-row {
    grid-template-columns: minmax(0, var(--sx-k-col)) minmax(0, 1fr) auto;
    grid-template-areas: 'k v copy';
    column-gap: var(--s-6);
    align-items: baseline;
  }

  .sx-row__k { align-self: baseline; padding-block-start: 0.15em; }
  .sx-copy { align-self: start; margin-block: calc(var(--s-2) * -1) 0; }
  .sx-baseline .sx-row { grid-template-areas: 'k v v'; }
}

@media (min-width: 62rem) {
  .sx { --sx-k-col: 17rem; }

  /* sticky group headers, offset by nav + toolbar */
  .sx-group__head {
    position: sticky;
    top: calc(var(--sx-stick) + var(--sx-toolbar-h));
  }
}

/* --------------------------------------------------------------------------
   7. Reduced motion — filtering must stay instant, never animated
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .sx-kf,
  .sx-copy,
  .sx-chip,
  .sx-tool { transition: none; }
  .sx-kf:hover { transform: none; }
  .sx-row.is-flash { animation: none; outline: 2px solid var(--signal-c); }
  .sx-bone { animation: none; }
}

/* --------------------------------------------------------------------------
   8. Print — the complete sheet, filters ignored
   -------------------------------------------------------------------------- */

@media print {
  .sx__toolbar,
  .sx-copy,
  .sx-empty,
  .sx-skeleton { display: none !important; }

  /* every filtered-away row and group comes back */
  .sx-is-out { display: revert !important; }

  .sx { --sx-row-y: var(--s-2); }

  .sx__figures {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    break-inside: avoid;
  }

  .sx-kf { border-color: #999; background: none; }

  .sx-group { break-inside: auto; }
  .sx-group + .sx-group { margin-block-start: var(--s-6); }

  .sx-group__head {
    position: static !important;
    break-after: avoid;
    border-block-end-width: 2px;
  }

  .sx-row {
    break-inside: avoid;
    grid-template-columns: minmax(0, 14rem) minmax(0, 1fr);
    grid-template-areas: 'k v';
  }

  .sx mark { background: none; font-weight: 700; text-decoration: underline; }
}
