/* Every colour the site uses, so the dark palette below can swap them all. */
:root {
  color-scheme: light;
  /* A soft blue page, so the white cards and tables stand off it. */
  --bg: #ebf1f8;
  --card: #ffffff;
  --subtle: #f1f5fa;
  --hover: #f6f9fc;
  --text: #18181b;
  --muted: #6b6b72;
  --border: #d7e0ec;
  --border-strong: #c1cddc;
  --accent: #0e6c78;
  --accent-soft: #e7f2f3;
  --on-accent: #ffffff;
  --ok-bg: #e3f6e8;
  --ok-fg: #17663a;
  --fail-bg: #fce8e8;
  --fail-fg: #9b1c1c;
  --code-bg: #0d1117;
  --code-head: #161b22;
  --code-fg: #e6edf3;
  --code-muted: #8b949e;
  --tip-bg: #18181b;
  --tip-fg: #f4f4f5;
  --dot: rgba(40, 70, 120, 0.17);
  --radius: 10px;
  --shadow: 0 1px 2px rgba(24, 24, 27, 0.04);
  --pop-shadow: 0 10px 30px rgba(24, 24, 27, 0.12), 0 2px 6px rgba(24, 24, 27, 0.06);
  /* The reader's own system fonts: Segoe UI on Windows, San Francisco on a
     Mac, Roboto on Android. Nothing is downloaded. Cascadia Mono rather than
     Cascadia Code, whose ligatures would redraw operators such as >= in code. */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, "Cascadia Mono", Consolas, "Liberation Mono", monospace;
}
/* Set by the toggle in the nav; the head script applies it before paint. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0e0f11;
  --card: #15161a;
  --subtle: #1b1c21;
  --hover: #1a1b20;
  --text: #ececef;
  --muted: #9a9aa3;
  --border: #26272d;
  --border-strong: #34353c;
  --accent: #5cc3cf;
  --accent-soft: rgba(92, 195, 207, 0.12);
  --on-accent: #0e0f11;
  --ok-bg: rgba(52, 199, 89, 0.14);
  --ok-fg: #7ee2a0;
  --fail-bg: rgba(248, 81, 73, 0.15);
  --fail-fg: #ff9b95;
  --code-bg: #0a0b0d;
  --code-head: #121317;
  --tip-bg: #ececef;
  --tip-fg: #15161a;
  --dot: rgba(236, 236, 239, 0.1);
  --shadow: none;
  --pop-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  color: var(--text);
  background: var(--bg);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
h1, h2, h3 { letter-spacing: -0.015em; }
::selection { background: var(--accent-soft); color: var(--text); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Header / nav ---------- */
/* No banner: the header shares the page's colour, with a faint dot grid
   in its top right corner that fades out before the content. */
header {
  position: relative;
  isolation: isolate;
  border-bottom: 1px solid var(--border);
}
header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image: radial-gradient(var(--dot) 1px, transparent 1.4px);
  background-size: 18px 18px;
  -webkit-mask-image: radial-gradient(ellipse 60% 120% at 100% 0%, #000 0%, transparent 75%);
  mask-image: radial-gradient(ellipse 60% 120% at 100% 0%, #000 0%, transparent 75%);
}
nav {
  display: flex;
  align-items: center;
  gap: 4px;
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 20px;
  flex-wrap: wrap;
}
nav a {
  color: var(--muted);
  padding: 15px 12px 13px;
  font-size: 0.92rem;
  font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.15s ease, border-color 0.15s ease;
}
nav a:hover { color: var(--text); text-decoration: none; }
/* The current page is underlined where the nav meets the title's rule. */
nav a.active { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }
nav .brand {
  font-weight: 700;
  font-size: 1.05rem;
  margin-right: 14px;
  color: var(--text);
}
nav .spacer { flex: 1; }
nav .gh {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  padding: 5px 13px;
  margin-left: 8px;
  margin-bottom: 0;
  background: var(--card);
  color: var(--text);
  font-size: 0.84rem;
}
nav .gh:hover { border-color: var(--text); text-decoration: none; }
.github-icon { width: 16px; height: 16px; flex: 0 0 auto; }
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 31px;
  height: 31px;
  margin-left: 8px;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--card);
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.theme-toggle:hover { color: var(--text); border-color: var(--text); }
.theme-toggle svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* The icon shows the theme a click switches to. */
.theme-toggle .icon-sun, :root[data-theme="dark"] .theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: block; }
html:not(.js) .theme-toggle { display: none; }

