/* ═══════════════════════════════════════════════════════════════
   home.css — index page only. Requires tokens.css and chrome.css.
═══════════════════════════════════════════════════════════════ */

/* ═══════════ site notice ═══════════ */
/* A full-width band under the nav, in the Wikipedia manner: unmissable
   because it spans the page and sits above everything, quiet because it
   is warm-neutral rather than an alert colour. It is an announcement,
   not an error. */
.notice {
  border-bottom: 1px solid rgba(201, 165, 80, .22);
  background: rgba(201, 165, 80, .055);
}
/* Set by the head script before first paint, and by home.js once an
   account exists. Both hide it without a reflow after the fact. */
.notice-dismissed .notice { display: none; }
.notice-inner {
  display: flex; align-items: flex-start; gap: 14px;
  padding-top: 15px; padding-bottom: 15px;
}
.notice-mark { flex-shrink: 0; margin-top: 1px; }
.notice-mark svg { stroke: var(--gold); fill: none; stroke-width: 1.7; stroke-linecap: round; }

.notice-body { flex: 1; min-width: 0; max-width: 88ch; }
.notice-hd { font-size: 14px; font-weight: 600; color: var(--paper); }
.notice-body p { font-size: 13.5px; line-height: 1.6; color: var(--dim); }
.notice-body p + p { margin-top: 6px; }

.notice-link {
  display: inline-block; margin-top: 9px;
  font-size: 13.5px; font-weight: 600; color: var(--gold); text-decoration: none;
}
.notice-link:hover { text-decoration: underline; text-underline-offset: 3px; }

.notice-x {
  flex-shrink: 0; width: 28px; height: 28px; border-radius: 7px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 1px solid transparent; color: var(--dimmer);
  transition: color .15s, border-color .15s, background .15s;
}
.notice-x:hover { color: var(--paper); border-color: var(--line); background: rgba(255,255,255,.04); }
.notice-x svg { stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

@media (max-width: 620px) {
  .notice-inner { gap: 11px; padding-top: 13px; padding-bottom: 13px; }
  .notice-mark { display: none; }
  .notice-body p { font-size: 13px; }
}

/* ═══════════ brand texture ═══════════ */
/* Static remnant of the old animated FASTQ canvas. Same identity,
   none of the motion competing with the headline. */
.seq-rule {
  font-family: var(--mono); font-size: 11px; letter-spacing: .42em;
  color: var(--dim); opacity: .08; user-select: none;
  white-space: nowrap; overflow: hidden; padding: 24px 0 0;
}

/* ═══════════ hero ═══════════ */
.hero { padding: 30px 0 62px; }
/* stretch, not start: the browse card fills the row so its foot lines up
   with the bottom of the query column rather than stopping short. */
.hero .wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .92fr);
  gap: 56px; align-items: stretch;
}
.hero-copy { min-width: 0; }

.lockup { display: flex; align-items: center; gap: 16px; margin-bottom: 26px; }
.lockup-mark {
  width: 58px; height: 58px; border-radius: 50%; flex-shrink: 0;
  background: radial-gradient(circle at 50% 38%, #131F42 0%, #04091A 78%);
  border: 2px solid rgba(201, 165, 80, .6);
  box-shadow: 0 0 0 6px var(--gold-soft), 0 6px 26px -6px rgba(201, 165, 80, .35);
  display: flex; align-items: center; justify-content: center;
}
.lockup-mark svg { width: 27px; height: 33px; stroke: var(--gold); fill: none; stroke-linecap: round; }
.lockup-word { display: flex; flex-direction: column; gap: 4px; }
.lockup-word b { font-size: 20px; font-weight: 800; letter-spacing: .09em; line-height: 1; }
.lockup-word b span { color: var(--gold); }
.lockup-word small {
  font-family: var(--mono); font-size: 10px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--dimmer);
}

