/* ── home: hero search ───────────────────────────────────────── */

/* Nothing below the stat line but the panels, and `.panel-grid` owns the gap
   to them — so the hero closes on its last line rather than adding padding
   and a margin of its own on top of it. */
.hero {
  margin: 1rem 0 0;
  padding: 1.5rem 0 0;
  text-align: center;
}

.hero h1 {
  font-size: 1.35rem;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: -0.012em;
  color: var(--ink-strong);
  margin: 0 auto 0.4rem;
  max-width: 38ch;
}

.hero .sub {
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 60ch;
  margin: 0 auto 1.6rem;
}

/* the search itself ----------------------------------------------- */

.hero-search {
  position: relative;
  max-width: 640px;
  margin: 0 auto;
}
.hero-search-field {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--bg-elev);
  border: 1px solid var(--rule);
  border-radius: 12px;
  box-shadow:
    0 1px 0 rgba(12, 14, 18, 0.02),
    0 10px 30px -18px rgba(12, 14, 18, 0.18);
  transition: border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease;
}
.hero-search-field:hover {
  border-color: var(--ink-faint);
}
.hero-search-field:focus-within {
  border-color: var(--accent);
  box-shadow:
    0 0 0 4px var(--accent-ring),
    0 14px 36px -20px rgba(67, 56, 202, 0.35);
  transform: translateY(-1px);
}

.hero-search-field .icon {
  flex-shrink: 0;
  width: 18px; height: 18px;
  margin: 0 0.25rem 0 1.1rem;
  color: var(--ink-faint);
  transition: color 140ms ease;
}
.hero-search-field:focus-within .icon { color: var(--accent); }

.hero-search-field input {
  flex: 1;
  border: 0;
  background: transparent;
  outline: none;
  padding: 1.1rem 0.6rem;
  font-family: var(--font-sans);
  font-size: 1.05rem;
  font-weight: 400;
  color: var(--ink-strong);
  letter-spacing: -0.005em;
}
.hero-search-field input::placeholder {
  color: var(--ink-faint);
  font-weight: 400;
}

.hero-search-field .kbd {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 26px;
  min-width: 26px;
  padding: 0 0.45em;
  margin-right: 0.8rem;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--ink-soft);
  background: var(--bg-sunken);
  border: 1px solid var(--rule);
  border-radius: 5px;
  box-shadow: inset 0 -1px 0 var(--rule);
  transition: color 140ms ease, background 140ms ease, border-color 140ms ease;
}
.hero-search-field:focus-within .kbd {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: transparent;
}
.hero-search-field button.go {
  all: unset;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  padding: 0 1rem;
  margin-right: 0.4rem;
  font-family: var(--font-sans);
  font-size: 0.88rem;
  font-weight: 500;
  color: white;
  background: var(--accent);
  border-radius: 7px;
  cursor: pointer;
  transition: background 140ms ease;
}
.hero-search-field button.go:hover { background: var(--accent-hover); }

/* suggestions ----------------------------------------------------- */
.hero-suggest {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  margin: 1.35rem auto 0;
  font-size: 0.84rem;
}
.hero-suggest .label {
  color: var(--ink-faint);
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-right: 0.2rem;
}
.hero-suggest a {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.28em 0.7em;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink-soft);
  background: var(--bg-elev);
  border: 1px solid var(--rule);
  border-radius: 999px;
  text-decoration: none;
  transition: color 120ms ease, border-color 120ms ease, background 120ms ease, transform 120ms ease;
}
.hero-suggest a:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: var(--bg-elev);
  text-decoration: none;
  transform: translateY(-1px);
}
.hero-suggest a .glyph {
  font-size: 0.72rem;
  color: var(--ink-faint);
}
.hero-suggest a:hover .glyph { color: var(--accent); }

/* The one control in a row of suggestions. Tinted rather than outlined so it
   reads as the thing that changes the row, not as another term in it — and
   set in the UI face, where every chip beside it is monospaced. */
