/* Search by Molecule.
 *
 * One page, one gene, five questions. Each card answers exactly one of them
 * and says which in its heading, so a reader scans headings rather than
 * decoding plots. Cards fill in as their data lands; the page never blocks on
 * its slowest panel.
 *
 * Colour is set here and nowhere else. Every value is an explicit RGB hex.
 * Expression runs cyan to yellow on a dark ground, the house scale. Fold
 * change is signed, so it runs on a separate diverging scale and never
 * borrows the expression one -- a reader who has learnt that yellow means
 * "high" must not meet a yellow that means "up in disease".
 */

:root {
  --mol-ink: #1b2733;
  --mol-muted: #5d6b7a;
  --mol-line: #e3e8ee;
  --mol-rule: #cfd8e3;
  --mol-paper: #ffffff;
  --mol-ground: #f7f9fb;
  --mol-brand: #0b3d78;
  --mol-brand-soft: #e8f0f9;

  /* Expression, low to high. */
  --mol-expr-lo: #00ffff;
  --mol-expr-hi: #ffff00;
  --mol-expr-bg: #1a1a1a;

  /* Fold change, down / none / up. */
  --mol-down: #2c6fb5;
  --mol-mid: #f2f4f7;
  --mol-up: #c0392b;

  --mol-dev: #6b4fa8;
}

.MoleculePage {
  background: var(--mol-ground);
}

.mol-wrap {
  max-width: 1240px;
  margin: 0 auto;
  padding: 18px 20px 64px;
}

/* ------------------------------------------------------------ the gene bar */

.mol-seek {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 14px;
  position: relative;
}

.mol-seek input {
  flex: 1 1 auto;
  height: 44px;
  border: 1px solid var(--mol-rule);
  border-radius: 22px;
  padding: 0 18px;
  font-size: 16px;
  color: var(--mol-ink);
  background: var(--mol-paper);
}

.mol-seek input:focus {
  outline: none;
  border-color: var(--mol-brand);
  box-shadow: 0 0 0 3px rgba(11, 61, 120, 0.12);
}

