/* Dark theme matching the SharePoint original closely enough that the team
   recognises it, without inheriting its layout problems. */

:root {
  --bg: #0d0b0c;
  --panel: #141112;
  --panel-2: #1b1719;
  --line: #2e2729;
  --text: #ece7e8;
  --muted: #9b9092;
  --accent: #c98bdb;
  --accent-line: #d264c8;
  --blue-line: #4a8fd4;
  --green: #4ec98b;
  --amber: #e0b341;
  --red: #e06a5a;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.5 "Segoe UI", system-ui, sans-serif;
}

a { color: inherit; }

.masthead {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.25rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  margin: 1rem;
  background: var(--panel);
}
.masthead h1 { margin: 0; font-family: Georgia, serif; font-size: 2rem; }
.subtitle { margin: .35rem 0 0; color: var(--muted); font-size: .9rem; }
.who { color: var(--muted); }

/* --- main navigation ----------------------------------------------------- */

.mainnav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .3rem;
  font-size: .85rem;
}
/* Separates the account corner from the section links. A rule rather than a
   flexible gap: the masthead sizes the nav to its content, so a spring here
   would have nothing to push against. */
.nav-gap {
  width: 1px;
  align-self: stretch;
  min-height: 1.4rem;
  background: var(--line);
  margin: 0 .55rem;
}
.mainnav .who { margin-right: .3rem; }

.navlink {
  padding: .4rem .8rem;
  border: 1px solid transparent;
  border-radius: 7px;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color .12s, background .12s, border-color .12s;
}
.navlink:hover { color: var(--text); background: var(--panel-2); border-color: var(--line); }

/* The current section is stated, not merely hinted: same treatment as a
   selected node in the tree, so "where am I" reads the same everywhere. */
.navlink.is-current {
  color: var(--accent);
  background: linear-gradient(135deg, #3a2246, #2a1c33);
  border-color: var(--accent-line);
  font-weight: 600;
}

/* Admin is a way out of the app rather than a part of it. */
.navlink-quiet { color: var(--muted); font-size: .8rem; }
.navlink-quiet:hover { color: var(--text); }

/* Narrow: the masthead's title and nav stop competing for one row. Left to
   itself the nav is squeezed into a column barely wider than one word. */
@media (max-width: 640px) {
  .masthead { flex-direction: column; align-items: stretch; }
  .mainnav { width: 100%; }
  .nav-gap { display: none; }
  .mainnav .who { margin-left: auto; }
}

main { margin: 0 1rem 2rem; }

/* --- messages ----------------------------------------------------------- */

.messages { list-style: none; margin: 0 0 1rem; padding: 0; display: grid; gap: .4rem; }
.message {
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: 8px;
  background: var(--panel-2);
  padding: .55rem .8rem;
  font-size: .85rem;
}
.message-success { border-left-color: var(--green); }
.message-info    { border-left-color: var(--blue-line); }
.message-warning { border-left-color: var(--amber); }
.message-error   { border-left-color: var(--red); }

/* --- stats ------------------------------------------------------------- */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: .75rem;
  margin-bottom: 1rem;
}
.stat {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  padding: 1rem 1.1rem;
}
.stat b { display: block; font-family: Georgia, serif; font-size: 1.9rem; font-weight: 400; }
.stat span { color: var(--muted); font-size: .8rem; }

/* --- tree -------------------------------------------------------------- */

.tree {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  padding: 1rem 1.25rem 1.25rem;
}
.tree h2 {
  margin: 0;
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}
.tree-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: .75rem;
}

/* --- view / edit toggle -------------------------------------------------- */