.hero h1 {
  font-size: clamp(33px, 4.15vw, 48px); line-height: 1.04;
  letter-spacing: -.036em; font-weight: 700;
  max-width: 14ch; margin-bottom: 16px;
}
.hero h1 span { color: var(--gold); }
.hero-lede {
  font-size: 17px; line-height: 1.5; font-weight: 500;
  color: var(--paper); max-width: 46ch; margin-bottom: 12px;
}
.hero-lede b { color: var(--gold); font-weight: 600; }
.hero-sub { font-size: 14.5px; line-height: 1.6; color: var(--dim); max-width: 52ch; margin-bottom: 28px; }

/* ═══════════ query ═══════════ */
.query {
  background: var(--well);
  border: 1px solid var(--gold-edge);
  border-radius: 11px; overflow: hidden;
  transition: border-color .18s, box-shadow .18s, opacity .18s;
}
.query:focus-within { border-color: rgba(201,165,80,.62); box-shadow: 0 0 0 4px rgba(201,165,80,.07); }
.query.is-locked { opacity: .38; filter: grayscale(.55); pointer-events: none; }

.query-row { display: flex; align-items: stretch; }
.query-row input {
  flex: 1; min-width: 0; height: 58px; padding: 0 18px;
  background: none; border: none; outline: none; color: var(--paper);
  font-family: var(--mono); font-size: 15px; letter-spacing: -.01em;
}
.query-row input::placeholder { color: var(--dimmer); }
.query-row button {
  flex-shrink: 0; padding: 0 26px; border: none; cursor: pointer;
  background: var(--gold); color: #08122B;
  font-size: 14.5px; font-weight: 700; letter-spacing: -.01em;
  transition: background .15s, opacity .15s;
}
.query-row button:hover:not(:disabled) { background: var(--gold-hi); }
.query-row button:disabled { opacity: .5; cursor: not-allowed; }

/* Format rule shown before submission rather than reported after it —
   the server rejects versionless accessions, so say so up front. */
.query-hint {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 8px 18px; border-top: 1px solid var(--hair);
  font-family: var(--mono); font-size: 11.5px; color: var(--dimmer);
}
.query-hint b { color: var(--dim); font-weight: 400; }

/* Normalisation feedback. Wording is written by home.js. */
/* The notice is a caution about the tool, not feedback on what was just
   typed. Sitting tight under the field made it read as validation
   output, so it gets clear separation from the query block. */
.hero-copy .ai-note { margin-top: 26px; }

.query-banner {
  display: none; width: 100%; margin-top: 10px;
  padding: 11px 14px; border-radius: 9px;
  font-size: 12.5px; line-height: 1.6; text-align: left;
  border: 1px solid; 
}
.query-banner.is-shown { display: block; }
.query-banner.is-warn  { border-color: rgba(201,165,80,.45); background: rgba(201,165,80,.07); color: var(--gold); }
.query-banner.is-error { border-color: rgba(224,112,112,.45); background: rgba(224,112,112,.08); color: var(--error); }
.query-banner code {
  font-family: var(--mono); font-size: 11.5px;
  background: rgba(255,255,255,.06); padding: 1px 5px; border-radius: 3px;
}