/* ---------- Hero ---------- */
.hero {
  max-width: 1100px;
  margin: 0 auto;
  padding: 52px 20px 36px;
  /* Every page draws the same rule between the nav and its title. */
  border-top: 1px solid var(--border);
}
.hero h1 { margin: 0 0 10px; font-size: 2.6rem; font-weight: 700; line-height: 1.1; letter-spacing: -0.035em; }
.hero p { margin: 0; color: var(--muted); font-size: 1.05rem; text-wrap: balance; }
/* The letters that spell DCP. */
.hero p strong { color: var(--text); font-weight: 600; }
/* The stone sits whole in the hero's right corner, clear of the rule
   below; the title and tagline keep clear of it. */
.hero.has-logo { position: relative; }
.hero.has-logo h1, .hero.has-logo p { padding-right: 200px; }
.hero-logo {
  position: absolute;
  right: 36px;
  bottom: 4px;
  width: auto;
  height: auto;
  max-height: calc(100% - 10px);
  max-width: 160px;
}
:root[data-theme="dark"] .hero-logo { filter: brightness(0.9); }
.problem-hero {
  padding-top: 30px;
  padding-bottom: 26px;
}
.problem-hero h1 { font-size: 2rem; font-weight: 700; letter-spacing: -0.03em; margin: 0; }
/* A problem's name is its identifier, so it is set like one. */
.problem-hero h1.problem-id { font-family: var(--mono); font-size: 1.85rem; font-weight: 600; }
.problem-hero .hero-note { margin-top: 8px; font-size: 0.92rem; }
.problem-hero .crumb { display: inline-block; margin-bottom: 10px; color: var(--muted); font-size: 0.86rem; }
.problem-hero .crumb:hover { color: var(--text); text-decoration: none; }
.problem-hero .hero-note a { color: var(--text); text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px; }
.problem-hero .hero-note a:hover { text-decoration-color: var(--accent); }
.count-note { color: var(--muted); font-weight: 400; }

/* ---------- Layout ---------- */
main { max-width: 1100px; margin: 0 auto; padding: 32px 20px 72px; }

/* ---------- Filters ---------- */
.controls {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}
.controls input[type="search"] {
  flex: 1;
  min-width: 220px;
  padding: 9px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--card);
  color: var(--text);
  font-size: 0.95rem;
  font-family: inherit;
}
.controls input[type="search"]::placeholder { color: var(--muted); opacity: 0.8; }
.controls select {
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card);
  font-size: 0.9rem;
  font-family: inherit;
  color: var(--text);
}
.controls select:focus, .controls input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.result-count { color: var(--muted); font-size: 0.9rem; margin: 0 0 12px; }

/* ---------- Badges ---------- */
.badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
}
.badge.plain {
  background: var(--muted);
}
.badge.outline {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
}

/* ---------- Sections ---------- */
.section { margin-bottom: 40px; }
.section h2 {
  font-size: 1.2rem;
  font-weight: 600;
  margin: 0 0 16px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}

/* ---------- Matrix ---------- */
.matrix-wrap { overflow-x: auto; scrollbar-width: thin; }
table.matrix {
  border-collapse: collapse;
  font-size: 0.85rem;
}
table.matrix th, table.matrix td {
  border: 1px solid var(--border);
  padding: 6px 10px;
  text-align: center;
}
table.matrix th { background: var(--card); font-weight: 600; }
table.matrix td.cell-id { text-align: left; font-family: var(--mono); font-size: 0.8rem; }
table.matrix td.cell-id a { color: var(--text); }
table.matrix td.cell-cat { text-align: left; }
table.matrix td.ok { background: var(--ok-bg); color: var(--ok-fg); font-weight: 600; }
table.matrix td.skip { color: var(--muted); }
table.matrix td.fail { background: var(--fail-bg); color: var(--fail-fg); font-weight: 600; }