.hero-suggest .more {
  font-family: var(--font-sans);
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--accent);
  background: var(--accent-soft);
  border-color: transparent;
  gap: 0.4em;
}
.hero-suggest .more:hover {
  color: var(--accent-hover);
  background: var(--accent-soft);
  border-color: var(--accent);
}
.hero-suggest .more .glyph-icon {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  transition: transform 320ms cubic-bezier(.2,.7,.2,1);
}
.hero-suggest .more:hover .glyph-icon { transform: rotate(-180deg); }
/* Held for the length of the request, which is the only honest spinner: the
   row is server-drawn, so the icon stops when the new terms actually land. */
.hero-suggest .more.htmx-request .glyph-icon {
  animation: chip-spin 700ms linear infinite;
}
@keyframes chip-spin { to { transform: rotate(-360deg); } }

/* stat line under the hero ------------------------------------- */
.hero-meta {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.85rem;
  margin: 2.4rem 0 0;
  font-size: 0.85rem;
  color: var(--ink-faint);
  font-family: var(--font-mono);
  letter-spacing: 0.01em;
}
.hero-meta a {
  color: inherit;
  text-decoration: none;
  transition: color 120ms ease;
}
.hero-meta a:hover,
.hero-meta a:hover b {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
}
.hero-meta b {
  font-weight: 600;
  color: var(--ink-strong);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.hero-meta .sep {
  width: 4px; height: 4px;
  background: var(--ink-faint);
  border-radius: 50%;
  opacity: 0.5;
}

/* ── below-the-fold sections ─────────────────────────────────── */

/* The two panels are read across, so their rules have to line up: same head
   height, same row height, same row count (the view slices `newest` to the
   number of sources). Both lists opt into these two variables. The technique
   panel below takes the head variable too, so its head keeps the same line
   box as the two above it despite sitting outside the grid. */
.panel-grid,
.technique-panel {
  --head-line: 1.25rem;
}
.panel-grid {
  --row-h: 4.25rem;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 3rem;
  margin-top: 3rem;
  align-items: start;
}
/* Drop the global section margin in both columns — dropping it in only one
   would offset that column's rows against the other's. */
.panel-grid section { margin: 0; }

.technique-panel { margin: 3rem 0 0; }
.technique-lede { font-size: 0.86rem; margin: 0 0 0.85rem; }
@media (max-width: 860px) {
  .panel-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .hero { padding: 3rem 0.5rem 0; }
}

/* Every child sits in the same fixed line box so a head carrying buttons is
   exactly as tall as one carrying text, and both lists start on the same y. */
.section-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}
.section-head > * { line-height: var(--head-line); }
.section-head h2 {
  margin: 0;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-strong);
}
.section-head .count {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-faint);
  letter-spacing: 0.02em;
  text-align: right;
}
.section-head .count a {
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}
.section-head .count a:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
  text-decoration: none;
}

/* minimal sort control — sits where the section count would */
.sort-set {
  display: inline-flex;
  align-items: baseline;
  gap: 0.1rem;
  flex-shrink: 0;
}
.sort-set .lab {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-faint);
  opacity: 0.7;
  margin-right: 0.2rem;
}
.sort-set button {
  all: unset;
  cursor: pointer;
  line-height: var(--head-line);
  padding: 0 0.4em;
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  transition: color 120ms ease, background 120ms ease;
}
.sort-set button:hover { color: var(--ink); background: var(--bg-elev); }
.sort-set button:focus-visible { box-shadow: 0 0 0 2px var(--accent-ring); }
.sort-set button[aria-pressed="true"] { color: var(--accent); }
.sort-set button .dir { visibility: hidden; margin-left: 0.1em; }
.sort-set button[aria-pressed="true"] .dir { visibility: visible; }