/* Queue hold notice. Wordless in markup; filled by home.js. */
.hold-notice {
  display: none; margin-top: 12px; padding: 14px 16px;
  border: 1px solid rgba(224,112,112,.4); background: rgba(162,45,45,.10);
  border-radius: 10px; text-align: left;
}
.hold-notice.is-shown { display: block; }
.hold-notice .hd { display: flex; align-items: center; gap: 9px; margin-bottom: 6px; }
.hold-notice .lbl { font-family: var(--mono); font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: #F09595; }
.hold-notice .cnt { margin-left: auto; font-family: var(--mono); font-size: 10px; color: #C98F8F; }
.hold-notice .msg { font-size: 13.5px; line-height: 1.55; color: var(--paper); }
.hold-notice .sub { font-size: 12px; line-height: 1.5; color: var(--dim); margin-top: 6px; }

/* ═══════════ engine capacity ═══════════ */
/* Two measured windows as meters. Deliberately low-contrast: this is
   context for someone deciding whether to submit now, not a headline. */
.capacity {
  margin-top: 26px; padding-top: 16px; border-top: 1px solid var(--hair);
}
.cap-hd { display: flex; align-items: center; gap: 10px; margin-bottom: 11px; }
.cap-updated { margin-left: auto; font-family: var(--mono); font-size: 10.5px; color: var(--dimmer); white-space: nowrap; }
.cap-updated:empty { display: none; }

.cap-refresh {
  flex-shrink: 0; width: 26px; height: 26px; border-radius: 7px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 1px solid var(--line); color: var(--dimmer);
  transition: color .15s, border-color .15s, background .15s;
}
.cap-refresh:hover { color: var(--gold); border-color: var(--gold-edge); background: var(--gold-soft); }
.cap-refresh:disabled { cursor: default; color: var(--dimmer); }
.cap-refresh svg { stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.cap-refresh.is-busy svg { animation: cap-spin .8s linear infinite; }
@keyframes cap-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .cap-refresh.is-busy svg { animation: none; opacity: .5; } }
.cap-k {
  font-family: var(--mono); font-size: 9.5px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--dimmer);
}

.cap-row {
  display: grid; grid-template-columns: 52px minmax(0, 1fr) 38px auto;
  align-items: center; gap: 11px; padding: 3px 0;
}
.cap-name { font-size: 12px; color: var(--dim); }
.cap-track { height: 5px; border-radius: 3px; background: rgba(255,255,255,.07); overflow: hidden; }
.cap-track > i { display: block; height: 100%; width: 0; border-radius: 3px; background: var(--live); transition: width .5s ease, background .3s; }
.cap-pct { font-family: var(--mono); font-size: 11.5px; color: var(--dim); text-align: right; font-variant-numeric: tabular-nums; }
.cap-reset { font-family: var(--mono); font-size: 10.5px; color: var(--dimmer); white-space: nowrap; }

/* Amber below a fifth, red once the window is committed. Same thresholds
   as the allowance pill, so the two never tell different stories. */
.cap-row.is-low  .cap-track > i { background: var(--gold); }
.cap-row.is-low  .cap-pct { color: var(--gold); }
.cap-row.is-none .cap-track > i { background: var(--error); }
.cap-row.is-none .cap-pct { color: var(--error); }

.cap-foot { margin-top: 10px; font-size: 11.5px; line-height: 1.5; color: var(--dimmer); }
.cap-foot:empty { display: none; }
.cap-foot b { color: var(--dim); font-weight: 500; }

@media (max-width: 480px) {
  .cap-row { grid-template-columns: 46px minmax(0, 1fr) 34px; }
  .cap-reset { grid-column: 2 / -1; text-align: right; }
}

/* ═══════════ corpus ═══════════ */
.corpus { border-top: 1px solid var(--hair); border-bottom: 1px solid var(--hair); padding: 32px 0; }
.corpus .wrap { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 46px; align-items: center; }
.corpus-k { font-family: var(--mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--dimmer); margin-bottom: 9px; }
.corpus-count { font-family: var(--mono); font-size: 38px; font-weight: 600; color: var(--gold); letter-spacing: -.03em; line-height: 1; }
.corpus-sub { font-size: 13.5px; color: var(--dimmer); margin-top: 6px; max-width: 22ch; }
.corpus-sub a { color: var(--dim); }
.corpus-bar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; background: var(--slate-2); }
.corpus-bar > span { height: 100%; width: 0; transition: width 1.1s cubic-bezier(.22,.7,.24,1); }
@media (prefers-reduced-motion: reduce) { .corpus-bar > span { transition: none; } }
.corpus-keys { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-top: 14px; font-size: 13px; color: var(--dim); }
.corpus-keys span { display: inline-flex; align-items: center; gap: 8px; }
.corpus-keys i { width: 8px; height: 8px; border-radius: 2px; flex-shrink: 0; }
.corpus-keys b { font-family: var(--mono); font-size: 12.5px; font-weight: 500; color: var(--paper); }