/* ---------- Problem page ---------- */
.card-box {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px 22px;
  box-shadow: var(--shadow);
  margin-bottom: 18px;
}
.card-box h3 { margin: 0 0 10px; font-size: 0.95rem; font-weight: 600; }

/* ---------- Markdown description ---------- */
.md-desc { margin: 0; font-size: 0.97rem; line-height: 1.65; }
.md-desc p:first-child { margin-top: 0; }
.md-desc p:last-child { margin-bottom: 0; }
.md-desc ul, .md-desc ol { padding-left: 22px; margin: 8px 0; }
.md-desc h1, .md-desc h2, .md-desc h3, .md-desc h4 { margin: 14px 0 8px; }
.md-desc h3, .md-desc h4 { font-size: 1.05rem; }
.md-desc code {
  background: var(--subtle);
  border: 1px solid var(--border);
  padding: 1px 6px;
  border-radius: 5px;
  font-family: var(--mono);
  font-size: 0.85em;
}
.md-desc pre {
  background: var(--code-bg);
  color: var(--code-fg);
  color-scheme: dark;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
  padding: 14px;
  border-radius: 8px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 0.85rem;
  line-height: 1.5;
}
.md-desc pre code { background: none; padding: 0; color: inherit; }
.md-desc blockquote {
  margin: 8px 0;
  padding: 2px 14px;
  border-left: 3px solid var(--border);
  color: var(--muted);
}

.provenance dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 18px;
  margin: 0;
  font-size: 0.92rem;
}
.provenance dt { color: var(--muted); font-weight: 600; }
.provenance dd { margin: 0; word-break: break-word; }

/* ---------- Tabs ---------- */
.tab-bar { display: flex; gap: 6px; border-bottom: 1px solid var(--border); margin-bottom: 0; flex-wrap: wrap; }
.tab-btn { white-space: nowrap; }
.tab-btn {
  border: none;
  background: transparent;
  padding: 10px 16px;
  font-size: 0.95rem;
  font-family: inherit;
  color: var(--muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.tab-btn:hover { color: var(--text); }
.tab-btn.active { color: var(--accent); font-weight: 600; border-bottom-color: var(--accent); }
/* ---------- Pickers: instances and models ---------- */
/* One look for every "pick one of these": pills, the chosen one filled. */
.tab-bar.picker { border-bottom: 0; gap: 6px; }
.tab-btn.pick {
  margin: 0;
  padding: 4px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--card);
  color: var(--text);
  font-size: 0.86rem;
  white-space: nowrap;
}
.tab-btn.pick:hover { border-color: var(--text); color: var(--text); }
/* The chosen pill is filled with ink, so colour stays for links and results. */
.tab-btn.pick.active { background: var(--text); border-color: var(--text); color: var(--bg); font-weight: 500; }
.picker-group > .tab-bar .tab-btn.pick { min-width: 36px; font-variant-numeric: tabular-nums; }
.picker-note { margin: 10px 0 12px; font-size: 0.85rem; }
/* The chosen instance sits in the box itself, not in a second card. */
.picker-group > .tab-pane { padding: 0; border: 0; box-shadow: none; background: none; border-radius: 0; }
.instances-box pre.code-block { max-height: 420px; overflow: auto; }
.instances-box .tab-group .tab-group .tab-pane { padding: 14px 16px; }

.model-picker { flex-direction: column; gap: 8px; margin-bottom: 14px; }
.picker-row { display: flex; align-items: flex-start; gap: 12px; }
/* A rule sets the reference model apart from the generated ones below it. */
.reference-row { border-bottom: 1px solid var(--border); padding-bottom: 10px; }
/* Paradigm abbreviations keep their case: MaxSAT, not MAXSAT. */
.picker-label {
  flex: 0 0 84px;
  padding-top: 5px;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 600;
}
.picker-label[title] { cursor: help; }
.picker-chips { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.model-group > .tab-pane { border-top: 1px solid var(--border); border-radius: var(--radius); }
/* Models the catalogue's filters hide, and the paradigm rows left empty. */
.model-picker [hidden] { display: none; }
.binding-bar [hidden] { display: none; }

/* The catalogue's model filters, carried to a problem page: one chip each,
   its × removing it. Quiet beside the model pills, which stay the choice. */
.model-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: 0 0 14px; font-size: 0.82rem; }
.model-filters[hidden] { display: none; }
.filter-label { color: var(--muted); font-weight: 600; margin-right: 2px; }
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 6px 2px 10px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.filter-chip-group { color: var(--muted); }
.filter-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  color: var(--accent);
  font-size: 0.95rem;
  line-height: 1;
}
.filter-chip:hover .filter-chip-x, .filter-chip:focus-visible .filter-chip-x { background: var(--accent); color: var(--bg); }
.filter-clear { font-size: inherit; }
.filter-count { margin-left: auto; color: var(--muted); }
.filter-empty { flex-basis: 100%; margin: 4px 0 0; color: var(--muted); }
/* A solver's models in several languages: tabs inside its pane, not a second card. */
.binding-group { margin-top: 0; }
.binding-bar { margin-bottom: 16px; }
.binding-group > .tab-pane { padding: 0; border: 0; box-shadow: none; background: none; border-radius: 0; }

