/* Stilyagi · page styles for docs. Extracted from the source site's inline <style>. */

.docs-layout {
  max-width: 1320px;
  margin: 0 auto;
  padding: calc(var(--unit) * 4);
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: calc(var(--unit) * 5);
}
.side-toc {
  position: sticky;
  top: 100px;
  align-self: start;
  border-top: var(--rule-weight-2) solid var(--ink);
  padding-top: 14px;
}
.side-toc a {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 6px 0;
  border-bottom: 1px dashed rgba(15, 15, 15, 0.2);
  text-decoration: none;
}
.side-toc a:hover {
  color: var(--accent-text);
}
.side-toc a.active {
  color: var(--accent-text);
  font-weight: 700;
}

.cat-head {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 20px;
  align-items: end;
  margin-bottom: 18px;
  border-bottom: var(--rule-weight-2) solid var(--ink);
  padding-bottom: 14px;
}
.cat-head h2 {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: 2.4rem;
  line-height: 0.95;
  margin: 0;
}
.cat-head h2 .red {
  color: var(--accent-text);
}
.cat-head .counts {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: right;
  line-height: 1.7;
}

.filter-bar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  /* The bar and the table are the only children of #catalogue, so sticking
     the bar to the section keeps it in reach for exactly as long as the
     table is on screen and releases it at the section's end.  The masthead
     runs 74–90px tall depending on how the brand imprint wraps: anchoring
     masthead is 74px tall at the narrowest desktop and grows with the brand
     type to a 90px ceiling around 1920px, so the anchor tracks it rather than
     stepping at a breakpoint: the wash always meets the masthead with no gap,
     and the padding holds the controls a constant 20px clear of its rule.
     (Below 460px the imprint wraps to two lines and the masthead outgrows the
     floor; the box simply tucks behind it, which is equally gapless.) */
  position: sticky;
  top: clamp(73px, 61px + 1.6vw, 89px);
  z-index: 5;
  padding: 20px 0 18px;
  background: rgba(239, 228, 206, 0.96);
  backdrop-filter: blur(8px);
  border-bottom: var(--rule-weight) solid var(--ink);
  align-items: center;
}
.filter-bar .lbl {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-right: 6px;
}
.filter-chip {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 5px 10px;
  border: 1px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
  font-weight: 600;
}
.filter-chip.active {
  background: var(--press-red);
  color: var(--paper);
  border-color: var(--press-red);
}
.filter-chip.ns-md.active {
  background: var(--signal-sage-solid);
  border-color: var(--signal-sage-solid);
  color: var(--paper);
}
.filter-chip.ns-pydoc.active {
  background: var(--rust-patina);
  border-color: var(--rust-patina);
  color: var(--paper);
}
.filter-chip.ns-rsdoc.active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
.filter-chip.ns-pun.active {
  background: var(--jazz-magenta-solid);
  border-color: var(--jazz-magenta-solid);
  color: var(--paper);
}
.filter-chip.ns-gram.active {
  background: var(--jazz-cyan);
  border-color: var(--jazz-cyan);
  color: var(--ink);
}
.filter-chip.ns-spell.active {
  background: var(--jazz-ochre);
  border-color: var(--jazz-ochre);
  color: var(--ink);
}
/* The chip row is the wide-viewport control; the select takes over below.
   Exactly one of the pair is ever displayed — see the 1280px rule. */
.filter-select {
  display: none;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 600;
  padding: 5px 10px;
  border: 1px solid var(--ink);
  background: var(--paper);
  color: var(--ink);
  cursor: pointer;
}
.filter-select:focus-visible {
  outline: 2px solid var(--press-red);
  outline-offset: 1px;
}
.search-box {
  margin-left: auto;
  min-width: 240px;
  padding: 6px 10px;
  border: 1px solid var(--ink);
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.85rem;
}
.search-box:focus {
  outline: 2px solid var(--press-red);
  outline-offset: 1px;
}

