/* Tessera CMap — styling for the d3 graph component.
 * Pair this with cmap.js and consume from any host that needs a
 * concept-graph view. Colours match the sc-family voice; hosts
 * that need a different palette can either:
 *   - override these custom properties under a parent scope, or
 *   - skip this stylesheet and ship their own equivalents.
 *
 * The component sets the SVG content; this file only styles it.
 */

/* ---- group meta-graph nodes (rounded rectangles) ---- */
.group-node { cursor: pointer; }
.group-box {
  fill: #fafaf7;
  stroke: var(--accent, #4f7c40);
  stroke-width: 2.5;
  transition: fill 100ms ease, stroke-width 100ms ease;
}
.group-node:hover .group-box {
  fill: #f3f7ee;
  stroke-width: 3.5;
  filter: drop-shadow(0 1px 4px rgba(74,112,48,0.25));
}
.group-title {
  font-size: 15px;
  font-weight: 600;
  fill: #2e4a25;
  pointer-events: none;
  user-select: none;
}
.group-kicker, .group-count {
  font-size: 11px;
  fill: #6b7280;
  pointer-events: none;
  user-select: none;
}
.group-bar { pointer-events: none; }
.group-bar-bg       { fill: #e5e7eb; }
.group-bar-mastered { fill: #4ade80; }
.group-bar-learning { fill: #fde68a; }
.group-bar-stuck    { fill: #fca5a5; }
.group-progress-text {
  font-size: 10px; font-weight: 500; fill: #6b7280;
  font-variant-numeric: tabular-nums; pointer-events: none;
}

/* ---- concept nodes (rounded rectangles, smaller) ---- */
.node { cursor: pointer; transition: opacity 200ms ease; }
.node-box {
  fill: #fff; stroke: var(--accent, #4f7c40); stroke-width: 2;
  transition: stroke-width 100ms ease;
}
.node[data-state="learning"] .node-box { fill: #fef3c7; stroke: #b45309; }
.node[data-state="mastered"] .node-box { fill: #166534; stroke: #166534; }
.node[data-state="stuck"]    .node-box { fill: #fee2e2; stroke: #b91c1c; }
.node.selected .node-box {
  stroke-width: 4;
  filter: drop-shadow(0 0 8px rgba(74,112,48,0.55));
}
.node.bridge .node-box {
  stroke-width: 1.3;
  stroke-dasharray: 2 2;
  opacity: 0.85;
}
.node.bridge .box-title { fill: #6b7280; }
.box-title {
  font-size: 12px; font-weight: 600;
  fill: #2e4a25; pointer-events: none; user-select: none;
  letter-spacing: -0.005em;
}
/* State-driven text colours come AFTER bridge so they win the
 * source-order tie-break (same specificity). Without this, a
 * mastered bridge shows gray text on dark green — unreadable. */
.node[data-state="learning"] .box-title { fill: #7a4a05; }
.node[data-state="mastered"] .box-title { fill: #fff;    }
.node[data-state="stuck"]    .box-title { fill: #7c1d12; }

/* ---- edges ---- */
.link { stroke: rgba(70,80,60,0.45); stroke-width: 1.2px; fill: none; }
.link.prereq    { stroke-width: 1.8px; stroke: rgba(70,80,60,0.65); }
.link.extends   { stroke-dasharray: 4 3; }
.link.co-occurs { stroke-dasharray: 1 3; opacity: 0.55; }