/* The reference model's sources: links named by site and page, citations as written. */
.source-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; font-size: 0.92rem; }
.source-list li { overflow-wrap: anywhere; }

/* "<- -> switch models", bottom right, while the Models section is on screen. */
.key-hint {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 6px 7px 12px;
  border-radius: 999px;
  background: var(--tip-bg);
  color: var(--tip-fg);
  font-size: 0.85rem;
  box-shadow: var(--pop-shadow);
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.key-hint.shown { opacity: 1; transform: none; pointer-events: auto; }
.key-hint kbd {
  padding: 0 6px;
  border: 1px solid color-mix(in srgb, var(--tip-fg) 28%, transparent);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--tip-fg) 10%, transparent);
  font-family: var(--mono);
  font-size: 0.8rem;
}
.key-hint span { margin: 0 4px 0 2px; }
.key-hint button { border: 0; padding: 0 6px; background: none; color: inherit; opacity: 0.6; font-size: 1.05rem; line-height: 1; cursor: pointer; }
.key-hint button:hover { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .key-hint { transition: none; } }

/* A generated model's metadata and evaluation, side by side. */
.model-info {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: 16px;
  align-items: start;
  margin-bottom: 18px;
}
.model-info .card-box { margin: 0; }
.eval-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; margin-bottom: 10px; }
.eval-head h3 { margin: 0; }
.eval-head .eval-note { flex-basis: 100%; }
.eval-summary { margin: 0 0 8px; font-size: 0.92rem; }
.eval-pills { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 8px; }
.eval-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 26px;
  height: 26px;
  padding: 0 6px;
  border-radius: 6px;
  font-size: 0.78rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: default;
}
.eval-pill.ok { background: var(--ok-bg); color: var(--ok-fg); }
.eval-pill.skip { background: var(--subtle); color: var(--muted); }
.eval-pill.fail { background: var(--fail-bg); color: var(--fail-fg); }
.eval-note { margin: 0 0 8px; color: var(--muted); font-size: 0.84rem; }
.eval-details > summary { cursor: pointer; color: var(--accent); font-size: 0.88rem; }
.eval-details[open] > summary { margin-bottom: 8px; }
@media (max-width: 860px) {
  .model-info { grid-template-columns: minmax(0, 1fr); }
}

.tab-pane {
  display: none;
  padding: 18px 20px;
  background: var(--card);
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 var(--radius) var(--radius);
  box-shadow: var(--shadow);
}
.tab-pane.active { display: block; }