/* ═══════════ sections ═══════════ */
.sec { padding: 64px 0; }
.sec + .sec { border-top: 1px solid var(--hair); }
.sec-hd { max-width: 58ch; margin-bottom: 36px; }
.sec-hd h2 { font-size: 26px; font-weight: 700; line-height: 1.15; letter-spacing: -.025em; margin-bottom: 9px; }
.sec-hd p { font-size: 15px; color: var(--dim); }

/* Numbered because the pipeline genuinely is ordered. */
.steps { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--hair); border: 1px solid var(--hair); border-radius: 12px; overflow: hidden; }
.step { background: var(--ink); padding: 22px 20px 24px; }
.step-n { display: block; font-family: var(--mono); font-size: 12px; color: var(--gold); margin-bottom: 12px; }
.step h3 { font-size: 14.5px; font-weight: 600; letter-spacing: -.01em; margin-bottom: 7px; }
.step p { font-size: 13.5px; line-height: 1.55; color: var(--dimmer); }

/* ═══════════ cards ═══════════ */
.card { border: 1px solid var(--hair); border-radius: 12px; overflow: hidden; background: var(--slate); }
.card-hd {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid var(--hair);
}
.card-hd h2, .card-hd h3 { font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.card-hd a { font-size: 13px; color: var(--dim); text-decoration: none; }
.card-hd a:hover { color: var(--gold); }
/* Not a link: the list beneath is already everything. */
.card-count { font-family: var(--mono); font-size: 12.5px; color: var(--dimmer); }
.card-note { padding: 12px 18px; border-top: 1px solid var(--hair); font-size: 12px; line-height: 1.5; color: var(--dimmer); }
.card-empty { padding: 26px 18px; text-align: center; font-size: 13px; color: var(--dimmer); }

.card-search {
  display: flex; align-items: center; gap: 9px;
  margin: 14px 18px 0; padding: 0 12px; height: 40px;
  background: var(--well); border: 1px solid var(--line); border-radius: 8px;
  transition: border-color .18s;
}
.card-search.is-inline { margin: 0; width: 200px; }
.card-search:focus-within { border-color: var(--gold-edge); }
.card-search svg { width: 14px; height: 14px; flex-shrink: 0; stroke: var(--dimmer); fill: none; stroke-width: 1.6; }
.card-search input {
  flex: 1; min-width: 0; border: none; background: none; outline: none;
  font-family: var(--mono); font-size: 12.5px; color: var(--paper);
}
.card-search input::placeholder { color: var(--dimmer); }

/* ═══════════ browse panel (hero, right column) ═══════════ */
/* .browse-col is the grid item; the card is taken out of flow inside it.
   That is what makes the query column the master: an in-flow card with a
   long list would size the grid row itself, and the row would grow to fit
   80 variants instead of matching the column beside it. .browse-col's own
   min-height is the floor when the query column is short. */
.browse-col { position: relative; min-height: 480px; }
.browse-card {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
}

.filters { display: flex; flex-wrap: wrap; gap: 7px; padding: 12px 18px 13px; border-bottom: 1px solid var(--hair); }
.filter {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 11.5px; padding: 4px 11px; border-radius: 999px; cursor: pointer;
  background: none; border: 1px solid var(--line); color: var(--dim);
  transition: border-color .12s, color .12s, background .12s;
}
.filter:hover { border-color: rgba(124,152,208,.28); color: var(--paper); }
.filter.is-active { background: var(--gold-soft); border-color: rgba(201,165,80,.45); color: var(--gold); }
.filter i { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }

 /* Grows to whatever the column leaves it, so the header, filters and
   footnote stay put and only the rows scroll. min-height keeps the card
   usable if the left column is unusually short. */
.v-list {
  flex: 1 1 auto; min-height: 240px;
  overflow-y: auto; overscroll-behavior: contain;
}
.v-list::-webkit-scrollbar { width: 4px; }
.v-list::-webkit-scrollbar-thumb { background: rgba(124,152,208,.16); border-radius: 4px; }

.v-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 14px; align-items: center;
  padding: 11px 18px; border-bottom: 1px solid var(--hair);
  text-decoration: none; transition: background .12s;
}
.v-row:last-child { border-bottom: none; }
.v-row:hover { background: rgba(255,255,255,.025); }
.v-row.is-queued { background: rgba(0, 229, 153, .035); }
.v-main { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.v-gene { font-family: var(--mono); font-size: 12.5px; font-weight: 600; color: var(--gold); flex-shrink: 0; }
.v-hgvs { font-family: var(--mono); font-size: 12.5px; color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v-prot { font-family: var(--mono); font-size: 11px; color: var(--dimmer); flex-shrink: 0; }
.v-status { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--live); white-space: nowrap; }

/* ═══════════ gene browser ═══════════ */
/* The original gene browser, kept as-is and moved into this section.
   renderGeneDiagram() in static/gene-diagram.js owns everything inside
   #gbDetail and writes .gb-* markup, so these class names must not be
   renamed. tokens.css carries aliases for the old variable names that
   file expects. */

.sec-hd-row {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; max-width: none; flex-wrap: wrap;
}
.sec-tools { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

.btn-ghost {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 9px 16px; cursor: pointer;
  background: rgba(255,255,255,.04);
  border: 1px solid var(--line); border-radius: 8px;
  color: var(--dim); font-size: 12.5px; font-weight: 500;
  transition: background .15s, border-color .15s, color .15s;
}
.btn-ghost:hover { background: rgba(255,255,255,.08); border-color: rgba(124,152,208,.3); color: var(--paper); }

.gp-trigger {
  display: inline-flex; align-items: center; gap: 10px; cursor: pointer;
  background: var(--well); border: 1px solid var(--gold-edge);
  border-radius: 8px; padding: 7px 14px; transition: border-color .15s;
}
.gp-trigger:hover { border-color: rgba(201,165,80,.55); }
.gp-trigger-gene { font-family: var(--mono); font-size: 17px; font-weight: 700; color: var(--gold); }
.gp-trigger svg { width: 14px; height: 14px; stroke: var(--dim); fill: none; }

.gb-card { padding: 0; overflow: hidden; }
.gb-detail { padding: 22px 26px; min-width: 0; width: 100%; }
.gb-detail-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 18px; }
.gb-detail-gene { font-family: var(--mono); font-size: 22px; font-weight: 700; color: var(--gold); }
.gb-detail-meta { font-size: 11px; color: var(--dim); margin-top: 3px; }
.gb-fw {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border: 1px solid rgba(0,229,153,.3); border-radius: 999px;
  font-size: 10px; color: var(--live); white-space: nowrap;
}
.gb-fw svg { width: 12px; height: 12px; fill: none; stroke: currentColor; }

.gb-mix-label, .gb-var-head {
  font-size: 11px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--dimmer); margin-bottom: 8px;
}
.gb-mix-bar { display: flex; height: 12px; border-radius: 4px; overflow: hidden; margin-bottom: 12px; }
.gb-legend { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 22px; font-size: 11px; color: var(--dim); }
.gb-leg { display: inline-flex; align-items: center; }
.gb-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; }