.mol-seek button {
  height: 44px;
  padding: 0 26px;
  border: 0;
  border-radius: 22px;
  background: var(--mol-brand);
  color: var(--mol-paper);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

.mol-suggest {
  position: absolute;
  top: 48px;
  left: 0;
  right: 0;
  z-index: 40;
  background: var(--mol-paper);
  border: 1px solid var(--mol-rule);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(16, 32, 56, 0.14);
  overflow: hidden;
  display: none;
}

.mol-suggest.open { display: block; }

.mol-suggest div {
  padding: 9px 16px;
  cursor: pointer;
  font-size: 15px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.mol-suggest div:hover,
.mol-suggest div.on { background: var(--mol-brand-soft); }

.mol-suggest small { color: var(--mol-muted); }

/* --------------------------------------------------------------- the header */

.mol-head {
  background: var(--mol-paper);
  border: 1px solid var(--mol-line);
  border-radius: 12px;
  padding: 20px 22px;
  margin-bottom: 16px;
}

/* The same masthead as every other page: 30px sans, bold, brand blue. */
.mol-head h1 {
  font-family: var(--lm-font-sans);
  font-size: 30px;
  line-height: 1.2;
  margin: 0 0 6px;
  color: var(--lm-blue);
  font-weight: 700;
  letter-spacing: -0.01em;
}

.mol-head .mol-sub {
  font-size: 15px;
  color: var(--mol-ink);
  margin: 0 0 14px;
  /* The description under the h1, widened by the same steps:
     78ch -> 101ch (+30%) -> 116ch (a further 15%). */
  max-width: 116ch;
}

.mol-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
}

.mol-fact strong {
  display: block;
  font-size: 19px;
  color: var(--mol-ink);
  font-weight: 700;
  line-height: 1.2;
}

.mol-fact span {
  font-size: 12px;
  color: var(--mol-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ---------------------------------------------------------------- the cards */

.mol-card {
  background: var(--mol-paper);
  border: 1px solid var(--mol-line);
  border-radius: 12px;
  padding: 18px 22px 20px;
  margin-bottom: 16px;
}

.mol-card > h2 {
  font-size: 19px;
  margin: 0 0 3px;
  color: var(--mol-ink);
  font-weight: 700;
}

.mol-card > p.mol-why {
  font-size: 13.5px;
  color: var(--mol-muted);
  margin: 0 0 14px;
  /* Widened at the site owner's request: the plot below each heading spans
     the whole card, so the sentence explaining it was set far narrower than
     the thing it describes. 82ch -> 107ch (+30%) -> 123ch (a further 15%),
     half again as wide as it began. The card is 1240px less 22px padding
     each side, and 123ch at 13.5px is about 830px, so it stays clear. */
  max-width: 123ch;
}

.mol-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  align-items: center;
  margin-bottom: 12px;
}

.mol-tools label {
  font-size: 12.5px;
  color: var(--mol-muted);
  margin-right: 4px;
}

.mol-tools select {
  height: 32px;
  border: 1px solid var(--mol-rule);
  border-radius: 6px;
  padding: 0 8px;
  font-size: 13.5px;
  color: var(--mol-ink);
  background: var(--mol-paper);
  max-width: 240px;
}

.mol-seg {
  display: inline-flex;
  border: 1px solid var(--mol-rule);
  border-radius: 7px;
  overflow: hidden;
}

.mol-seg button {
  border: 0;
  background: var(--mol-paper);
  color: var(--mol-muted);
  font-size: 13px;
  padding: 7px 13px;
  cursor: pointer;
}

.mol-seg button + button { border-left: 1px solid var(--mol-rule); }

.mol-seg button.on {
  background: var(--mol-brand);
  color: var(--mol-paper);
  font-weight: 600;
}

.mol-note {
  font-size: 12.5px;
  color: var(--mol-muted);
  margin-top: 10px;
  line-height: 1.5;
}

.mol-plot { position: relative; overflow-x: auto; }

.mol-plot svg { display: block; max-width: 100%; height: auto; }
/* A plot wider than the page column must SCROLL, not shrink. max-width:100% made the
   browser scale the whole SVG down (the disease grid draws 3,794 px wide in a 1,140 px
   column = 0.30x), which shrank every label with it. Every .mol-plot already declares
   overflow-x:auto, so scrolling is the behaviour the container was built for. Same fix
   as niche.css:231 for #na-dotplot. */
.mol-plot svg { max-width: none; }

.mol-empty {
  padding: 26px 0;
  color: var(--mol-muted);
  font-size: 14px;
}

.mol-busy {
  padding: 26px 0;
  color: var(--mol-muted);
  font-size: 14px;
}

.mol-busy::after {
  content: "";
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-left: 8px;
  border: 2px solid var(--mol-rule);
  border-top-color: var(--mol-brand);
  border-radius: 50%;
  vertical-align: -1px;
  animation: mol-spin 0.7s linear infinite;
}

@keyframes mol-spin { to { transform: rotate(360deg); } }

/* --------------------------------------------------------------- filtering */

.mol-filters {
  border: 1px solid var(--mol-line);
  border-radius: 12px;
  background: var(--mol-paper);
  margin-bottom: 16px;
}

.mol-filters > summary {
  padding: 13px 22px;
  cursor: pointer;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--mol-ink);
  list-style: none;
}

.mol-filters > summary::-webkit-details-marker { display: none; }

.mol-filters > summary::before {
  content: "\25B8";
  display: inline-block;
  margin-right: 9px;
  color: var(--mol-muted);
  transition: transform 0.15s;
}

.mol-filters[open] > summary::before { transform: rotate(90deg); }

.mol-filters .mol-filter-body {
  padding: 4px 22px 18px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
  gap: 14px 20px;
}

.mol-filter b {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--mol-muted);
  margin-bottom: 5px;
  font-weight: 600;
}

.mol-filter select {
  width: 100%;
  border: 1px solid var(--mol-rule);
  border-radius: 6px;
  font-size: 13px;
  padding: 5px 6px;
  color: var(--mol-ink);
  min-height: 88px;
}

.mol-filter-active {
  padding: 0 22px 16px;
  font-size: 13px;
  color: var(--mol-muted);
}

.mol-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--mol-brand-soft);
  color: var(--mol-brand);
  border-radius: 12px;
  padding: 3px 10px;
  margin: 0 6px 6px 0;
  font-size: 12.5px;
}

.mol-chip button {
  border: 0;
  background: none;
  color: var(--mol-brand);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0;
}

/* ------------------------------------------------------------------ tooltip */

.mol-tip {
  position: fixed;
  z-index: 90;
  pointer-events: none;
  background: #10203a;
  color: #ffffff;
  border-radius: 7px;
  padding: 8px 11px;
  font-size: 12.5px;
  line-height: 1.45;
  max-width: 300px;
  opacity: 0;
  transition: opacity 0.1s;
  box-shadow: 0 6px 20px rgba(8, 18, 34, 0.3);
}

.mol-tip.on { opacity: 1; }

.mol-tip b { color: #ffe08a; }

/* -------------------------------------------------------------- the legends */

.mol-legend {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--mol-muted);
  margin-top: 8px;
  flex-wrap: wrap;
}

.mol-legend .mol-ramp {
  width: 130px;
  height: 10px;
  border-radius: 2px;
  border: 1px solid var(--mol-rule);
}

.mol-legend .mol-key {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.mol-legend .mol-key i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  display: inline-block;
}

/* --------------------------------------------------------------- two column */

.mol-two {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}

