/* Additions to Tabler — only what Tabler does not bring along.
 *
 * Layout, cards, forms, tables and buttons come entirely from Tabler. What
 * lives here are the chart colour roles and the few building blocks there is no
 * Tabler component for (a group's colour dot, the tooltip of the SVG charts,
 * the context map grid).
 *
 * The categorical colours come from a palette checked for colour vision
 * deficiency and are deliberately NOT the Tabler colours. Roles 1-8 are the
 * documented default palette, 9-12 were computed against them: largest minimum
 * distance in OKLab, including under protanopia and deuteranopia.
 *
 * What is verified is the neighbourhood comparison (stacked bar, legend) on a
 * light ground. Five roles fall below 3:1 contrast against the surface — which
 * is why every bar carries a visible label and there is a table view.
 *
 * For a scatter plot, where every colour is read against every other, twelve
 * distances are not enough. The topic map still colours by participant — but
 * identity does not hang on colour alone there: a legend with names, a tooltip
 * on every point, and hovering a legend entry narrows the plot to that
 * participant. The insights tab of a participant page keeps the older rule and
 * highlights the selection instead of colouring it.
 */
:root {
  --series-1: #2a78d6;
  --series-2: #eb6834;
  --series-3: #1baf7a;
  --series-4: #eda100;
  --series-5: #e87ba4;
  --series-6: #008300;
  --series-7: #4a3aa7;
  --series-8: #e34948;
  --series-9: #7c4003;
  --series-10: #9b0170;
  --series-11: #60b5e7;
  --series-12: #b17eff;

  /* Chart chrome tied to Tabler so that areas and lines match the rest of the
     page. */
  --surface:        var(--tblr-bg-surface, #fff);
  --text-primary:   var(--tblr-body-color, #182433);
  /* Chart labels stay neutral: in the ATIP theme --tblr-secondary is a blue
     (#2858a5) and would read like a link on an axis. */
  --text-secondary: var(--tblr-secondary-color, #667382);
  --grid:           var(--tblr-border-color, #e6e7e9);
  --axis:           var(--tblr-border-color-active, #c8cbcf);
  --neutral-mark:   #c8cbcf;
}

/* ---------- SVG charts ---------- */
svg { display: block; max-width: 100%; }
svg text { fill: var(--text-secondary); font-size: 11px; }

/* ---------- A group's colour dot ---------- */
/* Identity is carried by the dot next to the text, never by the text colour. */
.group-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 3px;
  flex: none;
}

.group-toggle {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
}
.group-toggle-off {
  opacity: .45;
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-size: .8125rem;
  color: var(--text-secondary);
  margin-right: 1rem;
}

/* ---------- Topic list ---------- */
.topic-row {
  text-align: left;
  cursor: pointer;
}
/* Tabler colours .active strongly; a quiet marker is enough here so the list
   does not dominate next to the map. */
.list-group-item.topic-row.active {
  background: var(--tblr-active-bg, #f5f6f7);
  color: inherit;
  border-color: var(--grid);
  font-weight: 600;
}

/* ---------- Example sections ---------- */
.example {
  border-left: 2px solid var(--grid);
  padding: .125rem 0 .125rem .875rem;
}
.example + .example { margin-top: .875rem; }
.example p { margin: 0; font-size: .875rem; color: var(--text-secondary); }

/* ---------- Chart tooltip ---------- */
/* Not .tooltip: that class belongs to Bootstrap. */
.tooltip-panel {
  position: fixed;
  z-index: 1080;
  pointer-events: none;
  max-width: 320px;
  background: var(--surface);
  border: 1px solid var(--axis);
  border-radius: var(--tblr-border-radius, 4px);
  padding: .5rem .625rem;
  box-shadow: var(--tblr-box-shadow-dropdown, 0 8px 24px rgba(0, 0, 0, .12));
  font-size: .8125rem;
  line-height: 1.45;
}
.tooltip-panel .headline { font-weight: 600; color: var(--text-primary); }
.tooltip-panel .sub { color: var(--text-secondary); margin-top: .125rem; }
.tooltip-panel .row {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin: .3125rem 0 0;
  color: var(--text-secondary);
}
.tooltip-panel .row .stroke { width: 14px; height: 2px; border-radius: 1px; flex: none; }
.tooltip-panel .row .val { color: var(--text-primary); font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---------- Loading state ---------- */
/* While reloading, leave the previous drawing dimmed in place — no skeleton,
   no layout jump. */
.card.loading { opacity: .45; transition: opacity .15s ease; }

/* ---------- Visibility ---------- */
/* Bootstrap's utilities are !important: an element with .d-flex would stay
   visible despite the hidden attribute (the insights error alert, for one).
   Hence the counter rule — it applies to every hidden element on the page. */
[hidden] { display: none !important; }

/* ---------- Context Map (Concierge) ---------- */
/* Rebuild of the cross table from the aBF frontend so that participants
   recognise the same view: CSS grid instead of a table, first column 181px,
   data columns 2.5rem, row height 2.5rem, header row 129px — the same
   measurements as there. Colours and borders come from Tabler. */
.context-map-scroll {
  overflow-x: auto;
  border: 1px solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius);
}

.context-map-grid {
  display: grid;
  grid-template-columns: 181px repeat(calc(var(--grid-columns) - 1), 2.5rem);
  grid-template-rows: 129px;
  grid-auto-rows: 2.5rem;
  width: fit-content;
  min-width: 100%;
}

.context-map-grid .grid-cell {
  display: flex;
  align-items: center;
  gap: .25rem;
  padding: 0 .5rem;
  min-width: 0;
  border-right: 1px solid var(--tblr-border-color);
  border-bottom: 1px solid var(--tblr-border-color);
  background: var(--tblr-bg-surface);
  transition: background-color .15s ease;
}

/* Header row and first column stay put while scrolling. */
.context-map-grid .column-header,
.context-map-grid .grid-corner {
  position: sticky;
  top: 0;
  z-index: 2;
}
.context-map-grid .sticky-left {
  position: sticky;
  left: 0;
  z-index: 3;
  overflow: hidden;
}
.context-map-grid .grid-corner { z-index: 4; }

/* Axis labels: upright in the column headers (as in the aBF frontend's
   concierge) and toned down — they are the grid, not the content. The content
   is the ticks. */
.context-map-grid .column-header,
.context-map-grid .row-header,
.context-map-grid .grid-corner { background: var(--tblr-bg-surface-tertiary, #f6f7f9); }
.context-map-grid .column-header span,
.context-map-grid .row-header span {
  font-size: .8125rem;
  color: var(--tblr-secondary-color);
}
.context-map-grid .column-header {
  align-items: flex-end;
  justify-content: center;
  padding: .5rem .25rem;
}
/* vertical-rl reads top to bottom; the half turn flips it so the text runs
   bottom to top and starts at the cell edge. */
.context-map-grid .column-header span {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  max-height: 100%;
}

/* Crosshair: shows on hover which pair a cell belongs to. */
.context-map-grid .grid-cell.crosshair { background: var(--tblr-active-bg, #f5f6f7); }

/* The cell itself: a green tick means taken, otherwise a dashed plus appears
   on hover as an invitation. */
.context-map-grid .intent-cell {
  justify-content: center;
  cursor: pointer;
  padding: 0;
}
.context-map-grid .intent-cell .intent-on,
.context-map-grid .intent-cell .intent-off {
  font-size: 1.125rem;
  transition: transform 120ms ease-in-out, opacity 120ms ease-in-out;
}
.context-map-grid .intent-cell .intent-on { color: var(--tblr-green); display: none; }
.context-map-grid .intent-cell .intent-off { color: var(--tblr-secondary-color); opacity: 0; }
.context-map-grid .intent-cell.is-active .intent-on { display: inline-flex; }
.context-map-grid .intent-cell.is-active .intent-off { display: none; }
.context-map-grid .intent-cell:hover .intent-off,
.context-map-grid .intent-cell:focus-visible .intent-off { opacity: 1; }
.context-map-grid .intent-cell:hover .intent-on,
.context-map-grid .intent-cell:focus-visible .intent-on { transform: scale(1.3); }
.context-map-grid .intent-cell.is-busy { opacity: .4; pointer-events: none; }

/* The search field in the corner sits flush in the 181px column. */
.context-map-grid .grid-corner .input-icon { width: 100%; }
.context-map-grid .grid-corner .form-control { border: 0; background: transparent; padding-left: 1.75rem; }
.context-map-grid .grid-corner .form-control:focus { box-shadow: none; }

@media (prefers-reduced-motion: reduce) {
  .context-map-grid .intent-cell .intent-on,
  .context-map-grid .intent-cell .intent-off { transition: none; }
}


/* ---------- Partner row in the hero ---------- */
/* Genesys and atip host the hackathon together and therefore stand side by
   side as equals: same optical height, same surroundings, no ranking. They sit
   top left, before title and text. Sizing through height only — the original
   files stay untouched (see img/README.md). The two marks are cropped
   differently, hence two values: the atip PNG carries padding at top and
   bottom, the Genesys SVG fills its box. */
.partner-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* No character between the marks: a × reads like a delete icon, a slash like
     an alternative. The gap alone separates them. */
  gap: 1.25rem 3rem;
}
.partner-logo { width: auto; height: 2.25rem; }
.partner-logo-atip { height: 3.25rem; }

/* The hero illustration carries no information — it shows the way of working.
   So it sits on the right, scales along and stays limited in width so that it
   does not outshout the text. unDraw art is recoloured to the primary colour
   (see img/README.md), never left in its original violet. */
.hero-illustration {
  display: block;
  width: 100%;
  max-width: 24rem;
  height: auto;
  margin-inline: auto;
}


/* ---------- Explainer strip ---------- */
/* Sits at the top of a tab where a card subtitle would otherwise be: not what
   the view is, but what is expected from the participants. The illustration is
   decoration and carries no information — hence `alt=""` and no space taken
   away from the text. */
.explainer {
  display: flex;
  flex-wrap: wrap;
  /* Text oben, nicht mittig: bei zwei Zeilen sähe zentriert noch gleich aus,
     bei vier hinge die Überschrift in der Luft. */
  align-items: flex-start;
  gap: 1rem 1.5rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius, 4px);
  background: var(--tblr-bg-surface-tertiary, #f6f7f9);
}
.explainer-icon { flex: none; width: 5.5rem; height: auto; }
/* Without its own flex basis the text block would drop below the image instead
   of shrinking: with `wrap` it is the max-content width that decides the break,
   not flex-shrink. 18rem is the width below which it should wrap. */
.explainer-text { flex: 1 1 18rem; min-width: 0; }
.explainer-title { margin: 0; font-size: 1rem; font-weight: 600; }
.explainer p {
  margin: .375rem 0 0;
  font-size: .875rem;
  color: var(--text-secondary);
}

/* ---------- Participant logos ---------- */
/* Uploaded files come in every crop and aspect ratio, so the height is fixed
   and the width follows — a logo must not push the row it sits in. */
.participant-logo {
  width: auto;
  height: 2rem;
  max-width: 10rem;
  object-fit: contain;
  vertical-align: middle;
}
.participant-logo-sm { height: 1.25rem; max-width: 6rem; }
.participant-logo-lg { height: 3rem; max-width: 14rem; }

/* ---------- Drag handle ---------- */
/* A row is only dragged by its handle, not by the whole row: the cells contain
   links and buttons that have to stay clickable. */
.drag-handle {
  display: inline-flex;
  color: var(--tblr-secondary-color);
  cursor: grab;
}
.drag-handle:active { cursor: grabbing; }
tr.is-dragging { opacity: .4; }

/* ---------- Mindmap ---------- */
/* Root on the left, branches to the right (planning page, drawn by
   planning.js). One series colour per branch on links and dots; the text stays
   in the body colour so the map reads without colour. The SVG keeps a minimum
   width and scrolls sideways on narrow screens — shrinking it would make the
   labels unreadable. */
.mindmap { overflow-x: auto; }
.mindmap svg {
  display: block;
  max-width: 100%;
  min-width: 36rem;
  height: auto;
  font-size: .875rem;
}
.mindmap .link { fill: none; stroke: currentColor; stroke-width: 1.5; opacity: .6; }
.mindmap .node circle { fill: currentColor; }
/* A halo in the surface colour keeps a label legible where a line still
   crosses it. */
.mindmap .node text {
  fill: var(--text-primary);
  paint-order: stroke;
  stroke: var(--surface);
  stroke-width: 3px;
  stroke-linejoin: round;
}
.mindmap .node.depth-0 text,
.mindmap .node.depth-1 text { font-weight: 600; }
/* A label with sources is a link: the marker behind it says so, hovering
   underlines the text. The marker is the Tabler icon as a webfont inside a
   foreignObject — the one way to keep icons a webfont inside SVG (point 3 of
   the idiom checklist). */
.mindmap a { cursor: pointer; }
.mindmap a:hover text { text-decoration: underline; }
.mindmap .marker { overflow: visible; }
.mindmap .marker i {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: .8125rem;
  color: var(--tblr-secondary-color);
}

/* ---------- Corner ribbon ---------- */
/* A diagonal band across the top right corner of a card: it carries the
   number or kind of the card ("Idee 1"), so the title stays free for what the
   card is about. Tabler's .ribbon is a straight tag on the edge; this is the
   corner variant. The box clips the rotated band at the card's edges — the
   card itself keeps its overflow, so nothing else inside gets cut. */
.ribbon-corner {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 1;
  width: 5.5rem;
  height: 5.5rem;
  overflow: hidden;
  pointer-events: none;
  border-top-right-radius: var(--tblr-card-border-radius, var(--tblr-border-radius, 4px));
}
.ribbon-corner span {
  position: absolute;
  top: 1.25rem;
  right: -2.1rem;
  width: 8rem;
  padding: .25rem 0;
  transform: rotate(45deg);
  text-align: center;
  font-size: .6875rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--tblr-primary-fg, #fff);
  background: var(--tblr-primary);
}
/* Whatever opens the card body — title or placeholder — must not run under
   the band. */
.ribbon-corner + .card-body > :first-child { padding-right: 3.25rem; }

/* ---------- Sign-in page ---------- */
/* The atip background from the AI Lab behind the sign-in card. #021B2C is the
   ground while the image loads — the darkest blue of the image, so the white
   footer stays legible from the first paint. The wordmark is part of the
   image, hence nothing above the card. */
.login-page {
  background: #021b2c url("img/atip_background.png") center / cover no-repeat;
}

/* ---------- Copy on click ---------- */
/* A masked secret is a button (copy.js): it keeps the look of the code next
   to it and shows by the cursor and the hover that a click does something. */
.copy-secret code { cursor: copy; }
.copy-secret:hover code,
.copy-secret:focus-visible code { background: var(--tblr-primary-lt, #e8eef7); }