/* ---------- Copy buttons ---------- */
.code-head button.copied { background: #16a34a; color: #fff; }

/* ---------- Code ---------- */
pre.code-block {
  background: var(--code-bg);
  color: var(--code-fg);
  padding: 16px 18px;
  border-radius: var(--radius);
  /* A thin dark scrollbar for a long line, not the light default. */
  color-scheme: dark;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 0.85rem;
  line-height: 1.5;
  margin: 0;
}
/* highlight.js makes the code element scroll; the block scrolls instead, so
   its thin scrollbar sits on the bottom edge. */
pre.code-block code { font-family: inherit; background: none; padding: 0; overflow: visible; }
/* Browsers without scrollbar-color (Safari) style it here. */
pre.code-block::-webkit-scrollbar { width: 8px; height: 8px; }
pre.code-block::-webkit-scrollbar-track, pre.code-block::-webkit-scrollbar-corner { background: transparent; }
pre.code-block::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); border-radius: 8px; }
pre.code-block::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.32); }
.code-head + pre.code-block { border-radius: 0 0 var(--radius) var(--radius); }
.code-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--code-head);
  border-radius: var(--radius) var(--radius) 0 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  padding: 8px 14px;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--code-muted);
}
.code-head button {
  background: rgba(255, 255, 255, 0.08);
  color: var(--code-fg);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  padding: 4px 12px;
  font-size: 0.78rem;
  cursor: pointer;
  font-family: var(--font);
}
.code-head button:hover { background: rgba(255, 255, 255, 0.16); }
.code-actions { display: flex; align-items: center; gap: 6px; }
.code-link { color: var(--code-muted); font-family: var(--font); font-size: 0.78rem; padding: 4px 8px; border-radius: 6px; }
.code-link::after { content: " \2197"; }
.code-link:hover { background: rgba(255, 255, 255, 0.08); color: var(--code-fg); text-decoration: none; }

.chip {
  display: inline-block;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 6px;
  padding: 2px 10px;
  font-family: var(--mono);
  font-size: 0.8rem;
  margin: 0 6px 6px 0;
}
.chip-row { margin-bottom: 8px; }

/* ---------- Instances section ---------- */
details.instances-box > summary {
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  list-style: none;
}
details.instances-box > summary::-webkit-details-marker { display: none; }
details.instances-box > summary::before {
  content: "▶";
  font-size: 0.62rem;
  color: var(--muted);
  transition: transform 0.15s ease;
}
details.instances-box[open] > summary::before { transform: rotate(90deg); }
details.instances-box > summary h3 { margin: 0; }
details.instances-box[open] > summary { margin-bottom: 14px; }

.pager { display: flex; justify-content: space-between; gap: 10px; margin-top: 30px; }
.pager .btn { max-width: 48%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--mono); font-size: 0.84rem; }

/* ---------- Page sections ---------- */
.page-section { margin-bottom: 22px; }
.page-section > h2 {
  font-size: 1.2rem;
  font-weight: 600;
  margin: 0 0 16px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}

.tab-group .tab-group { margin-top: 4px; }