@media (max-width: 900px) {
  .mol-two { grid-template-columns: 1fr; }
  .mol-head h1 { font-size: 27px; }
}

/* An axis label that would otherwise collide is rotated, never dropped. */
.mol-axis text { font-size: 11px; fill: #4a5866; }
.mol-axis line, .mol-axis path { stroke: var(--mol-rule); shape-rendering: crispEdges; }
.mol-grid line { stroke: #eef2f6; shape-rendering: crispEdges; }

/* A control that reads as a link but is a button, because it changes what the
   plot shows rather than navigating anywhere. */
.mol-linkish {
  border: 0;
  background: none;
  color: var(--mol-brand);
  font-size: 13px;
  cursor: pointer;
  padding: 0 2px;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Cell type names are written in full, so a long one wraps inside its fact
   box rather than stretching the row. */
.mol-fact { max-width: 320px; }
.mol-fact strong { overflow-wrap: break-word; }

/* The test result above the developmental chart. Larger than a note, because it is a
   result rather than a caveat, and it must be readable at a glance. */
.mol-stat {
  margin: 2px 0 10px;
  font-size: 13px;
  color: #2c3e50;
  line-height: 1.5;
}
.mol-stat b { color: #14315c; }
.mol-stat .mol-stat-weak { color: #6b7885; }

/* Two embeddings side by side: cell states, and this feature's expression. They stack
   below 900 px, because two 400 px panels in a phone viewport are two unreadable ones. */
.mol-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.mol-pair .mol-plot { min-width: 0; }
@media (max-width: 900px) { .mol-pair { grid-template-columns: 1fr; } }

/* Each embedding carries its own caption strip. Both are the same height so the two
   plots start on the same line, whatever the caption holds. */
.mol-pair-col { display: flex; flex-direction: column; min-width: 0; }
.mol-pair-cap {
  display: flex;
  align-items: center;
  min-height: 18px;
  margin: 0 0 4px 2px;
  font-size: 11px;
  color: var(--mol-muted);
}
.mol-cap-lab { letter-spacing: .02em; }

/* The colour key: a label, the low value, a gradient strip, the high value. Small on
   purpose -- it explains the panel below it and must not compete with it. */
.mol-ramp-key { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; }
.mol-ramp-key .mol-ramp-lab { color: var(--mol-muted); }
.mol-ramp-key .mol-ramp-num {
  font-variant-numeric: tabular-nums;
  color: var(--mol-ink, #1b2733);
}
.mol-ramp-key .mol-ramp-bar {
  width: 84px;
  height: 8px;
  border-radius: 2px;
  border: 1px solid var(--mol-rule);
  display: inline-block;
}

/* The one-line answer under the Show box. Small: it explains a choice the page already
   made, and must not compete with the title of the feature it chose. */
.mol-seek-note {
  margin: .35rem 0 0 2px;
  /* 13px, not 12: this line now carries a written answer, not a one-line hint. */
  font-size: 13px;
  line-height: 1.5;
  color: var(--mol-muted);
  /* USE THE WIDTH THE CARD HAS. Nathan, 2026-09-21: "you are sitll restricitng text to
     1/4the width of the frame... use most of it". 70ch at 12px is about 500px inside a
     1900px frame, so a three-sentence answer wrapped four times against a field of
     white. The line now takes the card's own width. */
  max-width: 100%;
}

/* Discover in the modality bar. It is not a measurement, so it is set apart from the
   buttons by a rule and reads as a destination rather than a fifth thing to select. */
.mol-modality-discover {
  margin-left: .55rem;
  padding: .35rem .8rem;
  font-size: 13px;
  font-weight: 600;
  color: #14315c;
  text-decoration: none;
  border: 1px solid #cfd8e0;
  border-radius: 4px;
  background: #f4f8fb;
  white-space: nowrap;
}
.mol-modality-discover:hover { background: #e8f0f7; border-color: #9db8d2; }

/* A SUBSTITUTED FACTOR IS A WARNING, NOT A FOOTNOTE.

   Switching a gene that carries no regulatory model to Gene regulation draws a
   DIFFERENT factor. The page has always said so in the note line; in the note's own
   grey it read as description, and a reader who skimmed it took the drawn activity for
   the factor they typed. Red, at the note's size, so it is seen without shouting. */
.mol-note-alert {
  color: #b3261e;
  font-weight: 600;
}

/* The written half of an answer, and where it came from. The deterministic sentence
   before it reads at the note's own weight; these two are quieter, because one is a
   model's joining prose and the other is a citation list. */
.mol-seek-written { color: #33414f; }
.mol-seek-src { font-size: .85em; color: #6b7a88; }

/* The controlled-vocabulary pointer under the feature description. It is a standing
   note, not part of the finding, so it reads at the note's weight. */
.mol-sub-terms {
  font-size: 13px;
  color: var(--mol-muted);
  margin-top: .2rem;
}