.source-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--rule-soft);
}
.source-list li {
  display: grid;
  grid-template-columns: 1.6rem 1fr auto;
  align-items: baseline;
  gap: 0.85rem;
  padding: 0.7rem 0;
  min-height: var(--row-h);
  box-sizing: border-box;
  border-bottom: 1px solid var(--rule-soft);
  font-size: 0.92rem;
  transition: background 120ms ease;
}
.source-list li:hover { background: var(--bg-elev); }
.source-list .num {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--ink-faint);
  letter-spacing: 0.02em;
}
.source-list a {
  color: var(--ink);
  font-weight: 500;
  text-decoration: none;
}
.source-list a:hover { color: var(--accent); text-decoration: none; }
.source-list .meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.55rem;
  row-gap: 0.18rem;
  margin-top: 0.22rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}
/* Mid-dot separators ride with the item they precede so a wrapped row
   can't strand a "·" at the end of a line. The first child stays clean. */
.source-list .meta > * + *::before {
  content: "·";
  color: var(--ink-faint);
  opacity: 0.5;
  margin-right: 0.55em;
}
.source-list .meta .lab {
  font-size: 0.62rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-right: 0.3em;
}
.source-list .meta time { color: var(--ink-soft); }
.source-list .meta .none { color: var(--ink-faint); opacity: 0.55; }
.source-list .n {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  align-self: start;
  padding-top: 0.05rem;
}
.source-list .n a { color: inherit; text-decoration: none; }
.source-list .n a:hover { color: var(--accent); }

.recent-list {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid var(--rule-soft);
}
.recent-list li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 1rem;
  padding: 0.7rem 0;
  min-height: var(--row-h);
  box-sizing: border-box;
  border-bottom: 1px solid var(--rule-soft);
  transition: background 120ms ease;
}
.recent-list li:hover { background: var(--bg-elev); }
.recent-list .title {
  min-width: 0;
}
.recent-list .title a {
  display: block;
  color: var(--ink);
  font-weight: 500;
  font-size: 0.92rem;
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.recent-list .title a:hover { color: var(--accent); text-decoration: none; }
.recent-list .src {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-faint);
  margin-top: 0.22rem;
  letter-spacing: 0.01em;
}
.recent-list .date {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  align-self: start;
  padding-top: 0.1rem;
}

/* One per line: the id column stays flush so the names read as a list, and a
   long sub-technique name ("Parent: Sub") truncates instead of wrapping.

   Two columns via multi-column rather than a grid, because the list is ranked
   and multicol fills the first column before the second: 1-10 read down the
   left, 11-20 down the right. A two-track grid would flow across instead and
   put rank 2 beside rank 1. It also takes whatever length the view hands it,
   where a grid would need the row count hard-coded here. */
.technique-grid {
  columns: 2;
  column-gap: 3rem;
  border-top: 1px solid var(--rule-soft);
}
.technique-grid a {
  display: grid;
  /* Multicol may break a block across the column boundary; a row split in
     half down the middle of the page is worse than an uneven column. */
  break-inside: avoid;
  /* Rows stop short of their column rather than stretching to it. 27rem is
     the widest row's natural width — "Command and Scripting Interpreter:
     PowerShell" needs 430px — so nothing truncates that did not truncate
     before, and the count stays near the name it belongs to instead of
     drifting to the page edge. What is left over becomes clear water
     between the two lists, which is what makes them read as one list
     continuing rather than two columns of unrelated numbers. */
  max-width: 27rem;
  grid-template-columns: 5.5rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 0.6rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--rule-soft);
  color: var(--ink);
  text-decoration: none;
  transition: color 120ms ease, padding-left 200ms ease;
}
.technique-grid a:hover {
  color: var(--accent);
  text-decoration: none;
  padding-left: 0.2rem;
}
.technique-grid a code {
  font-size: 0.82rem;
  font-weight: 500;
  color: inherit;
}
.technique-grid a .tname {
  font-size: 0.86rem;
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.technique-grid a:hover .tname { color: inherit; }
.technique-grid a .tname.none { color: var(--ink-faint); opacity: 0.55; }
/* Two tracks hold their names down to about here: 2 of 20 truncate at 820px,
   and those two are the ones long enough to truncate in a single column as
   well. Below it the rot is quick — 4 at 780, 7 at 740 — so the second track
   stops paying for itself. */
@media (max-width: 800px) {
  .technique-grid { columns: 1; }
}
.technique-grid a .n {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