.rules-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 6px;
}
.rules-table th {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: left;
  border-bottom: var(--rule-weight-2) solid var(--ink);
  padding: 10px 10px 8px;
}
.rules-table td {
  font-family: var(--font-editorial);
  font-size: 1rem;
  line-height: 1.45;
  padding: 12px 10px;
  border-bottom: 1px dashed rgba(15, 15, 15, 0.2);
  vertical-align: top;
}
.rules-table tr:hover td {
  background: var(--paper-shade);
}
.rules-table .id {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
}
.rules-table .ns {
  display: inline-block;
  padding: 2px 7px 1px;
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.12em;
  font-weight: 700;
  margin-right: 6px;
}
.ns-md {
  background: var(--signal-sage-solid);
  color: var(--paper);
}
.ns-pydoc {
  background: var(--rust-patina);
  color: var(--paper);
}
.ns-rsdoc {
  background: var(--ink);
  color: var(--paper);
}
.ns-pun {
  background: var(--jazz-magenta-solid);
  color: var(--paper);
}
.ns-gram {
  background: var(--jazz-cyan);
  color: var(--ink);
}
.ns-spell {
  background: var(--jazz-ochre);
  color: var(--ink);
}
.sev {
  display: inline-block;
  padding: 2px 6px 1px;
  font-family: var(--font-sans);
  font-size: 0.65rem;
  letter-spacing: 0.12em;
  font-weight: 700;
  text-transform: uppercase;
}
.sev-err {
  background: var(--press-red);
  color: var(--paper);
}
.sev-warn {
  background: var(--jazz-ochre);
  color: var(--ink);
}
.sev-info {
  background: var(--paper-shade);
  color: var(--ink);
  border: 1px solid var(--ink);
}
.fix {
  font-family: var(--font-sans);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 600;
}
.fix.safe {
  color: var(--signal-sage);
}
.fix.unsafe {
  color: var(--accent-text);
}
.empty-row td {
  text-align: center;
  padding: 40px;
  color: var(--ink-soft);
  font-style: italic;
}

/* Config & suppressions */
.config-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: calc(var(--unit) * 4);
  margin-top: calc(var(--unit) * 4);
}
.config-grid h3 {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: 1.4rem;
  margin: 0 0 12px;
}
.config-grid h3 .red {
  color: var(--accent-text);
}
.config-grid p {
  font-family: var(--font-editorial);
  font-size: 1.05rem;
  line-height: 1.55;
}
.config-grid pre {
  background: var(--ink);
  color: var(--paper);
  padding: 18px 20px;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  line-height: 1.6;
  overflow: auto;
  border-left: 4px solid var(--press-red);
}
.config-grid pre .k {
  color: var(--jazz-ochre);
}
.config-grid pre .s {
  color: var(--signal-sage);
}
.config-grid pre .c {
  color: #9d9d9d;
  font-style: italic;
}
.config-grid pre .n {
  color: var(--jazz-cyan);
}

.suppress {
  margin-top: calc(var(--unit) * 4);
}
.suppress h3 {
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: 1.4rem;
  margin: 0 0 14px;
}
.suppress .tabs {
  display: flex;
  gap: 0;
  border-bottom: var(--rule-weight-2) solid var(--ink);
  margin-bottom: 14px;
}
.suppress .tab {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 10px 18px;
  cursor: pointer;
  background: transparent;
  border: 0;
  color: var(--ink-soft);
  font-weight: 700;
  border-bottom: 3px solid transparent;
  margin-bottom: -3px;
}
.suppress .tab.active {
  color: var(--accent-text);
  border-bottom-color: var(--press-red);
  background: var(--paper-shade);
}
.suppress pre {
  background: var(--paper-shade);
  color: var(--ink);
  padding: 18px 22px;
  font-family: var(--font-mono);
  font-size: 0.9rem;
  line-height: 1.65;
  border-left: 4px solid var(--ink);
  overflow: auto;
}
.suppress pre .com {
  color: var(--accent-text);
  font-weight: 700;
}
.suppress pre .dim {
  color: var(--ink-soft);
}

/* Testing sandbox — reuses the config section's two-column prose/code pairing,
   so it only needs the status line and the inline code treatment of its own. */
/* The stamp is rotated, so it sits in its own flex column rather than in the
   text flow — inline, the second line of prose runs under its lower corner. */
.sandbox .sandbox-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--unit) * 2);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  line-height: 1.7;
  color: var(--ink-soft);
  margin-top: calc(var(--unit) * 2);
  /* Clearance for the corners the rotation throws outside the layout box. */
  padding-block: 8px;
}
.sandbox .sandbox-status .stamp {
  flex: none;
}
.sandbox .sandbox-status span:last-child {
  max-width: 72ch;
}
.sandbox .config-grid code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--paper-shade);
  padding: 1px 4px;
  /* Otherwise flag and dotted-path names break at their own punctuation —
     "--isolated" splits after the dashes on a phone.  The longest token here
     is sixteen characters, so holding them whole never overflows. */
  white-space: nowrap;
}
/* The code blocks carry Python, not TOML, but they wear the same palette as
   the configuration example so the page keeps one voice for machine text. */
.sandbox .config-grid pre code {
  background: transparent;
  padding: 0;
}

/* Colophon */
.colophon-sec {
  background: var(--ink);
  color: var(--paper);
  padding: calc(var(--unit) * 6) 0;
  margin-top: calc(var(--unit) * 6);
  position: relative;
  overflow: hidden;
}
/* The halftone motif in .halftone prints dark dots for paper grounds; this
   panel is ink-on-ink, so it takes the same gradient in paper. */