.btn {
  display: inline-block;
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  padding: 8px 14px;
  font-size: 0.9rem;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.btn:hover { border-color: var(--text); color: var(--text); text-decoration: none; }

/* ---------- Tables ---------- */

/* Rows split by hairlines only. The table carries the background and the
   rounded edge; the corner cells round with it. */
table.plain {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-size: 0.92rem;
}
table.plain th, table.plain td {
  border-bottom: 1px solid var(--border);
  padding: 10px 14px;
  text-align: left;
}
table.plain thead th:first-child { border-top-left-radius: var(--radius); }
table.plain thead th:last-child { border-top-right-radius: var(--radius); }
table.plain > tbody:last-child > tr:last-child > td { border-bottom: 0; }
table.plain > tbody:last-child > tr:last-child > td:first-child { border-bottom-left-radius: var(--radius); }
table.plain > tbody:last-child > tr:last-child > td:last-child { border-bottom-right-radius: var(--radius); }

/* ---------- Catalogue controls and list view ---------- */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.controls {
  align-items: flex-end;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px;
  box-shadow: var(--shadow);
}
.controls label { display: flex; flex-direction: column; gap: 4px; }
.controls label > span {
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.controls .search-field { flex: 1 1 220px; }
.controls .search-field input { width: 100%; min-width: 0; }
.filter-menu { position: relative; flex: 1 1 140px; min-width: 0; }
.filter-trigger {
  width: 100%;
  min-height: 39px;
  padding: 9px 30px 9px 11px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: var(--card);
  color: var(--text);
  font: inherit;
  font-size: 0.9rem;
  text-align: left;
  transition: border-color 0.15s ease;
  cursor: pointer;
  position: relative;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.filter-trigger::after {
  content: "⌄";
  position: absolute;
  right: 11px;
  color: var(--muted);
}
.filter-trigger:hover { border-color: var(--muted); }
.filter-menu.open .filter-trigger { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.filter-trigger.has-value { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 600; }
.filter-options {
  display: none;
  position: absolute;
  z-index: 5;
  top: calc(100% + 6px);
  left: 0;
  min-width: 100%;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card);
  box-shadow: var(--pop-shadow);
}
.filter-menu.open .filter-options { display: grid; gap: 2px; }
.filter-options label {
  display: flex;
  align-items: center;
  flex-direction: row;
  gap: 8px;
  min-height: 32px;
  padding: 4px 6px;
  border-radius: 6px;
  white-space: nowrap;
  cursor: pointer;
  font-size: 0.88rem;
}
.filter-options label:hover { background: var(--hover); }
.filter-options input { accent-color: var(--accent); }
.reset-btn {
  align-self: flex-end;
  min-height: 39px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  color: var(--muted);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}
.reset-btn:hover:not(:disabled) { border-color: var(--text); color: var(--text); }
.reset-btn:disabled { opacity: 0.5; cursor: default; }
.list-sort {
  border: none;
  padding: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.list-sort:hover { color: var(--accent); }
.problem-section { margin: 0 0 28px; }
/* One tab per problem type, the match count on the right. */
.type-tabs {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin: 0 0 14px;
  border-bottom: 1px solid var(--border);
}
.type-tab-list { display: flex; }
.type-tab {
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding: 10px 16px;
  background: none;
  color: var(--muted);
  font: inherit;
  font-size: 1.05rem;
  font-weight: 600;
  cursor: pointer;
}
.type-tab:hover { color: var(--text); }
.type-tab.active { color: var(--text); border-bottom-color: var(--accent); }
.tab-count {
  margin-left: 4px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--subtle);
  color: var(--muted);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}
.type-tab.active .tab-count { background: var(--text); color: var(--bg); }
.type-tabs .result-count { margin: 0; }
.results-side { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 14px; margin: 0 0 8px; }
/* With solvers picked: their problems, or the ones they have no model for. */
.mode-switch { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--card); }
.mode-switch[hidden] { display: none; }
.mode-btn { border: 0; padding: 5px 10px; background: none; color: var(--muted); font: inherit; font-size: 0.85rem; cursor: pointer; }
.mode-btn + .mode-btn { border-left: 1px solid var(--border); }
.mode-btn:hover { color: var(--text); }
.mode-btn.active { background: var(--subtle); color: var(--text); font-weight: 600; }
.mode-btn .tab-count { margin-left: 2px; }
/* On a phone the switch and count wrap below the tabs, so the line runs
   under the tabs themselves rather than under everything. */
@media (max-width: 640px) {
  .type-tabs { border-bottom: 0; }
  .type-tab-list { flex-basis: 100%; border-bottom: 1px solid var(--border); }
  .results-side { margin-top: 6px; }
}
.empty-state { color: var(--muted); padding: 18px 0; }
.link-btn { border: 0; padding: 0; background: none; color: var(--accent); font: inherit; cursor: pointer; }
.link-btn:hover { text-decoration: underline; }
table.problem-list { table-layout: fixed; }
table.problem-list th { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
table.problem-list th:nth-child(1) { width: 28%; }
table.problem-list th:nth-child(3) { width: 104px; }
table.problem-list th:nth-child(4) { width: 92px; }
table.problem-list td { vertical-align: top; }
/* The header stays in view down a long table. */
table.problem-list thead th { position: sticky; top: 0; z-index: 1; box-shadow: 0 1px 0 var(--border); }
/* Covers the hairline gap a fractional zoom leaves between header cells. */
table.problem-list thead th:not(:last-child) { box-shadow: 0 1px 0 var(--border), 1px 0 0 var(--subtle); }
table.problem-list tbody tr { transition: background-color 0.12s ease; }
table.problem-list tbody tr:hover { background: var(--hover); }
.list-name { font-family: var(--mono); font-size: 0.84rem; }
.list-desc { color: var(--muted); font-size: 0.86rem; }
/* One or two lines of the description; the problem page has the rest. */
.list-desc .clamp {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

@media (max-width: 640px) {
  table.problem-list th:nth-child(2), table.problem-list td:nth-child(2) { display: none; }
  table.problem-list th:nth-child(1) { width: auto; }
  table.problem-list th:nth-child(3) { width: 92px; }
  table.problem-list th:nth-child(4) { width: 80px; }
}
table.plain th { background: var(--subtle); font-weight: 600; }
table.plain th.num { text-align: right; }
table.plain td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.plain td.mono { font-family: var(--mono); font-size: 0.85rem; }

/* ---------- Solvers page ---------- */

.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.section-head h2 { margin: 0; padding-bottom: 8px; border-bottom: 0; }
.expand-all { padding: 4px 12px; font-size: 0.85rem; margin-bottom: 6px; }
html:not(.js) .expand-all { display: none; }

/* `163 / 164`: the count reads first, the catalogue size stays quiet. */
.count { font-weight: 600; }
.of { color: var(--muted); font-size: 0.85em; }

/* Name takes the spare width; the other columns keep to their content. */
.paradigm-table th:not(:nth-child(2)) { width: 1%; white-space: nowrap; }
.paradigm-table td.num { white-space: nowrap; }
.paradigm-table td.abbrev { font-weight: 600; white-space: nowrap; }
.paradigm-row td { background: transparent; }
.paradigm-row td:nth-child(2) { white-space: nowrap; }
/* A pill like the Browse buttons, so it reads as something to press. */
.row-toggle {
  margin-left: 10px;
  padding: 1px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--accent);
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}
.row-toggle::before { content: "Show ▾"; }
.row-toggle[aria-expanded="true"]::before { content: "Hide ▴"; }
.row-toggle:hover, .paradigm-row:hover .row-toggle { border-color: var(--accent); }
.js .paradigm-row { cursor: pointer; }
.paradigm-row:hover td { background: var(--hover); }
/* Without the script every list is already open: nothing to press. */
html:not(.js) .row-toggle { display: none; }

/* The solvers of one paradigm: a list in a full-width row of its own. */
.js tbody.collapsed .solver-panel { display: none; }
.solver-panel > td { padding: 0; background: var(--bg); }
/* A collapsed last paradigm is the table's bottom row, so it takes the edge. */
.js table.plain > tbody.collapsed:last-child > .paradigm-row > td { border-bottom: 0; }
.js table.plain > tbody.collapsed:last-child > .paradigm-row > td:first-child { border-bottom-left-radius: var(--radius); }
.js table.plain > tbody.collapsed:last-child > .paradigm-row > td:last-child { border-bottom-right-radius: var(--radius); }
.solver-list { list-style: none; margin: 0; padding: 4px 12px 4px 28px; font-size: 0.88rem; }
.solver-list li {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 16px;
  padding: 7px 0;
  border-bottom: 1px solid var(--border);
}
.solver-list li:last-child { border-bottom: 0; }
.solver-list li:target { background: var(--accent-soft); scroll-margin-top: 90px; }
.solver-count { white-space: nowrap; text-align: right; min-width: 80px; }
/* A solver with several interfaces lists them under its name, native first,
   each with the problems it models; the solver's count is any of them. */
/* A solver with several interfaces: one quiet sub-row each, native first,
   in the solver's columns. Smaller, muted, plain links: the solver's own row
   keeps the pills and the weight. */
.solver-list li.has-bindings { row-gap: 0; }
.has-bindings > .binding, .has-bindings > .binding-count, .has-bindings > .binding-action {
  padding-block: 2px;
  font-size: 0.78rem;
  color: var(--muted);
}
.binding { margin-left: 2px; padding-left: 12px; border-left: 2px solid var(--border); }
.has-bindings > .solver-name { padding-bottom: 4px; }
.binding-count { text-align: right; font-variant-numeric: tabular-nums; }
.binding-action { text-align: right; }
.binding-skill { margin-left: 8px; color: var(--muted); font-size: 0.72rem; }
.binding-browse { color: var(--accent); white-space: nowrap; }
.binding-skill:hover, .binding-browse:hover { text-decoration: underline; }
.binding:target, .solver-list li:has(> .solver-name > [id]:target) { background: var(--accent-soft); scroll-margin-top: 90px; }
/* What the framework hands the model to, e.g. Gecode under MiniZinc. */
.backend { color: var(--muted); margin-left: 8px; font-size: 0.82rem; }
.backend::before { content: "· "; }

.note-mark { margin-left: 2px; font-weight: 600; text-decoration: none; }
.table-note { color: var(--muted); font-size: 0.85rem; margin: 10px 0 0; max-width: 90ch; }
.table-note:target { color: var(--text); }

/* The "i" beside a paradigm, holding its description from paradigms.json. */
.info-wrap { position: relative; display: inline-block; margin-left: 6px; vertical-align: 1px; }
.info {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  border: 1px solid var(--muted);
  border-radius: 50%;
  color: var(--muted);
  font: italic 600 10px/1 Georgia, serif;
  cursor: help;
}
.info:hover, .info:focus { border-color: var(--accent); color: var(--accent); outline: none; }
.tip {
  display: none;
  position: absolute;
  z-index: 10;
  top: calc(100% + 6px);
  left: -8px;
  width: 340px;
  max-width: calc(100vw - 40px);
  padding: 10px 12px;
  background: var(--tip-bg);
  color: var(--tip-fg);
  border-radius: 8px;
  box-shadow: var(--pop-shadow);
  font-size: 0.82rem;
  font-weight: 400;
  line-height: 1.45;
  white-space: normal;
}
.info:hover + .tip, .info:focus + .tip { display: block; }

.browse {
  padding: 1px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--accent);
  font-size: 0.8rem;
  white-space: nowrap;
}
.browse:hover { border-color: var(--accent); background: var(--accent-soft); text-decoration: none; }
/* The skill a modelling agent follows for this integration, after its name. */
.skill {
  margin-left: 8px;
  padding: 0 7px;
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--muted);
  font-size: 0.74rem;
  white-space: nowrap;
}
.skill:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); text-decoration: none; }

