/* Search page: the query box, the tag index and the result rows. */

/* Search and graph share one screen.

   Stacking them is the point: hovering a result has to light the matching node
   up, and that is only useful if both halves are on screen at once. So the page
   is exactly one viewport tall and nothing on it scrolls — the result list
   scrolls inside its own row, the graph fills what is left. This is also the
   layout that keeps the canvas still: with explicit rows there is no free
   space for the grid to redistribute when the list above changes size. */
.explore {
  position: relative;
  z-index: 1;
  height: 100svh;
  padding: 104px clamp(20px, 5vw, 48px) 24px;
  max-width: 1100px;
  margin-inline: auto;
  display: grid;
  /* head, then the two halves; minmax(…, 0) lets both rows actually shrink
     instead of being forced open by their content. The graph takes roughly
     twice the list's share: the list scrolls, so height only buys it another
     row or two, while the graph has nowhere to put what it cannot fit and
     answers a short box by shrinking everything in it. */
  grid-template-rows: auto minmax(0, 0.75fr) minmax(0, 1.5fr);
  gap: 14px;
  overflow: hidden;
}

.explore__head { min-width: 0; }
.explore__controls {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 16px;
}

/* the only scroller on the page */
.explore__results {
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
}

.explore__graph { position: relative; min-height: 0; }
.explore__graph .gcanvas-wrap { height: 100%; min-height: 0; }
/* reset sits on the canvas rather than taking a row of its own */
.explore__graph .gpanel__reset {
  position: absolute;
  right: 10px;
  bottom: 10px;
  background: color-mix(in srgb, var(--bg-2) 88%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* The box is the one thing on the page you are meant to touch, so it is the
   only element that carries any weight. */
/* Box and button are one control: a square magnifier butted against the
   field, no label — the glyph is the word. The row keeps the margin the field
   used to own so nothing below it moves. */
.search__bar {
  display: flex;
  align-items: stretch;
  gap: 8px;
  margin: 4px 0 10px;
}

.search__field {
  flex: 1 1 auto;
  min-width: 0;
  padding: 11px 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font: 15px/1.4 var(--mono);
}
.search__field::placeholder { color: var(--muted); }
.search__field:focus { outline: none; border-color: var(--accent); }
/* the type-to-clear affordance Safari/Chrome draw, toned to the page */
.search__field::-webkit-search-cancel-button { filter: grayscale(1) opacity(.5); }

.search__btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--muted);
  font: 500 13px/1 var(--mono);
  cursor: pointer;
  transition: color .18s, border-color .18s, background .18s;
}
.search__btn:hover,
.search__btn:focus-visible {
  color: var(--accent);
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--panel));
  outline: none;
}
.search__btn:active { transform: translateY(1px); }
.search__btn-icon { width: 17px; height: 17px; flex: none; }

.search__count {
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--muted);
  margin: 0;
  flex: none;
}

.search__label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .08em;
  color: var(--muted);
  margin: 0 0 12px;
}

.search__empty { color: var(--muted); font-size: 14.5px; }
.search__empty b { color: var(--ink); font-weight: 600; }

/* --- tag index (shown when the box is empty) --- */
.tagcloud { display: flex; flex-wrap: wrap; gap: 8px; }
.tagchip {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--muted);
  transition: color .18s, border-color .18s, background .18s;
}
.tagchip b { font-size: 11px; font-weight: 500; color: var(--line); }
.tagchip:hover { color: var(--ink); border-color: var(--muted); background: var(--panel); }
.tagchip:hover b { color: var(--muted); }

/* --- a result --- */
.hit {
  --accent-topic: var(--accent);
  position: relative;
  display: block;
  padding: 13px 14px 13px 18px;
  text-decoration: none;
  color: var(--ink);
  border-bottom: 1px solid var(--line-soft);
  border-radius: 8px;
  transition: background .18s;
}
.hit[data-cat="cyber"] { --accent-topic: var(--cyber); }
.hit[data-cat="linux"] { --accent-topic: var(--tux); }
.hit[data-cat="coding"] { --accent-topic: var(--code); }
.hit[data-cat="compilers"] { --accent-topic: var(--comp); }
/* same short topic marker the notes list uses, so a row reads the same way
   wherever you meet it */
.hit::before {
  content: "";
  position: absolute;
  left: 0;
  top: 15px;
  bottom: 15px;
  width: 2px;
  border-radius: 2px;
  background: var(--accent-topic);
  opacity: .7;
}
.hit:hover { background: var(--panel); }
/* The graph is pointing at this row. Same ground as hover plus the topic edge
   brought up to full strength, so the two halves visibly agree without the row
   pretending the pointer is on it. */
.hit--focus { background: var(--panel); }
.hit--focus::before { opacity: 1; width: 3px; }

.hit__head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-family: var(--mono);
  font-size: 11px;
  margin-bottom: 6px;
}
.hit__cat { color: var(--accent-topic); }
.hit__path { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hit__title { display: block; font-size: 15.5px; font-weight: 600; margin-bottom: 4px; }
.hit__snippet {
  display: block;
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--muted);
}

/* The match itself. A tinted ground rather than a highlighter: several hits in
   one line should stay readable as a sentence. */
mark {
  background: color-mix(in srgb, var(--accent) 26%, transparent);
  color: var(--ink);
  border-radius: 3px;
  padding: 0 2px;
}

@media (max-width: 760px) {
  .hit__path { display: none; }
}

/* Narrow screens cannot show both halves at once, so the page goes back to
   scrolling: list first, then a fixed slice of graph under it. */
@media (max-width: 760px) {
  .explore {
    height: auto;
    min-height: 100svh;
    grid-template-rows: auto auto auto;
    overflow: visible;
    padding-top: 92px;
  }
  .explore__results { overflow-y: visible; }
  .explore__graph { height: 64svh; }
}