.gb-var-head { margin-bottom: 0; border-top: 1px solid var(--line); padding-top: 16px; }
.gb-var-list { margin-top: 4px; }
.gb-var-row {
  display: grid; grid-template-columns: 1fr auto 110px; align-items: center;
  gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--hair);
  text-decoration: none; color: inherit;
}
.gb-var-row:hover { background: rgba(255,255,255,.02); }
.gb-var-q { font-family: var(--mono); font-size: 11px; color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gb-var-p { font-family: var(--mono); font-size: 10px; color: var(--dimmer); }

/* Plot stays pinned; the per-gene variant list scrolls inside it.
   The old clamp subtracted --footer-height, which no longer exists now
   the footer is in flow — a fixed viewport fraction is what it wanted. */
[data-gdx="list"] {
  max-height: clamp(140px, 42vh, 460px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
[data-gdx="list"]::-webkit-scrollbar { width: 4px; }
[data-gdx="list"]::-webkit-scrollbar-thumb { background: rgba(124,152,208,.18); border-radius: 4px; }

/* ═══════════ gene command palette ═══════════ */
.gp-overlay {
  position: fixed; inset: 0; z-index: 300; display: none;
  align-items: flex-start; justify-content: center;
  background: rgba(5,11,28,.6);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
}
.gp-overlay.is-open { display: flex; }
.gp-palette {
  margin-top: 14vh; width: min(360px, calc(100vw - 40px));
  background: var(--slate); border: 1px solid var(--gold-edge);
  border-radius: 14px; box-shadow: 0 24px 60px rgba(0,0,0,.55); overflow: hidden;
}
.gp-search { display: flex; align-items: center; gap: 10px; padding: 0 14px; height: 50px; border-bottom: 1px solid var(--line); }
.gp-search svg { width: 15px; height: 15px; stroke: var(--dim); fill: none; flex-shrink: 0; }
.gp-search input { flex: 1; min-width: 0; border: none; background: none; outline: none; font-family: var(--mono); font-size: 14px; color: var(--paper); }
.gp-search input::placeholder { color: var(--dimmer); }
.gp-count { font-family: var(--mono); font-size: 10px; color: var(--dimmer); white-space: nowrap; }

.gp-list { max-height: 46vh; overflow-y: auto; overscroll-behavior: contain; }
.gp-list::-webkit-scrollbar { width: 4px; }
.gp-list::-webkit-scrollbar-thumb { background: rgba(124,152,208,.18); border-radius: 4px; }
.gp-group {
  position: sticky; top: 0; padding: 7px 14px 4px;
  font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: .12em;
  color: var(--dimmer); background: rgba(0,0,0,.24);
}
.gp-row {
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 14px; cursor: pointer; border-bottom: 1px solid var(--hair);
}
.gp-row:hover { background: rgba(255,255,255,.03); }
.gp-row.is-active { background: var(--gold-soft); box-shadow: inset 2px 0 0 var(--gold); }
.gp-name { font-family: var(--mono); font-size: 12.5px; color: var(--paper); }
.gp-name mark { background: none; color: var(--gold); text-decoration: underline; text-underline-offset: 2px; }
.gp-rowcount { font-size: 10px; color: var(--dim); }
.gp-empty { padding: 22px 14px; text-align: center; font-size: 12px; color: var(--dimmer); }
.gp-foot { display: flex; gap: 16px; padding: 9px 14px; border-top: 1px solid var(--line); font-family: var(--mono); font-size: 9px; color: var(--dimmer); }

/* ═══════════ free access ═══════════ */
/* Signed-out only. Sits above the query field, so it is deliberately
   quieter than the field it precedes — the search box has to stay the
   loudest thing in the column. */
.access {
  display: flex; align-items: center; flex-wrap: wrap; gap: 16px;
  border: 1px solid rgba(0, 229, 153, .22); background: rgba(0, 229, 153, .045);
  border-radius: 11px; padding: 14px 16px; margin-bottom: 20px;
}
.access > svg { width: 18px; height: 18px; flex-shrink: 0; stroke: var(--live); fill: none; stroke-width: 1.6; stroke-linejoin: round; }
.access p { flex: 1; min-width: 230px; font-size: 13px; line-height: 1.55; color: var(--dim); }
.access p b { color: var(--live); font-weight: 600; }
.access p strong { color: var(--paper); font-weight: 600; }
.access .access-cta {
  display: inline-flex; align-items: center; text-decoration: none;
  flex-shrink: 0; padding: 9px 17px; border-radius: 8px; cursor: pointer;
  background: rgba(0,229,153,.12); border: 1px solid rgba(0,229,153,.4);
  color: var(--live); font-size: 13px; font-weight: 700; white-space: nowrap;
}
.access .access-cta:hover { background: rgba(0,229,153,.2); }

/* ═══════════ allowance modal ═══════════ */
.qm-overlay { position: fixed; inset: 0; z-index: 900; background: rgba(5,11,28,.75); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); opacity: 0; pointer-events: none; transition: opacity .25s; }
.qm-overlay.is-open { opacity: 1; pointer-events: auto; }
.qm {
  position: fixed; z-index: 901; top: 50%; left: 50%;
  transform: translate(-50%, -52%);
  width: min(430px, calc(100vw - 40px));
  background: var(--slate); border: 1px solid var(--gold-edge);
  border-radius: 16px; padding: 24px 26px;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
  opacity: 0; pointer-events: none;
  transition: opacity .25s, transform .25s;
}
.qm.is-open { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%); }
.qm-hd { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.qm-eyebrow { font-family: var(--mono); font-size: 10px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--gold); border: 1px solid var(--gold-edge); border-radius: 20px; padding: 4px 12px; background: var(--gold-soft); }
.qm-x { width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; background: none; border: 1px solid var(--line); border-radius: 6px; color: var(--dim); cursor: pointer; }
.qm-x:hover { color: var(--paper); border-color: var(--gold-edge); }
.qm h3 { font-size: 17px; font-weight: 700; letter-spacing: -.01em; margin-bottom: 9px; }
.qm p { font-size: 13px; line-height: 1.7; color: var(--dim); margin-bottom: 18px; }
.qm-gauge { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.qm-gauge .t { flex: 1; height: 6px; border-radius: 3px; background: rgba(255,255,255,.07); overflow: hidden; }
.qm-gauge .f { display: block; height: 100%; width: 0; border-radius: 3px; background: var(--gold); transition: width .45s ease; }
.qm-gauge .p { font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--gold); }
.qm-meta { font-family: var(--mono); font-size: 10px; letter-spacing: .06em; color: var(--dimmer); min-height: 14px; }
.qm-actions { display: flex; gap: 10px; margin-top: 20px; }
.qm-btn { flex: 1; padding: 10px; border-radius: 8px; font-size: 12.5px; font-weight: 600; cursor: pointer; background: rgba(255,255,255,.04); border: 1px solid var(--line); color: var(--dim); transition: background .15s, color .15s; }
.qm-btn:hover { background: rgba(255,255,255,.08); color: var(--paper); }
.qm-btn.is-primary { background: rgba(201,165,80,.12); border-color: rgba(201,165,80,.35); color: var(--gold); }
.qm-btn.is-primary:hover { background: rgba(201,165,80,.2); }

/* ═══════════ toast ═══════════ */
.toast {
  position: fixed; bottom: 26px; left: 50%;
  transform: translateX(-50%) translateY(8px);
  background: var(--slate); border: 1px solid var(--line); color: var(--paper);
  padding: 12px 24px; border-radius: 8px; font-size: 13px; font-weight: 500;
  opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; z-index: 999;
}
.toast.is-shown { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.is-ok  { border-color: rgba(0,229,153,.4); color: var(--live); }
.toast.is-err { border-color: rgba(224,112,112,.4); color: var(--error); }

/* ═══════════ responsive ═══════════ */
@media (max-width: 980px) {
  .hero .wrap { grid-template-columns: 1fr; gap: 40px; }
  /* Stacked: no column to match, so return the card to normal flow and
     cap the list rather than letting it run the length of the corpus. */
  .browse-col { position: static; min-height: 0; }
  .browse-card { position: static; }
  .v-list { max-height: 420px; }
  .sec-hd-row { align-items: flex-start; }
  .sec-tools { width: 100%; }
  .steps { grid-template-columns: 1fr 1fr; }
    .corpus .wrap { grid-template-columns: 1fr; gap: 24px; }
}
@media (max-width: 640px) {
  .hero { padding: 24px 0 44px; }
  .access { gap: 12px; }
  .access p { min-width: 100%; }
  .access .access-cta { width: 100%; justify-content: center; }
  .seq-rule { display: none; }
  .lockup-mark { width: 50px; height: 50px; }
  .lockup-mark svg { width: 23px; height: 28px; }
  .lockup-word b { font-size: 17px; }
  .steps { grid-template-columns: 1fr; }
  .gene-grid { grid-template-columns: repeat(2, 1fr); }
  .query-row button { padding: 0 18px; }
  .query-hint { flex-direction: column; gap: 4px; }

  .gb-detail { padding: 18px 16px; }
  .gb-var-row { grid-template-columns: 1fr auto; }
  .gb-var-p { display: none; }
}