/* app.js mounts the tool in a shadow root (:host), so nothing inherits in from a
   page that embeds it. Standalone, the same tokens and body rules also style the page.
   Diagol Grotesk and Mono load on wishyouwerehere.se; standalone the system fonts
   stand in. The level colours come from Heading Outliner, the sibling tool. */
:host { all: initial; display: block; }

:root, :host {
  color-scheme: dark;
  --paper: #11161c;
  --ink: #e8edf2;
  --signal: #ff6b5e;
  --select: #5aaee6;
  --muted: color-mix(in srgb, var(--ink) 64%, var(--paper));
  --line: color-mix(in srgb, var(--ink) 20%, var(--paper));
  --faint: color-mix(in srgb, var(--ink) 7%, var(--paper));
  --font-sans: 'Diagol Grotesk', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --tracking: -0.03em;
  --space-1: 0.25rem;
  --space-2: 0.625rem;
  --space-3: 1.25rem;
  --space-4: 1.875rem;
  --space-5: 2.5rem;
  --space-6: 3.75rem;
  --radius: 0.25rem;
  --radius-button: 0.375rem;
}

* { box-sizing: border-box; }

body, :host {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 1rem/1.625 var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

.app { inline-size: min(100% - 2rem, 76rem); margin-inline: auto; padding-block: var(--space-4) var(--space-6); }

:focus-visible { outline: 2px solid var(--select); outline-offset: 2px; }

h1, h2, h3 { font-weight: 400; letter-spacing: var(--tracking); text-wrap: balance; }

button {
  border: 1px solid var(--line);
  border-radius: var(--radius-button);
  background: var(--paper);
  color: inherit;
  font: inherit;
  cursor: pointer;
}

button:hover { border-color: var(--ink); }

.hidden-label {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ———— The form ———— */

.top { max-inline-size: 38rem; margin-block-end: var(--space-5); }

.brand { display: inline-block; margin-block-end: var(--space-6); color: inherit; font: 500 0.8125rem var(--font-mono); text-decoration: none; }
.brand:hover { text-decoration: underline; }

h1 { margin: 0; font-size: clamp(3rem, 9vw, 5.25rem); line-height: 1; }
.meta { margin: var(--space-2) 0 0; font: 0.8125rem var(--font-mono); color: var(--select); }
.meta::before { content: "$ "; color: var(--muted); }
.lede { margin: var(--space-3) 0; font-size: 1.125rem; }
.privacy { margin: 0 0 var(--space-3); font-size: 0.875rem; color: var(--muted); }

.field { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.field input {
  flex: 1 1 14rem;
  min-inline-size: 0;
  min-block-size: 4rem;
  padding: 0 var(--space-3);
  border: 1px solid var(--ink);
  border-radius: var(--radius-button);
  background: var(--paper);
  color: inherit;
  font: 1.375rem var(--font-mono);
}

.field input::placeholder { color: var(--muted); }

.field button {
  min-block-size: 4rem;
  padding: 0 var(--space-4);
  font-size: 1.5rem;
  letter-spacing: var(--tracking);
}

#go { border-color: var(--ink); background: var(--ink); color: var(--paper); }
#go:hover { background: color-mix(in srgb, var(--ink) 85%, var(--paper)); }

.status { min-block-size: 1.625em; margin: var(--space-2) 0 0; font: 0.8125rem/1.8 var(--font-mono); color: var(--muted); }
/* While crawling the line names each page; kept to one line so the page below doesn't jump */
form:has(#stop:not([hidden])) + .status { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Once a site is being drawn, only what starts the next one stays */
.top.compact h1, .top.compact .lede, .top.compact .privacy { display: none; }
/* Embedded, the site's page carries the name and the heading */
:host([data-base]) :is(.brand, h1, .meta, .lede) { display: none; }
/* There the page sets the width; the field lines up with the site's heading through
   its --rutnat-indrag, which inherits into the shadow root */
:host([data-base]) .app { inline-size: auto; padding-block-start: 0; }
:host([data-base]) .top { padding-inline-start: var(--rutnat-indrag, 0); }
.top.compact { margin-block-end: var(--space-3); }
.top.compact .brand { margin-block-end: var(--space-1); }
.top.compact .meta { margin-block-end: var(--space-2); }
.top.compact .field input, .top.compact .field button { min-block-size: 2.75rem; font-size: 1rem; }
.top.compact .field button { padding: 0 var(--space-3); }

/* ———— The report ———— */

.report[hidden] { display: none; }

.report {
  display: grid;
  grid-template-columns: minmax(17rem, 24rem) minmax(0, 1fr);
  grid-template-areas: "summary summary" "outline board";
  gap: var(--space-4) var(--space-5);
  align-items: start;
}

.summary .notice { display: block; margin-block-start: var(--space-2); font-size: 1rem; line-height: 1.5; letter-spacing: 0; color: var(--signal); }
.summary { grid-area: summary; margin: 0; padding-block-start: var(--space-4); border-block-start: 1px solid var(--line); font-size: clamp(1.75rem, 4vw, 2.25rem); line-height: 1.15; letter-spacing: var(--tracking); }
.outline { grid-area: outline; }
.board { grid-area: board; min-inline-size: 0; }

@media (max-width: 52rem) {
  .report { grid-template-columns: minmax(0, 1fr); grid-template-areas: "summary" "board" "outline"; }
}

h2 { margin: 0 0 var(--space-2); font-size: 1.25rem; line-height: 1.2; }

/* ———— Pages, as a tree ———— */

.outline {
  position: sticky;
  inset-block-start: var(--space-3);
  max-block-size: calc(100vh - 2 * var(--space-3));
  overflow: auto;
  overscroll-behavior: contain;
}

@media (max-width: 52rem) {
  .outline { position: static; max-block-size: none; }
}

.outline-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-1) var(--space-2); }
.folds { display: flex; gap: var(--space-1); margin-block-end: var(--space-2); }
.folds button { min-block-size: 2.75rem; padding: 0 var(--space-2); font-size: 0.875rem; }

.tree, .tree ul, .headings, .notes { margin: 0; padding: 0; list-style: none; }

.node { display: flex; align-items: center; }

.branch { flex: none; align-self: stretch; display: flex; }
/* --twig: the middle of a row's first line, where its branch meets it */
.cell { --stroke: color-mix(in srgb, var(--ink) 32%, var(--paper)); --twig: 0.875rem; position: relative; inline-size: 1rem; }
.cell.p::before, .cell.t::before, .cell.e::before { content: ""; position: absolute; inset-block: 0; inset-inline-start: 50%; border-inline-start: 1px solid var(--stroke); }
.cell.e::before { inset-block-end: auto; block-size: var(--twig); }
.cell.t::after, .cell.e::after { content: ""; position: absolute; inset-inline: 50% 0; inset-block-start: var(--twig); border-block-start: 1px solid var(--stroke); }

.toggle {
  flex: none;
  align-self: flex-start;
  inline-size: 1.5rem;
  block-size: 1.75rem;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
}

.toggle:hover { background: var(--faint); border-radius: var(--radius); }
.toggle::before { content: ""; display: inline-block; inline-size: 0.45rem; block-size: 0.45rem; border: solid currentColor; border-width: 0 2px 2px 0; transform: translateX(-0.1rem) rotate(-45deg); }
.toggle[aria-expanded="true"]::before { transform: translateY(-0.1rem) rotate(45deg); }
.spacer { flex: none; inline-size: 1.5rem; }

@media (prefers-reduced-motion: no-preference) {
  .toggle::before { transition: transform 0.15s; }
}

.row {
  flex: 1;
  min-inline-size: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 var(--space-2);
  padding: 0.125rem var(--space-1);
  border: 0;
  border-radius: var(--radius);
  background: none;
  text-align: start;
  line-height: 1.4;
}

.row:hover { background: var(--faint); }
.row[aria-current="true"] { box-shadow: inset 0 0 0 2px var(--select); }
.row.dir { cursor: default; color: var(--muted); }
.row.dir:hover { background: none; }

.row .name { flex: 1 1 0; min-inline-size: 0; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row .count, .row .tag { flex: none; }
.count { font: 0.75rem var(--font-mono); color: var(--muted); }
.sub { inline-size: 100%; font: 0.75rem/1.6 var(--font-mono); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.tag {
  font: 0.6875rem/1.6 var(--font-mono);
  padding: 0 0.3rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--muted);
}

.tag.bad { border-color: var(--signal); color: var(--signal); }

/* In line with the row's name: one 1rem cell per level, then the toggle */
.detail {
  margin: var(--space-1) 0 var(--space-2) calc(var(--indent) * 1rem + 1.5rem);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
  border-inline-start: 1px solid var(--line);
  font-size: 0.875rem;
}

.detail p { margin: 0 0 var(--space-1); }
.detail .quiet { color: var(--muted); }
.detail .links-title { margin-block-start: var(--space-2); font-weight: 500; }
.links { display: grid; gap: 0.125rem; }
.links > div { overflow-wrap: anywhere; }
.notes { margin-block-end: var(--space-2); }
.notes .error { color: var(--signal); }

.headings li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0 var(--space-2);
  align-items: baseline;
  padding: 0.125rem 0;
}

.level { font: 500 0.6875rem/1.6 var(--font-mono); color: #fff; background: var(--c); padding: 0 0.3rem; border-radius: var(--radius); }
/* Heading Outliner's level colours, for the badges and the heading trees in the graph */
.l1 { --c: #0071bb; } .l2 { --c: #006837; }
.l3 { --c: #6633db; } .l4 { --c: #8a6d00; }
.l5 { --c: #7a5195; } .l6 { --c: #555; }
.headings .error .level { background: var(--signal); }
.where { font: 0.6875rem/1.6 var(--font-mono); color: var(--muted); }
.note { grid-column: 2 / -1; font-size: 0.8125rem; color: var(--muted); }
.headings .error .note { color: var(--signal); }

/* ———— Graph controls ———— */

.controls { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2); margin-block-end: var(--space-2); }

.pick { display: flex; }
.pick button { min-block-size: 2.75rem; padding: 0 var(--space-3); font: 0.875rem var(--font-mono); border-radius: 0; margin-inline-start: -1px; }
.pick button:first-child { border-radius: var(--radius-button) 0 0 var(--radius-button); margin-inline-start: 0; }
.pick button:last-child { border-radius: 0 var(--radius-button) var(--radius-button) 0; }
/* The chosen view is inverted, not just tinted */
.pick [aria-pressed="true"] { position: relative; border-color: var(--ink); background: var(--ink); color: var(--paper); }

.settings { position: relative; }
.settings summary { display: flex; align-items: center; gap: var(--space-1); min-block-size: 2.75rem; padding: 0 var(--space-3); border: 1px solid var(--line); border-radius: var(--radius-button); font: 0.875rem var(--font-mono); cursor: pointer; list-style: none; }
.settings summary::-webkit-details-marker { display: none; }
.settings summary::after { content: "▾"; color: var(--muted); }
.settings[open] summary { border-color: var(--ink); }

.layers {
  position: absolute;
  inset-block-start: calc(100% + var(--space-1));
  inset-inline-end: 0;
  z-index: 2;
  display: grid;
  gap: var(--space-1);
  min-inline-size: 17rem;
  padding: var(--space-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
  box-shadow: 0 0.5rem 1.5rem rgb(0 0 0 / 0.5);
}

.layers button { min-block-size: 2.75rem; padding: 0 var(--space-2); font-size: 0.875rem; text-align: start; }
.layers button::before { content: "○ "; color: var(--muted); }
.layers [aria-pressed="true"] { border-color: var(--ink); }
.layers [aria-pressed="true"]::before { content: "● "; color: var(--ink); }

.stage { position: relative; }

.graph {
  display: block;
  inline-size: 100%;
  aspect-ratio: 1;
  max-block-size: 78vh;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--paper);
}

.turn { position: absolute; inset-inline-start: var(--space-2); inset-block-end: var(--space-2); display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); }
.turn[hidden], .zoom[hidden] { display: none; }
.zoom { position: absolute; inset-inline-end: var(--space-2); inset-block-start: var(--space-2); display: flex; gap: var(--space-1); }
.zoom button { min-inline-size: 2.75rem; min-block-size: 2.75rem; font-family: var(--font-mono); }
.turn button { min-inline-size: 2.75rem; min-block-size: 2.75rem; }
.turn span { font-size: 0.8125rem; color: var(--muted); margin-inline-end: var(--space-1); }

.export { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin: var(--space-2) 0 var(--space-5); }
.export[hidden] { display: none; }
.export button { min-block-size: 2.75rem; padding: 0 var(--space-3); font-size: 0.875rem; }
.note-line.focus-note { margin-block-start: var(--space-2); color: var(--ink); }
.unlock { flex-basis: 100%; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); margin-block-start: var(--space-1); }
.unlock[hidden] { display: none; }
.unlock label { font-size: 0.875rem; margin-inline-end: var(--space-1); }
.unlock input { min-block-size: 2.75rem; padding: 0 var(--space-2); border: 1px solid var(--ink); border-radius: var(--radius-button); background: var(--paper); color: inherit; font: inherit; }
.unlock button { min-block-size: 2.75rem; padding: 0 var(--space-3); border-color: var(--ink); background: var(--ink); color: var(--paper); font-size: 0.875rem; }
.note-line { flex-basis: 100%; min-block-size: 1.5em; margin: 0; font-size: 0.875rem; color: var(--muted); }

/* ———— The graph itself ———— */

.rings circle, .rings ellipse { fill: none; stroke: var(--line); vector-effect: non-scaling-stroke; }
.rings .orphans { stroke: var(--muted); stroke-dasharray: 4 4; }
.rings text { fill: var(--muted); stroke: var(--paper); stroke-width: 4px; paint-order: stroke; text-anchor: middle; font-family: var(--font-sans); vector-effect: non-scaling-stroke; }
.rings .side { text-anchor: end; }
.edges line { stroke: var(--ink); stroke-opacity: 0.12; vector-effect: non-scaling-stroke; }
.nodes g { cursor: pointer; }
/* --zoom is set by graph.js: what sits on a node keeps its size on screen */
.nodes > g > :not(title) { transform: scale(calc(1 / var(--zoom, 1))); }
.graph.zoomed:not([data-view="solid"]) { cursor: grab; touch-action: none; }
.nodes .dot { fill: var(--ink); }
/* Heading Outliner marks errors with a red dashed outline; the same here */
.nodes .halo { display: none; fill: none; stroke: var(--signal); stroke-width: 2px; stroke-dasharray: 3 2; vector-effect: non-scaling-stroke; }
.nodes .error .halo { display: inline; }
.nodes text { display: none; fill: var(--muted); stroke: var(--paper); stroke-width: 3px; paint-order: stroke; text-anchor: middle; font-family: var(--font-sans); pointer-events: none; }
.nodes .named text, .nodes .on text, .nodes g:hover text { display: block; }
.graph.focus .edges line:not(.on) { stroke-opacity: 0.03; }
/* A chosen page: it and its neighbours come forward, the rest steps back */
.graph.focus .nodes g:not(.on, .out, .in) { opacity: 0.15; }
.graph.focus .nodes .in { opacity: 0.5; }
/* 3D draws the family tree; other links only for the chosen page */
.graph:not([data-view="rings"]) .edges line:not(.tree, .on) { display: none; }
/* :where keeps this below .on and .in, so a chosen tree edge still stands out */
.graph:where(:not([data-view="rings"])) .edges .tree { stroke-opacity: 0.4; }
.graph[data-view="solid"] { cursor: grab; touch-action: none; }
.graph .edges .on { stroke: var(--select); stroke-opacity: 0.9; stroke-width: 1.5px; }
/* Where you can go from the chosen page is solid and strong; what leads to it is
   dashed and quiet, since on most sites the menu leads everywhere */
.graph .edges .in { stroke-dasharray: 5 4; stroke-opacity: 0.35; stroke-width: 1px; }
.nodes .on .dot { fill: var(--select); transform: scale(1.9); transform-box: fill-box; transform-origin: center; }
.nodes .out .dot { fill: var(--paper); stroke: var(--select); stroke-width: 2px; vector-effect: non-scaling-stroke; }
.nodes .out text { display: block; fill: var(--ink); }
.nodes .on text { fill: var(--ink); font-weight: 600; }
.nodes .heads text { display: block; fill: var(--ink); dominant-baseline: middle; pointer-events: none; }
.heads circle { fill: var(--c); }
.heads line { stroke: var(--c); stroke-width: 1.5px; vector-effect: non-scaling-stroke; }

/* ———— Findings ———— */

.group { margin-block-end: var(--space-5); }
.group > h2 { padding-block-end: var(--space-2); border-block-end: 1px solid var(--line); }
.group:first-child > h2 { color: var(--signal); }

.finding { padding-block: var(--space-3); border-block-end: 1px solid var(--faint); max-inline-size: 46rem; }
.finding h3 { margin: 0; font-size: 1.125rem; line-height: 1.3; }
.finding .count { color: var(--muted); }
.finding .meaning { margin: var(--space-1) 0 var(--space-2); color: var(--muted); }

/* The site's list mark, ├─, and └─ for the last one */
.cases > div { display: grid; grid-template-columns: auto 1fr; column-gap: var(--space-1); margin-block-end: var(--space-1); }
.cases > div::before { content: "├─"; grid-row: span 2; font: 0.8125rem/1.9 var(--font-mono); color: var(--muted); }
.cases > div:last-of-type::before { content: "└─"; }
.what { overflow-wrap: anywhere; }

.pages { display: flex; flex-wrap: wrap; gap: var(--space-1); }

.page {
  padding: 0 0.3rem;
  border-color: var(--faint);
  font: 0.75rem/1.7 var(--font-mono);
  color: var(--select);
  overflow-wrap: anywhere;
  text-align: start;
}

.page:hover { border-color: var(--select); }
.more { padding: 0 var(--space-2); font-size: 0.8125rem; color: var(--muted); }

.lead { max-inline-size: 38rem; padding-block-start: var(--space-3); border-block-start: 1px solid var(--line); }
.lead ul { margin: 0; padding: 0; list-style: none; }
.lead li { margin-block-end: var(--space-2); color: var(--muted); }
.lead a { color: var(--ink); text-underline-offset: 0.2em; }

/* ———— Filters ———— */

.graph[hidden], .chart[hidden], .layers [hidden] { display: none; }
.graph.no-menu .edges .menu { display: none; }

/* ———— Charts ———— */

.chart { overflow: auto; max-block-size: 78vh; border: 1px solid var(--line); border-radius: var(--radius); background: var(--paper); color: var(--ink); }
.chart svg { display: block; font-family: var(--font-sans); font-size: 11px; }
.chart text:not([fill]) { fill: var(--ink); }
.note-line.chart-note { margin-block-start: var(--space-2); }

/* Flow */
.ribbon { opacity: 0.45; }
.ribbon:hover { opacity: 0.8; }
.chart .left { text-anchor: end; }
.chart .empty { fill: var(--muted); }

/* Tree */
.twig { fill: none; stroke: var(--line); stroke-width: 1.5px; }
.knot { cursor: pointer; }
.knot circle { fill: var(--paper); stroke: var(--select); stroke-width: 2px; }
.knot.shut circle { fill: var(--select); }
.knot.bad circle { stroke: var(--signal); }
.knot.bad.shut circle { fill: var(--signal); }
.knot.on circle { stroke: var(--ink); stroke-width: 3px; }
.chart .knot text { stroke: var(--paper); stroke-width: 4px; paint-order: stroke; }
.chart .knot.on text { font-weight: 600; }
.knot:hover text { text-decoration: underline; }