/* On a phone the table has to fit without scrolling sideways, since a
   scrolling wrapper would clip the tooltips. */
@media (max-width: 640px) {
  table.paradigm-table { width: 100%; font-size: 0.8rem; }
  .paradigm-row td:nth-child(2) { white-space: normal; }
  .paradigm-table th, .paradigm-table td { padding: 8px 5px; }
  .paradigm-table th, .paradigm-table th:not(:nth-child(2)) { white-space: normal; font-size: 0.82rem; }
  /* Every count is out of the same catalogue, so the phone drops the "/ 164". */
  .paradigm-table .of { display: none; }
  .browse-long { display: none; }
  .row-toggle { display: block; margin: 4px 0 0 auto; padding: 1px 8px; }
  .solver-list { padding: 4px 8px 4px 16px; }
  .solver-list li { gap: 10px; }
  .solver-count { min-width: 0; }
  .backend { display: block; margin-left: 0; }
  .backend::before { content: ""; }
  /* The tip hangs from the cell, not the icon, so it stays on screen. */
  .paradigm-row td:nth-child(2) { position: relative; }
  .paradigm-row .info-wrap { position: static; }
  .paradigm-row .tip { left: 0; width: auto; max-width: none; right: -120px; }
}

/* Arriving from a model page's "Solver" link, so the row that was asked for
   is marked rather than left to be found by eye. */
table.plain tbody tr:target {
  background: var(--accent-soft);
  /* Keep the row clear of the top edge when the browser jumps to it. */
  scroll-margin-top: 90px;
}
table.plain tbody tr:target td:first-child {
  box-shadow: inset 3px 0 0 var(--accent);
  font-weight: 600;
}

/* ---------- Footer ---------- */
footer {
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.84rem;
  padding: 28px 20px 44px;
  text-align: center;
}

@media (max-width: 640px) {
  .hero { padding-top: 36px; padding-bottom: 26px; }
  .hero h1 { font-size: 1.9rem; }
  .hero.has-logo h1, .hero.has-logo p { padding-right: 140px; }
  .hero-logo {
    top: auto;
    right: 4px;
    bottom: 6px;
    max-width: 110px;
    max-height: calc(100% - 12px);
  }
  .problem-hero h1 { font-size: 1.6rem; }
  .problem-hero h1.problem-id { font-size: 1.35rem; overflow-wrap: anywhere; }
  .provenance dl { grid-template-columns: 1fr; gap: 2px 0; }
  .provenance dt { margin-top: 8px; }
  .picker-row { gap: 8px; }
  .picker-label { flex-basis: 68px; }
}