.mode-toggle {
  display: inline-flex;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--panel-2);
  padding: 2px;
}
.mode {
  padding: .22rem .7rem;
  border-radius: 5px;
  font-size: .76rem;
  color: var(--muted);
  text-decoration: none;
}
.mode:hover { color: var(--text); }
.mode.is-current {
  background: linear-gradient(135deg, #3a2246, #2a1c33);
  color: var(--accent);
  font-weight: 600;
}
.mode-static {
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px dashed var(--line);
  border-radius: 7px;
  padding: .2rem .55rem;
}
.who-role {
  margin-left: .4rem;
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .05rem .45rem;
}

.columns {
  position: relative; /* the SVG connector layer positions against this */
  display: flex;
  gap: 2.5rem;
  align-items: flex-start;
  overflow-x: auto;
  /* Vertical: the strip is as tall as its content, so there is nothing to
     scroll to -- and hiding it stops the connector overlay, which is sized to
     the scroll extent, from provoking a stray scrollbar of its own. */
  overflow-y: hidden;
  padding: 1rem .25rem;
  background: repeating-radial-gradient(circle at 0 0, #1a1618 0 1px, transparent 1px 14px);
  border-radius: 8px;
  /* No `scroll-behavior: smooth` here on purpose: it would override
     scrollTo({behavior:"auto"}) and animate the initial page load too.
     tree.js decides per call whether to animate. */
}

/* Connector lines, drawn by tree.js. Sits behind the boxes and ignores the
   pointer so it can never intercept a click on a node. */
.tree-links {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  z-index: 0;
  overflow: visible;
}
.link {
  fill: none;
  stroke: var(--blue-line);
  stroke-width: 2;
  opacity: .55;
}
.link-active {
  stroke: var(--accent-line);
  opacity: .95;
}
/* Fixed width, not min-width: a long option label ("Recommend this resource for
   my organisation.") would otherwise stretch its whole column. Let it wrap. */
.column { flex: 0 0 auto; width: 190px; display: flex; flex-direction: column; gap: .65rem; }
/* The last column holds a select and a Save button, so it needs more room. */
.column-leaf { width: 240px; }
.column-head {
  font-size: .68rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .25rem;
}

.node {
  /* Positioned so it paints above the connector layer. Deliberately NOT on
     .column: making the column positioned would make it the offsetParent, and
     tree.js measures node offsets against .columns. */
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "label dot" "count dot";
  gap: 0 .5rem;
  padding: .6rem .75rem;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel-2);
  text-decoration: none;
  transition: border-color .12s, background .12s;
}
.node:hover { border-color: var(--accent); background: #241d26; }
.node.is-selected {
  background: linear-gradient(135deg, #3a2246, #2a1c33);
  border-color: var(--accent-line);
}
.node.is-selected .node-label { color: var(--accent); }
.node-label { grid-area: label; font-weight: 600; font-size: .9rem; overflow-wrap: anywhere; }
.node-count { grid-area: count; color: var(--muted); font-size: .74rem; }
.dot { grid-area: dot; width: 11px; height: 11px; border-radius: 50%; align-self: center; }
.dot-green { background: var(--green); }
.dot-amber { background: var(--amber); }
.dot-red   { background: var(--red); }

/* --- leaf cards -------------------------------------------------------- */

.leaf {
  position: relative; /* see .node -- paints above the connector layer */
  z-index: 1;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel-2);
  padding: .75rem;
  width: 100%;
}
.leaf.is-assigned { border-color: #2f5c46; background: #14201a; }
.leaf-head { display: flex; align-items: center; gap: .5rem; margin-bottom: .6rem; }
.field-label {
  display: block;
  font-size: .66rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .25rem;
}
.leaf select {
  width: 100%;
  padding: .4rem .5rem;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #0f0d0e;
  color: var(--text);
}
.leaf .save {
  margin-top: .6rem;
  width: 100%;
  padding: .45rem;
  border-radius: 6px;
  border: 1px solid var(--accent-line);
  background: #2a1c33;
  color: var(--text);
  cursor: pointer;
  font-weight: 600;
}
.leaf .save:hover { background: #3a2246; }
.open-link { display: inline-block; margin-top: .5rem; font-size: .78rem; color: var(--accent); }

/* --- leaf card, view mode ------------------------------------------------ */

/* The chosen name, read-only: text rather than a disabled control, because a
   disabled control still looks like something that ought to work. */
.chosen {
  margin: 0 0 .6rem;
  font-size: .88rem;
  font-weight: 600;
  overflow-wrap: anywhere;
}
.chosen-none { color: var(--muted); font-weight: 400; font-style: italic; }

/* The primary call to action in view mode: the document itself. */
.open-primary {
  display: block;
  text-align: center;
  padding: .45rem;
  border-radius: 6px;
  border: 1px solid var(--accent-line);
  background: #2a1c33;
  color: var(--text);
  font-weight: 600;
  font-size: .85rem;
  text-decoration: none;
}
.open-primary:hover { background: #3a2246; }

/* Secondary, and deliberately much quieter: editing is the rarer job here. */
.leaf-secondary {
  display: inline-block;
  margin-top: .55rem;
  font-size: .76rem;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px dotted var(--line);
}
.leaf-secondary:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* --- template combobox -------------------------------------------------- */

/* The native select stays in the form -- it is what gets submitted -- and is
   hidden only once tree.js has put a searchable control in front of it. */
.combo-native { display: none; }
.combo { position: relative; }
.combo-field { display: flex; align-items: stretch; gap: .3rem; }
.combo-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: .4rem .5rem;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #0f0d0e;
  color: var(--text);
  font: inherit;
  font-size: .85rem;
}
.combo-input:focus { outline: none; border-color: var(--accent); }
.combo-input::placeholder { color: var(--muted); }
.combo-clear {
  flex: 0 0 auto;
  width: 1.7rem;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #0f0d0e;
  color: var(--muted);
  cursor: pointer;
  line-height: 1;
}
.combo-clear:hover { color: var(--text); border-color: var(--accent); }
.combo.is-empty .combo-clear { visibility: hidden; }

.combo-list {
  list-style: none;
  margin: .3rem 0 0;
  padding: .2rem;
  max-height: 15rem;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #0f0d0e;
}
.combo-option {
  padding: .34rem .45rem;
  border-radius: 5px;
  font-size: .82rem;
  cursor: pointer;
  overflow-wrap: anywhere;
}
.combo-option-none { color: var(--muted); font-style: italic; }
.combo-option.is-chosen { color: var(--accent); }
.combo-option.is-active { background: #2a1c33; }
.combo-option mark { background: transparent; color: var(--accent); font-weight: 700; }
.combo-empty { padding: .4rem .45rem; color: var(--muted); font-size: .8rem; }

/* --- add a template from the leaf --------------------------------------- */

.add-template { margin-top: .7rem; border-top: 1px solid var(--line); padding-top: .55rem; }
.add-template > summary {
  cursor: pointer;
  color: var(--muted);
  font-size: .78rem;
  list-style: none;
}
.add-template > summary::-webkit-details-marker { display: none; }
.add-template > summary:hover { color: var(--accent); }
.add-template[open] > summary { color: var(--accent); margin-bottom: .5rem; }
.add-template label { display: block; margin-bottom: .45rem; }
.add-template input {
  width: 100%;
  padding: .4rem .5rem;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #0f0d0e;
  color: var(--text);
  font: inherit;
  font-size: .85rem;
}
.add-template input:focus { outline: none; border-color: var(--accent); }
.add-template .hint { font-size: .72rem; margin-top: .45rem; }

.hint { color: var(--muted); font-size: .82rem; margin: .9rem 0 0; }
.empty { color: var(--muted); font-size: .82rem; }

/* --- library pages ------------------------------------------------------ */

/* Same shell as .tree, reused by every panel on the library pages. */
.panel {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel);
  padding: 1rem 1.25rem 1.25rem;
  margin-bottom: 1rem;
}
.panel h2 {
  margin: 0 0 .75rem;
  font-size: .72rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
}
.crumb { margin: 0 0 .75rem; font-size: .82rem; }
.crumb a { color: var(--accent); text-decoration: none; }

.searchbar { display: flex; gap: .5rem; margin-bottom: .9rem; }
.searchbar input {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 32rem;
  padding: .45rem .6rem;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #0f0d0e;
  color: var(--text);
  font: inherit;
  font-size: .88rem;
}
.searchbar input:focus { outline: none; border-color: var(--accent); }
.searchbar input::placeholder { color: var(--muted); }
.searchbar button {
  padding: .45rem .9rem;
  border-radius: 6px;
  border: 1px solid var(--accent-line);
  background: #2a1c33;
  color: var(--text);
  cursor: pointer;
  font: inherit;
  font-size: .85rem;
}
.searchbar button:hover { background: #3a2246; }

.count { color: var(--muted); font-size: .82rem; margin: 0 0 .75rem; }

.table { width: 100%; border-collapse: collapse; font-size: .87rem; }
.table th {
  text-align: left;
  font-size: .66rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  padding: .4rem .6rem;
  border-bottom: 1px solid var(--line);
}
.table td { padding: .5rem .6rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.table tbody tr:hover { background: var(--panel-2); }
.table .num { text-align: right; white-space: nowrap; }
.table .url { color: var(--muted); overflow-wrap: anywhere; max-width: 32rem; }
.row-link { color: var(--accent); text-decoration: none; font-weight: 600; }
.row-link:hover { text-decoration: underline; }

/* --- the route table ----------------------------------------------------- */

/* Ten questions plus a link do not fit 1080p at full width, so the columns are
   equal and fixed and the text truncates -- each cell carries its full value as
   a hover tooltip. `table-layout: fixed` is what makes text-overflow work in a
   table cell at all; without it the cell would just grow. The wrapper still
   scrolls sideways, so a narrow window degrades rather than clips. */
/* Scrolls in both axes, and that is deliberate: a page of 100 routes scrolled
   at page level would take its headers with it, and ten unlabelled columns are
   unreadable. Capping the region here is what lets the header stay put --
   `position: sticky` resolves against the nearest scrolling ancestor, and a
   horizontal scroller is one whether or not it also scrolls vertically. */
.route-scroll { overflow: auto; max-height: 70vh; }
.route-table { table-layout: fixed; width: 100%; min-width: 44rem; }
.route-table th,
.route-table td {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: .45rem .55rem;
}
/* Long labels earn no more room than short ones: an even grid is what makes a
   column scannable top-to-bottom. */
.route-table th { cursor: help; }
.route-table td { cursor: default; }
.route-table td.empty { font-style: italic; }

/* The header stays put while a hundred routes scroll past it -- without it the
   columns lose their meaning two screens down. */
.route-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--panel);
}

/* Just wide enough for the arrow; every other column shares what is left. */
.route-table .route-open { width: 2.2rem; text-align: right; }
.route-table .route-open a { font-size: 1rem; text-decoration: none; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.pager { display: flex; align-items: center; gap: 1rem; margin-top: .9rem; font-size: .82rem; }
.pager a { color: var(--accent); text-decoration: none; }
.pager a:hover { text-decoration: underline; }
.pager .is-disabled { color: var(--line); }
.pager-where { color: var(--muted); }

.detail-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1rem;
}
.detail-head .stats { margin-bottom: 0; min-width: 22rem; }
.detail-name { margin: 0 0 .35rem; font-family: Georgia, serif; font-size: 1.6rem; }
.detail-head .open-link { margin-top: 0; overflow-wrap: anywhere; }

.edit-template {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: .75rem;
  border-top: 1px solid var(--line);
  padding-top: .9rem;
}
.edit-template label { display: block; flex: 1 1 18rem; }
.edit-template input {
  width: 100%;
  padding: .45rem .6rem;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #0f0d0e;
  color: var(--text);
  font: inherit;
  font-size: .88rem;
}
.edit-template input:focus { outline: none; border-color: var(--accent); }
.edit-template .save { flex: 0 0 auto; width: auto; padding: .5rem 1rem; }
.edit-template .hint { flex: 1 1 100%; margin: 0; }

.filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .6rem; margin-bottom: .9rem; }
.filters label { display: block; }
.filters select {
  padding: .38rem .5rem;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #0f0d0e;
  color: var(--text);
  font: inherit;
  font-size: .82rem;
}
.filters .save { width: auto; margin-top: 0; padding: .4rem .9rem; }
.clear-filters { color: var(--muted); font-size: .8rem; padding-bottom: .45rem; }
.clear-filters:hover { color: var(--accent); }

.history { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; font-size: .83rem; }
.history li { padding: .4rem .6rem; border-left: 2px solid var(--line); background: var(--panel-2); border-radius: 0 6px 6px 0; }
.history .when { color: var(--muted); margin-right: .5rem; }
.history .was { color: var(--muted); text-decoration: line-through; }
.history .now { color: var(--accent); }
.history .who { color: var(--muted); margin-left: .5rem; }

/* --- sign in ------------------------------------------------------------ */

/* Narrow and centred: the page asks for two things, so it should not present
   itself with the full width of the tree behind it. */
.signin { max-width: 22rem; margin: 3rem auto; }
.signin-form {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-2);
  padding: 1.25rem 1.3rem;
}
.signin-field { margin: 0 0 .9rem; }
.signin-field label {
  display: block;
  margin-bottom: .3rem;
  color: var(--muted);
  font-size: .8rem;
}
.signin-field input {
  width: 100%;
  padding: .5rem .6rem;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #0f0d0e;
  color: var(--text);
  font: inherit;
}
.signin-field input:focus { outline: none; border-color: var(--accent); }
.signin-error { display: block; margin-top: .3rem; color: var(--red); font-size: .8rem; }
.signin-submit {
  width: 100%;
  padding: .55rem 1rem;
  border-radius: 7px;
  border: 1px solid var(--accent-line);
  background: #2a1c33;
  color: var(--text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.signin-submit:hover { background: #3a2246; }

/* The sign-out control is a form, because logging out is a POST. It has to
   sit in the nav's row of links without looking like the odd one out. */
.signout { display: inline; margin: 0; }
.signout button {
  border: 1px solid transparent;
  background: none;
  font: inherit;
  cursor: pointer;
}