.colophon-sec::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    rgba(239, 228, 206, 0.85) 1px,
    transparent 1.4px
  );
  background-size: 9px 9px;
  opacity: 0.08;
}
.colophon-inner {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 calc(var(--unit) * 4);
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: calc(var(--unit) * 6);
}
.colophon-inner h2 {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 3.6rem;
  line-height: 0.9;
  text-transform: uppercase;
  margin: 0 0 18px;
}
.colophon-inner h2 .red {
  color: var(--accent-text);
}
.colophon-inner p {
  font-family: var(--font-editorial);
  font-size: 1.15rem;
  line-height: 1.6;
  max-width: 58ch;
  color: var(--paper);
}
.colophon-inner p + p {
  text-indent: 1.8em;
  margin-top: 10px;
}
.colophon-inner em {
  font-style: italic;
  color: var(--jazz-ochre);
}
.credits {
  border-left: var(--rule-weight-2) solid var(--press-red);
  padding-left: calc(var(--unit) * 3);
}
.credits .row {
  padding: 10px 0;
  border-bottom: 1px dashed rgba(248, 243, 230, 0.25);
  font-family: var(--font-sans);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 10px;
}
.credits .row b {
  color: var(--accent-text);
  font-weight: 700;
}
.credits .row:last-child {
  border-bottom: 0;
}
.agitprop-stamp {
  position: absolute;
  right: calc(var(--unit) * 4);
  top: calc(var(--unit) * 2);
  transform: rotate(-4deg);
  border: 3px double var(--press-red);
  color: var(--accent-text);
  padding: 6px 14px;
  font-family: var(--font-display);
  font-weight: 900;
  text-transform: uppercase;
  font-size: 0.95rem;
  letter-spacing: 0.1em;
  background: rgba(0, 0, 0, 0.35);
}

/* Seven chips plus a search box stop fitting on one line well before the
   layout collapses, and a wrapped chip row makes the sticky bar tall enough
   to eat the viewport.  Below this width the native select does the job in
   one line. */
@media (width <= 1280px) {
  .filter-chip {
    display: none;
  }
  .filter-select {
    display: inline-block;
  }
}

/* Each autofix cell carries its own "autofix" label for the stacked layout
   below, where the column headers are hidden.  Wide enough for the headers to
   show, the label would only repeat them. */
.rules-table .col-label {
  display: none;
}

/* The namespace tally cannot hold its own column beside the heading at phone
   widths — it is a single unbreakable line, so it pushes the page sideways.
   Stack it under the heading and let it read left to right. */
@media (width < 680px) {
  .cat-head {
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
  }
  .cat-head .counts {
    text-align: left;
  }
}

/* Stacked: the rule id keeps a column of its own down the left, while the
   title, severity, and autofix stack in the column beside it — severity and
   autofix sharing the row underneath the description.  The row becomes a
   grid, which costs the table its implicit ARIA roles, so the markup states
   them explicitly. */
@media (width < 680px) {
  .rules-table,
  .rules-table tbody,
  .rules-table td {
    display: block;
  }
  .rules-table thead {
    display: none;
  }
  .rules-table tr {
    display: grid;
    grid-template-columns: auto auto 1fr;
    gap: 4px 12px;
    padding: 12px 0;
    border-bottom: 1px dashed rgba(15, 15, 15, 0.2);
  }
  /* A grid display would otherwise beat the UA rule that hides filtered-out
     rows, so restate it at matching specificity. */
  .rules-table tr[hidden] {
    display: none;
  }
  .rules-table td {
    padding: 0;
    border-bottom: 0;
  }
  .rules-table td.id {
    grid-area: 1 / 1 / 3 / 2;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .rules-table td:nth-child(2) {
    grid-area: 1 / 2 / 2 / 4;
  }
  .rules-table td:nth-child(3) {
    grid-area: 2 / 2 / 3 / 3;
    align-self: center;
  }
  .rules-table td:nth-child(4) {
    grid-area: 2 / 3 / 3 / 4;
    align-self: center;
    justify-self: start;
  }
  /* The column headers are gone, and "safe" on its own does not say what it
     is safe to do, so each cell carries its own label. */
  .rules-table .col-label {
    display: inline;
    color: var(--ink-soft);
  }
  .rules-table .empty-row td {
    grid-area: auto / 1 / auto / -1;
  }
}

@media (max-width: 900px) {
  .docs-layout {
    /* A bare 1fr takes its minimum from the content, which the config TOML
       block drags out to 2700px; the pre already scrolls, so cap the track
       and let it. */
    grid-template-columns: minmax(0, 1fr);
  }
  .side-toc {
    position: static;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }
  .side-toc a {
    border: 1px solid var(--ink);
    padding: 6px 10px;
  }
  .config-grid,
  .colophon-inner {
    grid-template-columns: 1fr;
  }
}
