/* The skills tree, concept C: every sub skill across the whole degree.

   Ported from the approved mockup, and scoped: every selector starts at the
   tree's root, [data-skills-tree], or at Growth's, [data-growth], so nothing
   here reaches the rest of the portfolio, and nothing of the mockup's page
   frame came across. Growth prints the tree's summary parts (Coming up, the
   ideas for the student's own work, the notes), so their rules start at
   either root; its own layout has a section of its own near the end.

   Wide or narrow is a container query on the root, not the screen, so the
   tree fits the Canvas frame it sits in. The wide drawing shows from a root
   790px wide, where it is drawn at 0.88 of its size: the same narrowest scale
   the mockup allowed at its 880px screen. The narrow drawing is the default,
   so a browser without container queries still gets a whole tree.

   What the script adds (the Tree / List switch, Close, the keyboard tip, the
   floating module lists, a little motion) has its rules under html.st-js, a
   class only the tree's own script sets, in a section of its own near the
   end. Without it everything else here works as it stands.

   Colour: never a side rail, and the brand red only on the standard's line
   and its pill. Small text is --muted-small, which keeps 4.5:1 on white and on
   every tint the tree uses. */

/* ---------- the root ----------
   The tree's root and Growth's share the tokens and the type. */
:is([data-skills-tree], [data-growth]) {
  --muted-small: #596170;  /* 6.2:1 on white, 5.4:1 on --now-bg: all muted text */
  /* The tree sits on the white card. Its quiet parts, from quietest up. */
  --band: #f5f6f8;         /* the graduate band */
  --now-bg: #eef1f6;       /* the column for now, a selected row, an open module */
  --lit-bg: #e6ebf3;       /* a module lit from a timeline */
  --track: #d3d8e0;        /* the unreached part of a path */
  --line: #c4cad4;         /* the trunk and the stems */
  --dot: #767d89;          /* dotted stems, empty columns, ahead nodes: 4.15:1, over the 3:1 for graphics */
  container-type: inline-size;
  margin-top: 4px;
  color: var(--ink);
  font-family: Arial, Helvetica, sans-serif;
  font-size: 14px;
  line-height: 1.45;
}
[data-skills-tree] {
  /* The drawings' widths, so HTML laid between slices can line up with them. */
  --vb: 372;
  --trunk-x: 18;
  --panel-x: 30;           /* where an open timeline starts: under its row's highlight */
  container-name: skills-tree;
}
[data-growth] { container-name: growth; }
[data-skills-tree],
[data-skills-tree] *,
[data-skills-tree] *::before,
[data-skills-tree] *::after { box-sizing: border-box; }
[data-skills-tree] [hidden] { display: none !important; }
[data-skills-tree] button { font-family: inherit; }
/* The app's links are the brand red; the tree's are ink, since red here means the standard. */
[data-skills-tree] a,
[data-skills-tree] a:hover { color: inherit; }
[data-skills-tree] button:focus-visible,
[data-skills-tree] a:focus-visible,
[data-skills-tree] summary:focus-visible,
[data-skills-tree] input:focus-visible,
[data-skills-tree] [tabindex]:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}
[data-skills-tree] .visually-hidden { padding: 0; margin: -1px; border: 0; }

/* ---------- the card ---------- */
[data-skills-tree] .tree-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 18px 16px 20px;
  overflow: hidden;
}
[data-skills-tree] .tc-head { display: flex; justify-content: space-between; align-items: center; gap: 4px 16px; flex-wrap: wrap; }
[data-skills-tree] .tc-title { font-size: 19px; font-weight: bold; margin: 0; }
/* Tree or List: the script's to show, since only the script can switch. */
[data-skills-tree] .view-switch { display: none; background: #edeff3; border-radius: 9px; padding: 3px; gap: 3px; }
[data-skills-tree] .st-segment {
  border: 0; background: transparent; border-radius: 7px; padding: 8px 16px;
  font-size: 13px; font-weight: bold; color: var(--muted-small); cursor: pointer;
}
[data-skills-tree] .st-segment:hover { color: var(--ink); }
[data-skills-tree] .st-segment[aria-pressed="true"] { background: var(--surface); color: var(--ink); }

/* What could not be read just now: plain words, in ink, on the card's quiet grey. */
:is([data-skills-tree], [data-growth]) .st-notes {
  margin: 12px 0 0; padding: 10px 14px; border-radius: 10px; background: var(--surface-muted);
  font-size: 13px; color: var(--ink);
}
:is([data-skills-tree], [data-growth]) .st-notes p { margin: 0; max-width: 90ch; }
:is([data-skills-tree], [data-growth]) .st-notes p + p { margin-top: 4px; }

[data-skills-tree] .summary {
  display: grid; grid-template-columns: 1fr; gap: 18px;
  margin-top: 16px; padding: 18px 20px; background: var(--surface-muted); border-radius: 10px;
}
[data-skills-tree] .big { margin: 0; font-size: 44px; font-weight: bold; line-height: 1; letter-spacing: -0.01em; }
[data-skills-tree] .big small { font-size: 20px; color: var(--ink-soft); }
/* The big number is the at-the-standard tally, so it carries that tally's mark. */
[data-skills-tree] .big-sub { display: flex; align-items: center; gap: 9px; margin: 6px 0 0; font-size: 15px; font-weight: bold; }
[data-skills-tree] .dip { margin: 10px 0 0; font-size: 13px; color: var(--ink); line-height: 1.5; max-width: 46ch; }
[data-skills-tree] .dip-names { display: block; margin-top: 3px; font-size: 12.5px; }
[data-skills-tree] .dip-names p { max-width: 46ch; }
[data-skills-tree] .tallies { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 7px; font-size: 13px; color: var(--ink-soft); }
[data-skills-tree] .tallies li { display: flex; align-items: center; gap: 9px; }
[data-skills-tree] .tallies b { color: var(--ink); min-width: 1.3em; text-align: right; }
[data-skills-tree] .tg { flex: none; }
:is([data-skills-tree], [data-growth]) .side-h { margin: 0 0 6px; font-size: 12.5px; font-weight: bold; color: var(--ink); }
[data-skills-tree] .st-chips + .side-h { margin-top: 16px; }
[data-skills-tree] .st-chips { display: flex; flex-wrap: wrap; gap: 8px; }
[data-skills-tree] .st-chip {
  display: inline-flex; align-items: baseline; gap: 6px; font-size: 12.5px; font-weight: bold;
  padding: 6px 12px; border: 1px solid var(--border-strong); border-radius: 16px;
  background: var(--surface); color: var(--ink); text-decoration: none; min-height: 30px;
}
[data-skills-tree] .st-chip:hover { border-color: var(--ink); text-decoration: none; }
[data-skills-tree] .st-chip span { font-weight: normal; color: var(--muted-small); font-size: 12px; }
[data-skills-tree] .st-chip[aria-current="true"] { background: var(--ink); border-color: var(--ink); color: #fff; }
[data-skills-tree] .st-chip[aria-current="true"] span { color: #d3d8e2; }
:is([data-skills-tree], [data-growth]) .coming { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; font-size: 13px; line-height: 1.45; color: var(--ink-soft); }
:is([data-skills-tree], [data-growth]) .coming b { color: var(--ink); }
/* Each "when" once, its modules beside it where there is room, under it on a phone. */
:is([data-skills-tree], [data-growth]) .c-group { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 3px 10px; align-items: start; }
:is([data-skills-tree], [data-growth]) .c-mods { list-style: none; margin: 0; padding: 0; display: grid; gap: 3px; }
:is([data-skills-tree], [data-growth]) .c-when {
  justify-self: start; display: inline-block; font-size: 11px; font-weight: bold; color: var(--ink);
  background: #e6e9ef; border-radius: 9px; padding: 1px 8px; margin-top: 1px; white-space: nowrap;
}
/* One short row per module: the module and a label, flowing as one line that wraps. The words carry the
   meaning; a module whose sub skills are not known yet says so on a dashed tag, never only in colour. */
:is([data-skills-tree], [data-growth]) .c-tag {
  display: inline-block; font-size: 10.5px; font-weight: bold; color: var(--ink-soft);
  border: 1px dashed var(--dot); border-radius: 9px; padding: 0 7px; line-height: 1.5; vertical-align: 1px;
}
:is([data-skills-tree], [data-growth]) .c-text { margin: 0; font-size: 13px; color: var(--ink-soft); }
/* A mapped module's sub skills, one tap away. Inline, so the label follows the module's name; opened, the
   names come under the row. */
:is([data-skills-tree], [data-growth]) .c-names { display: inline; }
:is([data-skills-tree], [data-growth]) .c-names > summary {
  display: inline-flex; align-items: center; gap: 4px; cursor: pointer; border-radius: 4px; list-style: none;
  white-space: nowrap; color: var(--ink);
  text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px;
}
:is([data-skills-tree], [data-growth]) .c-names > summary::-webkit-details-marker { display: none; }
:is([data-skills-tree], [data-growth]) .c-names > summary::marker { content: ""; }
:is([data-skills-tree], [data-growth]) .c-names > summary:hover { text-decoration-color: currentColor; }
:is([data-skills-tree], [data-growth]) .c-names p { margin: 3px 0 2px; font-size: 12.5px; color: var(--ink-soft); }

/* ---------- the tree area, on the white card ---------- */
[data-skills-tree] .tree-area {
  margin: 18px -16px 0; padding: 14px 12px 16px; border-top: 1px solid var(--border);
  background: var(--surface); scroll-margin-top: 8px;
}

/* Your degree so far: the journey the timelines draw, one stop per trimester, each year a group of its own
   under its band: its own line, from its first stop to its last, and a narrow column between one year and the
   next (--jr-space) with a light divider in it, so the years read apart. The number in a stop is the count at
   the standard at the end of that trimester (or now). The stop whose tree is shown is filled in ink, ringed,
   sits on the now column's band and says Now or Then in words. */
[data-skills-tree] .growth { padding-bottom: 12px; border-bottom: 1px solid var(--border); }
[data-skills-tree] .g-title { margin: 0; font-size: 13.5px; font-weight: bold; }
[data-skills-tree] .g-sub { margin: 2px 0 0; font-size: 12px; color: var(--muted-small); line-height: 1.45; text-wrap: pretty; }
/* The standard's own pill, as the tree draws it on the red line (white on the brand red, 5.6:1). */
[data-skills-tree] .std-pill {
  display: inline-block; padding: 0 7px; border-radius: 8px; background: var(--brand); color: #fff;
  font-size: 10.5px; font-weight: bold; line-height: 1.6; white-space: nowrap; vertical-align: 1px;
}
[data-skills-tree] .jr { --jr-space: 28px; display: grid; margin-top: 10px; }
/* A year's band, as a timeline draws it: its name, and ALU's expectation for it, never a forecast. */
[data-skills-tree] .jr-year {
  grid-row: 1; margin: 0 0 10px; padding-bottom: 4px; border-bottom: 1px solid var(--border-strong);
  font-size: 11.5px; line-height: 1.3; color: var(--muted-small);
}
[data-skills-tree] .jr-year b { color: var(--ink); margin-right: 4px; }
/* "ALU expects" and the level each wrap as one. */
[data-skills-tree] .jr-ex,
[data-skills-tree] .jr-lv { white-space: nowrap; }
[data-skills-tree] .jr-stop {
  grid-row: 2; position: relative; display: flex; flex-direction: column; align-items: center; gap: 5px;
  min-width: 0; padding: 4px 0 6px; border-radius: 10px; color: var(--ink); text-decoration: none;
}
/* The line the stops sit on, the timeline's rail: solid behind you, dashed ahead. Each year has a line of its
   own: it starts at the year's first stop (is-first) and ends at its last (is-last). */
[data-skills-tree] .jr-stop::before {
  content: ""; position: absolute; left: 0; right: 0; top: 17px; height: 2px;
  background: repeating-linear-gradient(90deg, var(--dot) 0 4px, transparent 4px 8px);
}
[data-skills-tree] .jr-stop.is-done::before { background: var(--muted-small); }
[data-skills-tree] .jr-stop.is-now::before { background: linear-gradient(90deg, var(--muted-small) 0 50%, transparent 50%), repeating-linear-gradient(90deg, var(--dot) 0 4px, transparent 4px 8px); }
[data-skills-tree] .jr-stop.is-first::before { left: 50%; }
[data-skills-tree] .jr-stop.is-last::before { right: 50%; }
/* Now at a year's edge: dashed ahead of it when it starts the year, solid behind it when it ends the year. */
[data-skills-tree] .jr-stop.is-now.is-first::before { background: repeating-linear-gradient(90deg, var(--dot) 0 4px, transparent 4px 8px); }
[data-skills-tree] .jr-stop.is-now.is-last::before { background: var(--muted-small); }
/* Between one year and the next: a light divider down the gap, through the bands and the stops. */
[data-skills-tree] .jr-gap { grid-row: 1 / span 2; justify-self: center; width: 1px; margin: 1px 0 6px; background: var(--border-strong); }
[data-skills-tree] .jr-node {
  position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; flex: none;
  width: 28px; height: 28px; border-radius: 50%; background: var(--surface); border: 1.5px solid var(--ink-soft);
  font-size: 12.5px; font-weight: bold; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums;
}
/* Ahead: quiet, hollow and small, with no number. A finished trimester with no grades: a small filled stop. */
[data-skills-tree] .is-ahead .jr-node { width: 10px; height: 10px; margin: 9px 0; border-color: var(--dot); }
[data-skills-tree] .is-quiet .jr-node { width: 12px; height: 12px; margin: 8px 0; border: 0; background: var(--muted-small); }
[data-skills-tree] .jr-t { font-size: 11.5px; font-weight: bold; line-height: 1.3; color: var(--ink); white-space: nowrap; }
/* A stop that is a way to look back reads as a link. */
[data-skills-tree] a.jr-stop .jr-t { text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px; }
[data-skills-tree] .is-ahead .jr-t,
[data-skills-tree] .is-quiet .jr-t { font-size: 11px; font-weight: normal; color: var(--muted-small); text-decoration: none; }
[data-skills-tree] .jr-pill { display: none; padding: 0 7px; border-radius: 8px; font-size: 10.5px; font-weight: bold; line-height: 1.6; white-space: nowrap; }
[data-skills-tree] .jr-now { display: inline-block; background: var(--ink); color: #fff; }
/* The tree shown: fill, ring and word together, never colour alone. */
[data-skills-tree] .jr-stop[aria-current="true"] { background: var(--now-bg); }
[data-skills-tree] .jr-stop[aria-current="true"] .jr-node {
  background: var(--ink); border-color: var(--ink); color: #fff;
  box-shadow: 0 0 0 3px var(--now-bg), 0 0 0 4.5px var(--ink);
}
[data-skills-tree] .is-done[aria-current="true"] .jr-t { display: none; }
[data-skills-tree] .is-done[aria-current="true"] .jr-then { display: inline-block; background: var(--ink); color: #fff; }
/* During a look back, Now is still there to go back to: outlined, and its stop white. */
[data-skills-tree] .is-now:not([aria-current]) .jr-node { background: var(--surface); }
[data-skills-tree] .is-now:not([aria-current]) .jr-now { background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }
[data-skills-tree] a.jr-stop:not([aria-current]):hover .jr-node { background: var(--now-bg); border-color: var(--ink); }
[data-skills-tree] a.jr-stop:not([aria-current]):hover .jr-t { text-decoration-color: currentColor; }
/* During a look back: the sentence, then Back to now, which starts where the sentence does when it wraps. */
[data-skills-tree] .g-status { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 8px 0 0; font-size: 12px; color: var(--ink-soft); text-wrap: pretty; }
[data-skills-tree] .g-status.visually-hidden { display: block; }
[data-skills-tree] .g-status .back-now {
  display: inline-block; background: var(--ink); color: #fff; border: 0; border-radius: 12px;
  padding: 3px 10px; font-size: 11.5px; font-weight: bold; text-decoration: none; cursor: pointer;
}
[data-skills-tree] .g-status .back-now:hover { color: #fff; text-decoration: underline; }

/* How to read this: one line, the summary, above the tree. Opened, a legend in small groups, a shape and two
   or three words each, every shape drawn with the tree's own classes, in one neutral colour (the hue only
   ever says which meta skill). Three columns with room; stacked on a phone. */
[data-skills-tree] .keys { position: relative; padding: 10px 0 4px; }
[data-skills-tree] .htr-body {
  --hue: var(--ink-soft);
  display: grid; gap: 14px; margin-top: 8px; padding: 12px 16px;
  background: var(--surface-muted); border: 1px solid var(--border); border-radius: 12px;
}
[data-skills-tree] .htr-col { display: grid; gap: 14px; align-content: start; min-width: 0; }
[data-skills-tree] .htr-g h4 { margin: 0 0 5px; font-size: 12px; font-weight: bold; color: var(--ink); }
[data-skills-tree] .htr-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 3px 12px;
}
[data-skills-tree] .htr-list li {
  display: grid; grid-template-columns: 28px minmax(0, 1fr); column-gap: 7px; align-items: center;
  min-height: 20px; font-size: 12px; line-height: 1.3; color: var(--ink-soft); text-wrap: balance;
}
[data-skills-tree] .htr-sym { justify-self: center; overflow: visible; }
/* A branch's count reads best whole, on a row of its own; on a phone its two leaves share the next. */
[data-skills-tree] #htr-branch + .htr-list > li:first-child { grid-column: 1 / -1; }
[data-skills-tree] .htr-note { margin: 6px 0 0; font-size: 11.5px; line-height: 1.4; color: var(--muted-small); text-wrap: pretty; }
/* The numbers sit in the symbols' slot, so each point starts where the legend's words start (28 + 7). */
[data-skills-tree] .htr-score { margin: 0; padding-left: 35px; display: grid; gap: 4px; font-size: 12px; line-height: 1.4; color: var(--ink-soft); }
[data-skills-tree] .htr-score li { text-wrap: pretty; }
/* For sighted keyboard use, beside the summary. Hidden until the script makes the arrow keys work. */
[data-skills-tree] .kb-tip {
  position: absolute; top: 12px; right: 0; margin: 0; padding: 3px 9px; border-radius: 10px;
  background: var(--surface-muted); font-size: 11.5px; color: var(--ink-soft);
  visibility: hidden; pointer-events: none;
}
@media (hover: none) {
  [data-skills-tree] .kb-tip { display: none; }
}

/* ---------- the tree, in slices ---------- */
[data-skills-tree] .tree-stage { margin-top: 6px; }
[data-skills-tree] .tree { max-width: 520px; margin: 0 auto; }
[data-skills-tree] .tree svg.vw,
[data-skills-tree] .tree svg.vn { display: block; width: 100%; height: auto; overflow: visible; }
[data-skills-tree] .vw { display: none !important; }

[data-skills-tree] .nb > summary,
[data-skills-tree] .sk > summary { display: block; list-style: none; cursor: pointer; }
[data-skills-tree] .nb > summary::-webkit-details-marker,
[data-skills-tree] .sk > summary::-webkit-details-marker { display: none; }
[data-skills-tree] .nb > summary::marker,
[data-skills-tree] .sk > summary::marker { content: ""; }
[data-skills-tree] .nb > summary { border-radius: 10px; }
[data-skills-tree] .nb > summary:hover { background: var(--surface-muted); }
[data-skills-tree] .nb > summary:focus-visible { outline-offset: -2px; }

[data-skills-tree] .trunk { stroke: var(--line); stroke-width: 2.2; stroke-linecap: butt; }
[data-skills-tree] .stem { stroke: var(--line); stroke-width: 2.2; stroke-linecap: round; }
[data-skills-tree] .root { fill: var(--ink); stroke: var(--ink); stroke-width: 2; }
[data-skills-tree] .root-glow { fill: var(--ink); fill-opacity: 0.08; }
[data-skills-tree] .root-you { fill: #fff; font-size: 12.5px; font-weight: bold; text-anchor: middle; }
[data-skills-tree] .root-you.small { font-size: 11px; }
[data-skills-tree] .root-line { fill: var(--muted-small); font-size: 11.5px; }

[data-skills-tree] .hub .arc { fill: none; stroke: var(--border-strong); stroke-width: 1.6; stroke-linecap: round; }
[data-skills-tree] .hub .arc.st-on { stroke: var(--hue); stroke-width: 3.6; }
[data-skills-tree] .hub-core { fill: var(--surface); stroke: var(--border-strong); stroke-width: 1.2; }
/* Lit: ink on a pale tint of the hue, since white on the hue is under 4.5:1 for some meta skills. */
[data-skills-tree] .hub.st-on .hub-core { fill: var(--tint, var(--surface)); stroke: var(--hue); stroke-width: 1.4; }
[data-skills-tree] .hub-n { fill: var(--ink); font-size: 11px; font-weight: bold; text-anchor: middle; }
[data-skills-tree] .bname { fill: var(--ink); font-size: 13px; font-weight: bold; }
[data-skills-tree] .btally { fill: var(--muted-small); font-size: 11px; }
[data-skills-tree] .btally.end { text-anchor: end; }
/* "T2 is known to test 4": why the branch is open, in words, in ink. */
[data-skills-tree] .bnow { fill: var(--ink); font-size: 11px; }
[data-skills-tree] .bnow.end { text-anchor: end; }

[data-skills-tree] .gradband { fill: var(--band); }
[data-skills-tree] .stdline { stroke: var(--brand); stroke-width: 1.6; }
[data-skills-tree] .stdpill { fill: var(--brand); }
[data-skills-tree] .stdtext { fill: #fff; font-size: 9.5px; font-weight: bold; text-anchor: middle; }
[data-skills-tree] .tier { fill: var(--muted-small); font-size: 10px; text-anchor: middle; }
[data-skills-tree] .vn .tier { font-size: 9.5px; }
/* The wide drawing is scaled to the card (about 0.88 at the narrowest), so its words start a size up. */
[data-skills-tree] .vw .stdtext,
[data-skills-tree] .vw .nowtext { font-size: 10.5px; }
[data-skills-tree] .vw .tier,
[data-skills-tree] .vw .tnum,
[data-skills-tree] .vw .tcap,
[data-skills-tree] .vw .yl { font-size: 11px; }
[data-skills-tree] .vw .rname { font-size: 12.5px; }
[data-skills-tree] .vw .soon { font-size: 11.5px; }
[data-skills-tree] .vw .root-line { font-size: 12px; }
[data-skills-tree] .tier.strong { fill: var(--ink); font-weight: bold; }
/* Several branches open on load (those this trimester's modules test), and each would repeat the same level
   names, years and trimesters. With room they are shown on the first open branch only; one after it keeps
   its red standard, its pill and its Now. A phone, where the branches stack far apart, keeps them all. */
[data-skills-tree] .nb[open] ~ .nb[open] > .nb-body > svg.vw :is(.tier, .yl, .tnum, .tcap) { display: none; }

[data-skills-tree] .st-sub { stroke: var(--dot); stroke-width: 1.6; stroke-dasharray: 0.1 4.4; stroke-linecap: round; }
[data-skills-tree] .st-sub.st-on { stroke: var(--hue); stroke-width: 2.2; stroke-dasharray: none; stroke-linecap: butt; }
[data-skills-tree] .nb:not([open]) .stub { display: none; }

/* The degree strip beside each path. */
[data-skills-tree] .nowband { fill: var(--now-bg); }
[data-skills-tree] .ysep { stroke: var(--border-strong); stroke-width: 1; stroke-dasharray: 2 3; }
/* Every module's column: a dot where it does not test this sub skill, a tick where nobody knows yet. */
[data-skills-tree] .slots { fill: none; stroke: var(--dot); stroke-width: 2.4; stroke-linecap: round; }
[data-skills-tree] .slots-unm { fill: none; stroke: var(--dot); stroke-width: 1.2; stroke-linecap: round; }
[data-skills-tree] .ticks { fill: none; stroke: var(--border-strong); stroke-width: 1; }
[data-skills-tree] .yl { fill: var(--muted-small); font-size: 10px; font-weight: bold; }
[data-skills-tree] .tnum { fill: var(--muted-small); font-size: 10px; text-anchor: middle; }
[data-skills-tree] .tnum.now { fill: var(--ink); font-weight: bold; }
[data-skills-tree] .tcap { fill: var(--muted-small); font-size: 10px; }
[data-skills-tree] .tcap.end { text-anchor: end; }
[data-skills-tree] .nowpill { fill: var(--ink); }
[data-skills-tree] .nowtext { fill: #fff; font-size: 9.5px; font-weight: bold; text-anchor: middle; }
[data-skills-tree] .st { transition: opacity 0.15s ease-out; }
[data-skills-tree] .st-marked { fill: var(--hue); }
[data-skills-tree] .st-planned { fill: var(--surface); stroke: var(--hue); stroke-width: 1.5; }
[data-skills-tree] .st-empty { fill: var(--dot); }
/* A module lit from a timeline or the strip (the script lights it): every sub skill it tests, across the
   tree. Lit stops gain an ink ring and lit names go bold, so the state never rests on colour. */
[data-skills-tree] .tree.mod-hl .stops .st { opacity: 0.25; }
[data-skills-tree] .tree.mod-hl .stops .st.hl { opacity: 1; stroke: var(--ink); stroke-width: 2; stroke-dasharray: none; }
[data-skills-tree] .tree.mod-hl .sk:not(.has-hl) > .row .rname { fill: var(--muted-small); }
[data-skills-tree] .tree.mod-hl .sk.has-hl > .row .rname { font-weight: bold; }
[data-skills-tree] .tree.mod-hl .sk.has-hl > .row .hit { fill: var(--lit-bg); }
[data-skills-tree] .tree.mod-hl .nb:not(.has-hl) > summary .bname { fill: var(--muted-small); font-weight: normal; }

[data-skills-tree] .row { position: relative; outline: none; }
[data-skills-tree] .tree-area .sk > .row:focus-visible { outline: none; }
[data-skills-tree] .row .hit { fill: transparent; }
[data-skills-tree] .row:hover .hit { fill: var(--surface-muted); }
[data-skills-tree] .sk.is-sel > .row .hit,
[data-skills-tree] .sk[open] > .row .hit { fill: var(--now-bg); stroke: var(--border-strong); stroke-width: 1; }
/* A closed row's columns and stem run edge to edge, so they join the rows above and below. On the chosen or
   open row they stop inside its outline, so the outline stays whole. */
[data-skills-tree] .sk.is-sel > .row :is(.st-sub, .gradband, .stdline, .nowband, .ysep),
[data-skills-tree] .sk[open] > .row :is(.st-sub, .gradband, .stdline, .nowband, .ysep) { clip-path: inset(1.5px 0) view-box; }
/* The focus ring for a path, drawn in the SVG since the summary is the whole row. It is painted last and
   sits a unit outside the hit area, so the focused row is lifted above its neighbours to keep it whole. */
[data-skills-tree] .row .fring { fill: none; stroke: var(--ink); stroke-width: 2; opacity: 0; pointer-events: none; }
[data-skills-tree] .row:focus-visible { z-index: 1; }
[data-skills-tree] .row:focus-visible .fring { opacity: 1; }
[data-skills-tree] .elbow { fill: none; stroke: var(--dot); stroke-width: 1.6; stroke-dasharray: 0.1 4.4; stroke-linecap: round; }
[data-skills-tree] .elbow.st-on { stroke: var(--hue); stroke-width: 2.2; stroke-dasharray: none; }
[data-skills-tree] .seg { stroke: var(--track); stroke-width: 2; stroke-linecap: round; }
[data-skills-tree] .seg-lit { stroke: var(--hue); stroke-width: 2.8; stroke-linecap: round; }
[data-skills-tree] .glow { fill: var(--hue); fill-opacity: 0.14; }
[data-skills-tree] .st-node { fill: var(--hue); }
/* Where you are now: an ink ring, not a colour. */
[data-skills-tree] .halo { fill: none; stroke: var(--ink); stroke-width: 1.6; }
[data-skills-tree] .n-next { fill: var(--surface); stroke: var(--hue); stroke-width: 1.8; stroke-dasharray: 2.4 1.9; }
[data-skills-tree] .n-ahead { fill: var(--surface); stroke: var(--dot); stroke-width: 1; }
[data-skills-tree] .n-ghost { fill: var(--hue); fill-opacity: 0.5; }
[data-skills-tree] .diamond { fill: none; stroke: var(--hue); stroke-width: 1.5; }
[data-skills-tree] .plate { fill: var(--surface); stroke: var(--border); stroke-width: 1; }
[data-skills-tree] .soon { fill: var(--muted-small); font-size: 10.5px; }
[data-skills-tree] .rname { fill: var(--ink); font-size: 12px; }
[data-skills-tree] .sk.is-sel > .row .rname,
[data-skills-tree] .sk[open] > .row .rname { font-weight: bold; }
[data-skills-tree] .rchev,
[data-skills-tree] .chev { fill: none; stroke: var(--ink-soft); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; transform-box: fill-box; transform-origin: center; }
[data-skills-tree] .rchev { stroke: var(--muted-small); }
[data-skills-tree] .sk[open] > .row .rchev,
[data-skills-tree] .nb[open] > summary .chev { transform: rotate(180deg); }
[data-skills-tree] .leaf { fill: var(--hue); }
[data-skills-tree] .leaf-halo { fill: none; stroke: var(--ink); stroke-width: 1.2; }
[data-skills-tree] .leaf-none { fill: none; stroke: var(--hue); stroke-width: 1.3; }

/* Hover card on a path: which modules test it. Only with the script, which puts it away on Escape (WCAG
   1.4.13), and only on the wide tree with a pointer (below); the timeline says the same to everyone. */
[data-skills-tree] .tip { display: none; }
[data-skills-tree] .tip-h { display: block; margin-bottom: 5px; font-size: 12px; }
[data-skills-tree] .tip-g { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 6px; padding: 3px 0; border-top: 1px solid var(--border); }
[data-skills-tree] .tip-t { font-weight: bold; color: var(--ink); }
[data-skills-tree] .tip-list { display: grid; gap: 2px; }
[data-skills-tree] .tip-i { display: block; color: var(--ink); }
[data-skills-tree] .tip-i em { font-style: normal; color: var(--muted-small); margin-left: 3px; }
[data-skills-tree] .tip-i.is-lit { font-weight: bold; }
[data-skills-tree] .tip-i.is-lit::before { content: "\2192"; margin-right: 4px; }

/* ---------- the timeline, under an open sub skill ---------- */
/* The card hangs straight under its row's highlight, edge to edge: from --panel-x (the highlight's left)
   to 2 units in from the right, where the highlight ends. */
[data-skills-tree] .tl { position: relative; padding: 2px calc(2 / var(--vb) * 100%) 12px calc(var(--panel-x) / var(--vb) * 100%); }
[data-skills-tree] .tl.cont::before {
  content: ""; position: absolute; top: 0; bottom: 0; width: 2.2px;
  left: calc(var(--trunk-x) / var(--vb) * 100% - 1.1px); background: var(--line);
}
[data-skills-tree] .tl-card {
  background: var(--surface-muted); border: 1px solid var(--border); border-radius: 12px;
  padding: 14px 16px 12px; color: var(--ink);
}
/* A closed row's body, and a look back's: one line, and a way to the timeline. */
[data-skills-tree] .tl-wait p,
[data-skills-tree] .tl-snap p { margin: 0; font-size: 12.5px; color: var(--ink-soft); }
[data-skills-tree] .tl-open { font-weight: bold; color: var(--ink); text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px; }
[data-skills-tree] .tl-open:hover { text-decoration-color: currentColor; }
[data-skills-tree] .tl-title { margin: 0; font-size: 14.5px; font-weight: bold; }
[data-skills-tree] .tl-title span { font-weight: normal; color: var(--muted-small); }
[data-skills-tree] .tl-lead { margin: 4px 0 0; font-size: 12.5px; color: var(--ink-soft); max-width: 92ch; }
[data-skills-tree] .tl-lead b { color: var(--ink); }
:is([data-skills-tree], [data-growth]) .sym { display: inline-block; flex: none; vertical-align: -1px; }

[data-skills-tree] .tl-grid { list-style: none; margin: 12px 0 0; padding: 0; }
[data-skills-tree] .tl-year { margin: 12px 0 6px; padding-bottom: 4px; border-bottom: 1px solid var(--border-strong); font-size: 11.5px; color: var(--muted-small); }
[data-skills-tree] .tl-year:first-child { margin-top: 0; }
[data-skills-tree] .tl-year b { color: var(--ink); margin-right: 4px; }

/* Narrow: one trimester under another, the track running down the left. Trimesters in a row with nothing in
   them fold into one line. */
[data-skills-tree] .tl-tri { position: relative; display: grid; grid-template-columns: 22px minmax(0, 1fr); column-gap: 8px; padding-bottom: 12px; }
[data-skills-tree] .tl-rail { grid-column: 1; grid-row: 1 / span 5; position: relative; }
[data-skills-tree] .tl-rail::before {
  content: ""; position: absolute; left: 10px; top: 0; bottom: -12px; width: 2px;
  background: repeating-linear-gradient(180deg, var(--dot) 0 4px, transparent 4px 8px);
}
[data-skills-tree] .tl-tri.is-done .tl-rail::before { background: var(--muted-small); }
[data-skills-tree] .tl-tri.is-now .tl-rail::before { background: linear-gradient(180deg, var(--muted-small) 0 16px, transparent 16px), repeating-linear-gradient(180deg, var(--dot) 0 4px, transparent 4px 8px); }
[data-skills-tree] .tl-node {
  position: absolute; left: 5px; top: 2px; width: 12px; height: 12px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--dot);
}
[data-skills-tree] .is-done .tl-node { background: var(--muted-small); border-color: var(--muted-small); }
[data-skills-tree] .is-now .tl-node { background: var(--ink); border-color: var(--ink); box-shadow: 0 0 0 3px var(--surface-muted), 0 0 0 4.5px var(--ink); }
[data-skills-tree] .is-empty.is-ahead .tl-node { left: 7px; top: 4px; width: 8px; height: 8px; border-width: 1.5px; }
[data-skills-tree] .tl-t { grid-column: 2; margin: 0 0 6px; font-size: 11.5px; color: var(--muted-small); line-height: 1.35; }
[data-skills-tree] .tl-t b { color: var(--ink); font-size: 12.5px; margin-right: 4px; }
[data-skills-tree] .tl-short { display: none; }
[data-skills-tree] .tl-here {
  display: inline-block; margin-left: 4px; padding: 0 7px; border-radius: 8px;
  background: var(--ink); color: #fff; font-size: 10.5px; font-weight: bold; line-height: 1.6;
}
[data-skills-tree] .run-hide,
[data-skills-tree] .has-run > .tl-one { display: none; }
[data-skills-tree] .tl-tri.is-last-n .tl-rail::before { bottom: auto; height: 12px; }
[data-skills-tree] .tl-stops,
[data-skills-tree] .tl-unm { grid-column: 2; }
/* One column that may shrink below its longest word, so a card never spills into the next trimester. */
[data-skills-tree] .tl-stops { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
[data-skills-tree] .tl-empty { font-size: 11.5px; color: var(--muted-small); }
[data-skills-tree] .tl-empty::before { content: "\00b7"; margin-right: 5px; }
[data-skills-tree] .is-empty { padding-bottom: 7px; }
[data-skills-tree] .is-empty .tl-t { margin: 0; }
[data-skills-tree] .tl-stop {
  border: 1px solid var(--border-strong); background: var(--surface); border-radius: 8px;
  padding: 7px 9px; font-size: 12px; color: var(--ink-soft); transition: border-color 0.15s ease-out;
}
/* Next: an ink border and the word Next. Lit: a doubled ink border and a tinted card. */
[data-skills-tree] .tl-stop.is-next { border-color: var(--ink); }
[data-skills-tree] .tl-stop.is-lit { border-color: var(--ink); border-style: solid; box-shadow: inset 0 0 0 1px var(--ink); background: var(--lit-bg); }
[data-skills-tree] .tl-st { display: flex; flex-wrap: wrap; align-items: center; gap: 3px 5px; margin: 0; font-size: 11px; color: var(--muted-small); }
[data-skills-tree] .tl-nx { background: var(--ink); color: #fff; border-radius: 7px; padding: 0 6px; font-size: 10px; font-weight: bold; line-height: 1.6; }
[data-skills-tree] .tl-mod { display: block; margin: 0; font-size: 12.5px; font-weight: bold; color: var(--ink); line-height: 1.3; overflow-wrap: break-word; hyphens: auto; }
[data-skills-tree] p.tl-mod { margin-top: 4px; }
[data-skills-tree] .tl-mod > .sym { margin-right: 5px; }
[data-skills-tree] .tl-stop > p.tl-mod:first-child { margin-top: 0; }

/* A module in a timeline opens to show every other sub skill it tests. */
[data-skills-tree] .tl-also { margin: 2px -5px 0; }
[data-skills-tree] .tl-also > summary { display: block; list-style: none; cursor: pointer; border-radius: 6px; padding: 2px 5px 3px; }
[data-skills-tree] .tl-also > summary::-webkit-details-marker { display: none; }
[data-skills-tree] .tl-also > summary::marker { content: ""; }
[data-skills-tree] .tl-also > summary:hover,
[data-skills-tree] .tl-also[open] > summary { background: var(--now-bg); }
/* Inline, so the chevron follows the last word; the count and "more" never part. */
[data-skills-tree] .tl-hint {
  display: inline; font-size: 11px; color: var(--ink);
  text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px;
}
[data-skills-tree] .tl-hn { white-space: nowrap; }
[data-skills-tree] .tl-hn::after {
  content: ""; display: inline-block; width: 5px; height: 5px; margin: 0 2px 2px 6px; vertical-align: middle;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
}
[data-skills-tree] .tl-also[open] .tl-hn::after { margin-bottom: -2px; transform: rotate(-135deg); }
[data-skills-tree] .tl-also > summary:hover .tl-hint { text-decoration-color: currentColor; }
[data-skills-tree] .tl-hint.is-plain { display: block; margin-top: 2px; color: var(--muted-small); text-decoration: none; }
/* The list a module opens, in its own column: nothing without the script can make room for it across the card. */
[data-skills-tree] .tl-pop {
  margin: 6px 0 4px; padding: 10px 12px; background: var(--surface); color: var(--ink);
  border: 1px solid var(--border-strong); border-radius: 9px;
  font-size: 12px; line-height: 1.4; text-align: left;
}
[data-skills-tree] .tl-pop-h { margin: 0 0 8px; color: var(--ink-soft); }
[data-skills-tree] .tl-pop-g { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
[data-skills-tree] .tl-pop-g ul { list-style: none; margin: 3px 0 0; padding: 0 0 0 14px; display: grid; gap: 2px; }
[data-skills-tree] .tl-pop-m { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ink); }
[data-skills-tree] .tl-pop-m::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--hue); }
[data-skills-tree] .tl-pop-g ul span { color: var(--muted-small); }
[data-skills-tree] .tl-pop-g a { color: var(--ink); font-weight: bold; text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px; }
[data-skills-tree] .tl-pop-g a:hover { text-decoration-color: currentColor; }

[data-skills-tree] .tl-marks { list-style: none; margin: 5px 0 0; padding: 4px 0 0; border-top: 1px solid var(--border); display: grid; gap: 2px; }
[data-skills-tree] .tl-marks li { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 11.5px; }
[data-skills-tree] .tl-marks b { color: var(--ink); font-size: 12.5px; font-variant-numeric: tabular-nums; white-space: nowrap; }
[data-skills-tree] .tl-unm {
  margin: 6px 0 0; padding: 5px 8px; border: 1px dashed var(--dot); border-radius: 8px;
  font-size: 11px; color: var(--muted-small);
}
[data-skills-tree] .tl-foot { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
[data-skills-tree] .tl-next { margin: 0; font-size: 13px; color: var(--ink); }
[data-skills-tree] .tl-links { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 10px 0 0; }
[data-skills-tree] .tl-more {
  display: inline-block; background: var(--ink); color: #fff; border-radius: 14px; padding: 5px 12px;
  font-size: 12px; font-weight: bold; text-decoration: none;
}
[data-skills-tree] .tl-more:hover { color: #fff; text-decoration: underline; }
/* Close is the script's: one sub skill open at a time. With no script the row's own summary closes it. */
[data-skills-tree] .tl-close {
  display: none; background: var(--surface); color: var(--ink); border: 1px solid var(--border-strong);
  border-radius: 14px; padding: 4px 12px; font-size: 12px; font-weight: bold; cursor: pointer;
}
[data-skills-tree] .tl-close:hover { border-color: var(--ink); }

/* A trimester other than now, folded: its name, a Next pill if its module is next, and a chip saying what it
   holds in shapes and words. The whole summary is the tap target and takes the page's ink focus ring. */
[data-skills-tree] .tl-fold { position: static; min-width: 0; }
[data-skills-tree] .tl-fold > summary { list-style: none; cursor: pointer; border-radius: 6px; }
[data-skills-tree] .has-fold .tl-fold > summary .tl-t { margin: 0; }
/* Its words and its Next pill never break inside themselves; they wrap as wholes. */
[data-skills-tree] .tl-fold > summary .tl-t b,
[data-skills-tree] .tl-fold > summary .tl-term,
[data-skills-tree] .tl-fold > summary .tl-nx { white-space: nowrap; }
[data-skills-tree] .tl-fold > summary .tl-t .tl-nx { display: inline-block; margin-left: 2px; vertical-align: 1px; }
/* Narrow, one line: the shapes, the count and the word, then the chevron. With room, two (below). */
[data-skills-tree] .tl-chip {
  display: inline-flex; align-items: center; gap: 4px; min-height: 26px; padding: 2px 9px;
  border: 1px solid var(--border-strong); border-radius: 13px; background: var(--surface);
  font-size: 11px; font-weight: bold; line-height: 1.3; color: var(--ink); text-align: left; white-space: nowrap;
}
[data-skills-tree] .tl-chip-n { display: inline-flex; align-items: center; gap: 4px; min-height: 1.3em; }
[data-skills-tree] .tl-chip .sym { width: 10px; height: 10px; }
[data-skills-tree] .tl-chip::after,
[data-skills-tree] .tl-chip-n::after {
  content: ""; flex: none; display: inline-block; width: 5px; height: 5px; margin: -3px 1px 0 3px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
}
[data-skills-tree] .tl-chip-n::after { display: none; }
[data-skills-tree] .tl-fold[open] > summary .tl-chip::after,
[data-skills-tree] .tl-fold[open] > summary .tl-chip-n::after { margin-top: 3px; transform: rotate(-135deg); }
[data-skills-tree] .tl-fold > summary:hover .tl-chip { border-color: var(--ink); }
[data-skills-tree] .tl-fold[open] > summary .tl-chip { background: var(--now-bg); }
/* Opened, the module's own card says Next. */
[data-skills-tree] .tl-fold[open] > summary .tl-nx { display: none; }
/* A module lit across the tree, folded away here: the chip takes the lit card's doubled ink border. */
[data-skills-tree] .tl-fold:not([open]):has(.tl-stop.is-lit) .tl-chip { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); background: var(--lit-bg); }
[data-skills-tree] .tl-fold-b { margin-top: 6px; }
/* Narrow: "Trimester 1  May 2026 ........ (1 module v)" on one line, the node level with it. The words take
   what the chip leaves and wrap inside their own box, so the chip keeps to the line. */
[data-skills-tree] .tl-fold { grid-column: 2; }
[data-skills-tree] .tl-fold > summary { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-height: 28px; }
[data-skills-tree] .tl-fold > summary .tl-t { flex: 1 1 0; }
[data-skills-tree] .tl-fold > summary .tl-chip { flex: none; }
[data-skills-tree] .has-fold > .tl-rail .tl-node { top: 8px; }

/* ---------- list view ---------- */
[data-skills-tree] .lv-wrap { margin-top: 18px; }
[data-skills-tree] .lv { margin-top: 12px; }
/* The disclosure names the list, so its heading is for screen readers only, and stays in the outline. */
[data-skills-tree] .lv-title {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
/* Find a sub skill: one compact block at the top of the list. The label and the count share a line, and the
   box is full width on a phone, so the list starts close under it. */
[data-skills-tree] .lv-find { margin: 0 0 18px; max-width: 480px; }
[data-skills-tree] .lv-find-top { display: flex; justify-content: space-between; align-items: baseline; flex-wrap: wrap; gap: 2px 12px; margin-bottom: 5px; }
[data-skills-tree] .lv-find-l { font-size: 12.5px; font-weight: bold; color: var(--ink); }
[data-skills-tree] .lv-count { margin: 0; font-size: 12px; color: var(--muted-small); font-variant-numeric: tabular-nums; }
[data-skills-tree] .lv-find-box { position: relative; }
/* The box's edge is --dot, 4.15:1 on white, so it can be seen as a field (WCAG 1.4.11). */
[data-skills-tree] .lv-q {
  display: block; width: 100%; height: 38px; margin: 0; padding: 0 76px 0 34px;
  border: 1px solid var(--dot); border-radius: 19px; background: var(--surface); color: var(--ink);
  font: 14px/1.2 Arial, Helvetica, sans-serif; -webkit-appearance: none; appearance: none;
}
[data-skills-tree] .lv-q:hover { border-color: var(--ink-soft); }
/* One way to clear, the labelled button: not the browser's own cross as well. */
[data-skills-tree] .lv-q::-webkit-search-cancel-button,
[data-skills-tree] .lv-q::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
[data-skills-tree] .lv-find-ico { position: absolute; left: 12px; top: 11px; fill: none; stroke: var(--ink-soft); stroke-width: 1.7; stroke-linecap: round; pointer-events: none; }
[data-skills-tree] .lv-clear,
[data-skills-tree] .lv-go {
  position: absolute; right: 5px; top: 5px; height: 28px; padding: 0 12px;
  background: var(--surface); color: var(--ink); border: 1px solid var(--border-strong); border-radius: 14px;
  font-size: 12px; font-weight: bold; cursor: pointer;
}
[data-skills-tree] .lv-clear:hover,
[data-skills-tree] .lv-go:hover { border-color: var(--ink); }
[data-skills-tree] .lv-none { margin: 0 0 8px; font-size: 13px; color: var(--ink-soft); }
[data-skills-tree] .lv-all { margin: 0 0 14px; font-size: 13px; }
/* Space between groups, counted from the last group still showing, so a search never leaves a gap on top. */
[data-skills-tree] .lv-group:not([hidden]) ~ .lv-group { margin-top: 20px; }
[data-skills-tree] .lv-h { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 10px; margin: 0 0 6px; font-size: 15px; }
[data-skills-tree] .lv-h i { display: inline-block; width: 9px; height: 9px; border-radius: 50%; }
[data-skills-tree] .lv-h small { font-size: 12px; font-weight: normal; color: var(--muted-small); }
[data-skills-tree] .lv table { width: 100%; border-collapse: collapse; font-size: 13px; }
[data-skills-tree] .lv th { text-align: left; font-size: 11.5px; color: var(--muted-small); padding: 6px 8px; border-bottom: 1px solid var(--border); }
[data-skills-tree] .lv td { padding: 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
[data-skills-tree] .lv .c-score { font-variant-numeric: tabular-nums; }
[data-skills-tree] .lv .c-next,
[data-skills-tree] .lv .c-reach { color: var(--ink-soft); }
[data-skills-tree] .lv-link { display: inline-block; margin: -4px -8px; padding: 4px 8px; border-radius: 6px; font-weight: bold; text-decoration: none; }
[data-skills-tree] .lv-link:hover { background: var(--surface-muted); text-decoration: underline; }
[data-skills-tree] .lv-link[aria-current="true"] { background: var(--ink); color: #fff; }
[data-skills-tree] .lv-ghost { display: block; font-size: 11.5px; color: var(--muted-small); }
[data-skills-tree] .muted { color: var(--muted-small); }
[data-skills-tree] .mini { display: block; }
[data-skills-tree] .m-std { stroke: var(--ink); stroke-width: 1.2; }
[data-skills-tree] .m-base { stroke: #d3d8e0; stroke-width: 2; }
[data-skills-tree] .m-lit { stroke: var(--hue); stroke-width: 2; }
[data-skills-tree] .m-node { fill: var(--hue); }
[data-skills-tree] .m-halo { fill: none; stroke: var(--ink); stroke-width: 1.1; }
[data-skills-tree] .m-next { fill: #fff; stroke: var(--hue); stroke-width: 1.4; stroke-dasharray: 1.8 1.4; }
[data-skills-tree] .m-ahead { fill: #fff; stroke: var(--dot); stroke-width: 1.2; }
[data-skills-tree] .m-ghost { fill: var(--hue); fill-opacity: 0.45; }
[data-skills-tree] .m-dots { stroke: var(--dot); stroke-width: 1.4; stroke-dasharray: 0.1 4; stroke-linecap: round; }
[data-skills-tree] .m-diamond { fill: none; stroke: var(--hue); stroke-width: 1.3; }

/* ---------- details ---------- */
[data-skills-tree] .details { margin-top: 22px; }
[data-skills-tree] .detail { display: none; scroll-margin-top: 12px; }
[data-skills-tree] .detail.is-open,
[data-skills-tree] .detail:target { display: block; }
[data-skills-tree] .d-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px 16px; flex-wrap: wrap; }
[data-skills-tree] .meta-tag { display: inline-flex; align-items: center; font-size: 12px; font-weight: bold; color: var(--ink-soft); }
[data-skills-tree] .meta-tag i { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; background: var(--hue); }
[data-skills-tree] .d-title { margin: 4px 0 3px; font-size: 21px; }
[data-skills-tree] .d-title:focus { outline: none; }
[data-skills-tree] .d-title:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
[data-skills-tree] .d-desc { margin: 0; font-size: 14px; color: var(--ink-soft); max-width: 62ch; }
[data-skills-tree] .back-tree {
  display: inline-block; background: var(--surface); border: 1px solid var(--border-strong); color: var(--ink);
  border-radius: 16px; padding: 6px 12px; font-size: 12.5px; font-weight: bold; text-decoration: none;
}
[data-skills-tree] .back-tree:hover { border-color: var(--ink); text-decoration: none; }
[data-skills-tree] .d-grid { display: grid; grid-template-columns: 1fr; gap: 16px; margin-top: 16px; }
[data-skills-tree] .box { background: var(--surface-muted); border-radius: 10px; padding: 16px 18px; min-width: 0; }
[data-skills-tree] .d-eyebrow { margin: 0 0 10px; font-size: 12px; font-weight: bold; color: var(--ink); }
[data-skills-tree] .d-gap { margin-top: 20px; }
[data-skills-tree] .d-level { margin: 12px 0 2px; font-size: 14px; }
[data-skills-tree] .d-meaning,
[data-skills-tree] .d-standing,
[data-skills-tree] .d-shown { margin: 4px 0 0; font-size: 13px; color: var(--ink-soft); }
[data-skills-tree] .d-standing { color: var(--ink); }
[data-skills-tree] .box p { font-size: 13px; line-height: 1.5; }
[data-skills-tree] .d-next p { margin: 0 0 8px; color: var(--ink-soft); }
[data-skills-tree] .d-next .d-big { font-size: 15px; color: var(--ink); }
[data-skills-tree] .d-when { padding-top: 8px; border-top: 1px solid var(--border); }
[data-skills-tree] .d-empty { margin: 0; color: var(--ink-soft); }

[data-skills-tree] .lp-wrap { position: relative; padding-top: 16px; }
[data-skills-tree] .lp { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
[data-skills-tree] .lp li { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; font-size: 11px; color: var(--muted-small); }
[data-skills-tree] .lp li + li::before {
  content: ""; position: absolute; top: 8px; right: 50%; width: 100%; height: 2px;
  background: linear-gradient(90deg, var(--hue) calc(var(--f, 0) * 100%), #d3d8e0 0);
}
[data-skills-tree] .lp li.none + li.none::before { background: repeating-linear-gradient(90deg, #b9c0cc 0 2px, transparent 2px 6px); }
[data-skills-tree] .lp-node { position: relative; z-index: 1; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--dot); background: #fff; }
[data-skills-tree] .lp .none .lp-node { width: 8px; height: 8px; margin: 5px 0; border: 0; background: var(--dot); }
[data-skills-tree] .lp .reached .lp-node { background: var(--hue); border-color: var(--hue); }
[data-skills-tree] .lp .current .lp-node { box-shadow: 0 0 0 3px #fff, 0 0 0 5px var(--ink); }
[data-skills-tree] .lp .next .lp-node { border-color: var(--hue); border-style: dashed; }
[data-skills-tree] .lp .ghost .lp-node::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--hue); opacity: 0.45; }
[data-skills-tree] .lp-name { margin-top: 7px; font-weight: bold; }
[data-skills-tree] .lp .reached .lp-name,
[data-skills-tree] .lp .next .lp-name { color: var(--ink); }
[data-skills-tree] .lp-std {
  position: absolute; left: 50%; top: 0; transform: translateX(-50%); z-index: 2;
  display: flex; flex-direction: column; align-items: center;
  font-size: 10px; font-weight: bold; color: var(--ink); white-space: nowrap; pointer-events: none;
}
[data-skills-tree] .lp-std::after { content: ""; width: 2px; height: 20px; margin-top: 1px; background: var(--ink); }

[data-skills-tree] .chart { display: block; width: 100%; max-width: 460px; height: auto; margin: 4px 0 0; }
[data-skills-tree] .c-grid { stroke: #dde1e8; stroke-width: 1; }
[data-skills-tree] .c-std { stroke: var(--ink); stroke-width: 1.2; stroke-dasharray: 4 3; }
[data-skills-tree] .c-y { fill: var(--muted-small); font-size: 10px; text-anchor: end; }
[data-skills-tree] .c-x { fill: var(--muted-small); font-size: 10px; text-anchor: middle; }
[data-skills-tree] .c-line { fill: none; stroke: var(--hue); stroke-width: 2; stroke-linejoin: round; }
[data-skills-tree] .c-mark { fill: #fff; stroke: var(--hue); stroke-width: 1.6; }
[data-skills-tree] .c-now { fill: var(--hue); }
[data-skills-tree] .c-ring { fill: none; stroke: var(--hue); stroke-width: 1.2; }
[data-skills-tree] .chart-key { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 6px 0 0; font-size: 11.5px !important; color: var(--muted-small); }
[data-skills-tree] .chart-key span { display: inline-flex; align-items: center; gap: 5px; }
[data-skills-tree] .k-mark { width: 9px; height: 9px; border-radius: 50%; border: 1.6px solid var(--hue); background: #fff; }
[data-skills-tree] .k-score { width: 16px; height: 2px; background: var(--hue); position: relative; }
[data-skills-tree] .k-score::after { content: ""; position: absolute; left: 5px; top: -3px; width: 7px; height: 7px; border-radius: 50%; background: var(--hue); }
[data-skills-tree] .k-std { width: 16px; height: 0; border-top: 1.4px dashed var(--ink); }
[data-skills-tree] .ev-list { list-style: none; margin: 12px 0 0; padding: 0; }
[data-skills-tree] .ev { display: grid; grid-template-columns: 50px minmax(0, 1fr) auto; gap: 10px; align-items: start; padding: 9px 0; border-top: 1px solid var(--border); font-size: 13px; }
[data-skills-tree] .ev-date { font-size: 12px; color: var(--muted-small); padding-top: 1px; }
[data-skills-tree] .ev-what b { display: block; }
[data-skills-tree] .ev-what > span { display: block; font-size: 12px; color: var(--muted-small); }
[data-skills-tree] .ev-mark { text-align: right; white-space: nowrap; }
[data-skills-tree] .ev-mark b { font-size: 14px; }
[data-skills-tree] .ev-mark span { display: block; font-size: 11px; color: var(--muted-small); }
[data-skills-tree] .tag { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 9px; vertical-align: 1px; background: var(--ink); color: #fff; font-size: 10.5px; font-weight: bold; }

/* ---------- your own work ----------
   Work the student logged outside their modules, and ideas for it. Always in ink: never a meta skill's hue,
   never the brand red, never a side rail. A filled triangle is logged work, a hollow one an idea, and each
   carries words beside it. */
:is([data-skills-tree], [data-growth]) .own-mk { fill: var(--ink); stroke: var(--ink); stroke-width: 1; stroke-linejoin: round; }
:is([data-skills-tree], [data-growth]) .idea-mk { fill: var(--surface); stroke: var(--ink); stroke-width: 1.3; stroke-linejoin: round; }
/* Own work and ideas are never part of a module, so they recede with the stops a lit module leaves unlit. */
[data-skills-tree] .own path { transition: opacity 0.15s ease-out; }
[data-skills-tree] .tree.mod-hl .own path { opacity: 0.25; }
:is([data-skills-tree], [data-growth]) .own-title { color: var(--ink); text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px; }
:is([data-skills-tree], [data-growth]) .own-title:hover { text-decoration-color: currentColor; }

/* In the summary, under the tallies: the line, and the pieces one tap away. */
[data-skills-tree] .own-line { margin: 12px 0 0; font-size: 13px; color: var(--ink-soft); }
[data-skills-tree] p.own-line,
[data-skills-tree] .own-line > summary { display: flex; align-items: flex-start; gap: 8px; }
[data-skills-tree] .own-line .sym { margin-top: 3px; }
[data-skills-tree] .own-line > summary { list-style: none; cursor: pointer; border-radius: 6px; }
[data-skills-tree] .own-line > summary > span { text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px; }
[data-skills-tree] .own-line > summary:hover > span { text-decoration-color: currentColor; }
[data-skills-tree] .own-pieces { list-style: none; margin: 6px 0 0; padding: 0 0 0 20px; display: grid; gap: 6px; font-size: 12.5px; line-height: 1.45; }
[data-skills-tree] .own-pieces b { color: var(--ink); }
:is([data-skills-tree], [data-growth]) .own-where { color: var(--muted-small); }

/* Beyond your modules: a band across the whole summary, under both columns, its cards side by side where
   there is room. */
[data-skills-tree] .summary > .own-sec { grid-column: 1 / -1; padding-top: 16px; border-top: 1px solid var(--border-strong); }
:is([data-skills-tree], [data-growth]) .own-h { display: flex; align-items: center; gap: 6px; }
:is([data-skills-tree], [data-growth]) .own-h:focus { outline: none; }
:is([data-skills-tree], [data-growth]) .own-h:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
:is([data-skills-tree], [data-growth]) .own-intro { margin: 0; font-size: 12.5px; color: var(--ink-soft); max-width: 90ch; }
:is([data-skills-tree], [data-growth]) .own-ideas {
  list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 10px; align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
}
:is([data-skills-tree], [data-growth]) .own-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px;
  font-size: 13px; color: var(--ink-soft); min-width: 0;
}
:is([data-skills-tree], [data-growth]) .own-top { margin: 0; }
:is([data-skills-tree], [data-growth]) .own-skill {
  font-weight: bold; color: var(--ink); text-decoration: underline; text-decoration-color: var(--dot);
  text-underline-offset: 2px;
}
:is([data-skills-tree], [data-growth]) .own-skill:hover { text-decoration-color: currentColor; }
:is([data-skills-tree], [data-growth]) .own-why { margin: 5px 0 0; font-size: 12.5px; line-height: 1.45; color: var(--ink-soft); }
:is([data-skills-tree], [data-growth]) .own-idea { margin: 7px 0 0; font-size: 13px; line-height: 1.45; color: var(--ink); }
:is([data-skills-tree], [data-growth]) .own-size {
  display: inline-block; padding: 0 6px; border: 1px solid var(--border-strong); border-radius: 7px;
  font-size: 10.5px; font-weight: normal; line-height: 1.55; color: var(--ink-soft); vertical-align: 1px; white-space: nowrap;
}
:is([data-skills-tree], [data-growth]) .own-more { margin: 6px 0 0; font-size: 12.5px; }
:is([data-skills-tree], [data-growth]) .own-more ul,
[data-skills-tree] .own-list-ideas { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 6px; }
:is([data-skills-tree], [data-growth]) .own-more li,
[data-skills-tree] .own-list-ideas li { font-size: 12.5px; line-height: 1.45; color: var(--ink-soft); }
:is([data-skills-tree], [data-growth]) .own-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
:is([data-skills-tree], [data-growth]) .own-row > .own-more { margin: 0; }
:is([data-skills-tree], [data-growth]) .own-row > .own-more[open] { flex-basis: 100%; }
:is([data-skills-tree], [data-growth]) .own-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
:is([data-skills-tree], [data-growth]) .own-acts form,
:is([data-skills-tree], [data-growth]) .own-back,
:is([data-skills-tree], [data-growth]) .own-onf { margin: 0; }
/* Log a step is the way forward, in ink; the choices about ideas are quiet buttons beside it. */
:is([data-skills-tree], [data-growth]) .own-log {
  display: inline-flex; align-items: center; min-height: 30px; background: var(--ink); color: #fff;
  border-radius: 14px; padding: 5px 12px; font-size: 12px; font-weight: bold; text-decoration: none;
}
:is([data-skills-tree], [data-growth]) .own-log:hover { color: #fff; text-decoration: underline; }
:is([data-skills-tree], [data-growth]) .own-later button,
:is([data-skills-tree], [data-growth]) .own-off button,
:is([data-skills-tree], [data-growth]) .own-onf button,
:is([data-skills-tree], [data-growth]) .own-undo {
  display: inline-flex; align-items: center; min-height: 30px; background: var(--surface); color: var(--ink);
  border: 1px solid var(--border-strong); border-radius: 14px; padding: 4px 12px;
  font-size: 12px; font-weight: bold; cursor: pointer;
}
:is([data-skills-tree], [data-growth]) .own-later button:hover,
:is([data-skills-tree], [data-growth]) .own-off button:hover,
:is([data-skills-tree], [data-growth]) .own-onf button:hover,
:is([data-skills-tree], [data-growth]) .own-undo:hover { border-color: var(--ink); }
:is([data-skills-tree], [data-growth]) .own-undo { margin-top: 8px; }
:is([data-skills-tree], [data-growth]) .own-done { margin: 8px 0 0; font-size: 12.5px; color: var(--ink-soft); max-width: 90ch; }
:is([data-skills-tree], [data-growth]) .own-off { margin: 8px 0 0; }
/* The words, then the button on a line of its own, so its focus ring never runs through the text. */
:is([data-skills-tree], [data-growth]) .own-offmsg { margin: 8px 0 0; font-size: 12.5px; color: var(--ink-soft); }
:is([data-skills-tree], [data-growth]) .own-offmsg p { margin: 0 0 8px; max-width: 90ch; }
/* A card set aside: what happened and for how long, and the way back. */
:is([data-skills-tree], [data-growth]) .own-aside p { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--ink); }

/* In a timeline: a card of its own in its trimester, after the modules, and never a module's stop. */
[data-skills-tree] .tl-owns { grid-column: 2; list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
[data-skills-tree] .tl-stops + .tl-owns { margin-top: 6px; }
[data-skills-tree] .has-own.is-empty .tl-t { margin: 0 0 6px; }
[data-skills-tree] .tl-own {
  background: var(--surface-muted); border: 1px solid var(--border-strong); border-radius: 8px;
  padding: 7px 9px; font-size: 12px; color: var(--ink-soft);
}
[data-skills-tree] .tl-own > p.tl-mod { margin-top: 4px; }
[data-skills-tree] .own-pill {
  display: inline-block; padding: 0 6px; background: #fff; border: 1px solid var(--ink); border-radius: 7px;
  font-size: 10.5px; font-weight: bold; color: var(--ink); line-height: 1.55;
}
[data-skills-tree] .tl-own-meta { margin: 2px 0 0; font-size: 11.5px; color: var(--muted-small); }
[data-skills-tree] .tl-seen { margin: 5px 0 0; padding-top: 4px; border-top: 1px solid var(--border); font-size: 11.5px; line-height: 1.4; color: var(--ink-soft); }
[data-skills-tree] .tl-own-foot { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border); }
[data-skills-tree] .tl-next + .tl-own-foot { margin-top: 8px; }
[data-skills-tree] .tl-own-foot > :not(summary) { max-width: 92ch; }
[data-skills-tree] .tl-own-foot .own-why { font-size: 12.5px; }
[data-skills-tree] .own-taken { margin: 5px 0 0; font-size: 12.5px; color: var(--ink); }
[data-skills-tree] .own-further { margin: 8px 0 0; font-size: 12.5px; font-weight: bold; color: var(--ink); }
[data-skills-tree] .own-further + .own-list-ideas { margin-top: 4px; }
[data-skills-tree] .own-go { margin: 9px 0 0; }
:is([data-skills-tree], [data-growth]) .own-note { margin: 6px 0 0; font-size: 12px; color: var(--muted-small); }

/* In the details: a box across both columns, beside the grades. No grade column: own work has no grade. */
[data-skills-tree] .own-saved { display: flex; align-items: center; gap: 8px; margin: 12px 0 0; font-size: 13px; font-weight: bold; color: var(--ink); }
[data-skills-tree] .box-own { grid-column: 1 / -1; }
[data-skills-tree] .box-own .d-eyebrow { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
/* The same "Not graded" as the timeline's own work card, so the box can never read as grades. */
:is([data-skills-tree], [data-growth]) .own-nm {
  display: inline-block; padding: 0 6px; border: 1px solid var(--border-strong); border-radius: 7px;
  font-size: 10.5px; font-weight: bold; line-height: 1.55; color: var(--ink-soft); background: var(--surface);
}
[data-skills-tree] .own-list { list-style: none; margin: 8px 0 0; padding: 0; }
[data-skills-tree] .own-piece { display: grid; grid-template-columns: 50px minmax(0, 1fr); gap: 10px; align-items: start; padding: 9px 0; border-top: 1px solid var(--border); font-size: 13px; }
[data-skills-tree] .own-piece .ev-what > span { display: block; font-size: 12px; color: var(--muted-small); }
[data-skills-tree] .own-piece .ev-what > .own-story { margin-top: 3px; font-size: 12.5px; color: var(--ink-soft); }
[data-skills-tree] .own-piece .ev-what > .own-seen { margin-top: 4px; font-size: 12px; color: var(--ink-soft); }
[data-skills-tree] .own-piece .ev-what > .own-feat { margin-top: 4px; font-size: 12px; font-weight: bold; color: var(--ink); }
[data-skills-tree] .own-none { margin: 0; color: var(--ink-soft); }
[data-skills-tree] .box .own-add { margin: 10px 0 0; }

/* In the list, and on a path's hover card. */
[data-skills-tree] .lv-own { display: flex; align-items: flex-start; gap: 6px; margin-top: 3px; font-size: 11.5px; color: var(--ink-soft); }
[data-skills-tree] .lv-own .sym { margin-top: 2px; }
[data-skills-tree] .tip-own { display: block; margin-top: 6px; padding-top: 5px; border-top: 1px solid var(--border); color: var(--ink); }
[data-skills-tree] .tip-own .tip-h { margin-bottom: 2px; }
/* A card with no module to list opens on the student's own work: no rule above it. */
[data-skills-tree] .tip-own:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* ---------- disclosures ----------
   Every disclosure on the tree opens with a chevron, never the browser's triangle: a triangle here means
   work of the student's own. Each summary gets the ink focus ring from the rule at the top. */
[data-skills-tree] .how-to-read > summary,
[data-skills-tree] .lv-wrap > summary,
[data-skills-tree] .tl-own-foot > summary,
:is([data-skills-tree], [data-growth]) .own-more > summary {
  display: inline-flex; align-items: center; gap: 6px; list-style: none; cursor: pointer; border-radius: 4px;
  font-size: 12.5px; font-weight: bold; color: var(--ink);
  text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px;
}
:is([data-skills-tree], [data-growth]) .own-more > summary { font-size: 12px; }
/* How to read this is the one line between the journey and the tree: a pill, so it reads as a control. */
[data-skills-tree] .how-to-read > summary {
  padding: 5px 12px; min-height: 30px; border: 1px solid var(--border-strong); border-radius: 15px;
  background: var(--surface); text-decoration: none;
}
[data-skills-tree] .how-to-read > summary:hover { border-color: var(--ink); }
[data-skills-tree] .how-to-read[open] > summary { background: var(--now-bg); }
[data-skills-tree] .how-to-read > summary::-webkit-details-marker,
[data-skills-tree] .lv-wrap > summary::-webkit-details-marker,
[data-skills-tree] .tl-own-foot > summary::-webkit-details-marker,
:is([data-skills-tree], [data-growth]) .own-more > summary::-webkit-details-marker,
[data-skills-tree] .own-line > summary::-webkit-details-marker,
[data-skills-tree] .tl-fold > summary::-webkit-details-marker { display: none; }
[data-skills-tree] .how-to-read > summary::marker,
[data-skills-tree] .lv-wrap > summary::marker,
[data-skills-tree] .tl-own-foot > summary::marker,
:is([data-skills-tree], [data-growth]) .own-more > summary::marker,
[data-skills-tree] .own-line > summary::marker,
[data-skills-tree] .tl-fold > summary::marker { content: ""; }
[data-skills-tree] .lv-wrap > summary:hover,
[data-skills-tree] .tl-own-foot > summary:hover,
:is([data-skills-tree], [data-growth]) .own-more > summary:hover { text-decoration-color: currentColor; }
[data-skills-tree] .how-to-read > summary::after,
:is([data-skills-tree], [data-growth]) .c-names > summary::after,
[data-skills-tree] .lv-wrap > summary::after,
[data-skills-tree] .tl-own-foot > summary::after,
:is([data-skills-tree], [data-growth]) .own-more > summary::after {
  content: ""; flex: none; display: inline-block; width: 5px; height: 5px; margin: -3px 2px 0 1px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
}
[data-skills-tree] .how-to-read[open] > summary::after,
:is([data-skills-tree], [data-growth]) .c-names[open] > summary::after,
[data-skills-tree] .lv-wrap[open] > summary::after,
[data-skills-tree] .tl-own-foot[open] > summary::after,
:is([data-skills-tree], [data-growth]) .own-more[open] > summary::after { margin-top: 3px; transform: rotate(-135deg); }
/* The pieces' line in the summary wraps, so its chevron sits by the first line. */
[data-skills-tree] .own-line > summary::after {
  content: ""; flex: none; display: inline-block; width: 5px; height: 5px; margin: 5px 2px 0 2px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
}
[data-skills-tree] .own-line[open] > summary::after { margin-top: 8px; transform: rotate(-135deg); }

/* ---------- with room ----------
   From a root 790px wide: the wide drawing, the summary and the details in two columns, and each timeline's
   trimesters side by side on a card straight under its path. */
@container skills-tree (width >= 790px) {
  [data-skills-tree] .tree-card { --vb: 860; --trunk-x: 20; --panel-x: 36; padding: 22px 22px 24px; }
  [data-skills-tree] .summary { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 20px 28px; }
  [data-skills-tree] .d-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  [data-skills-tree] .tree-area { margin: 20px -22px 0; padding: 16px 16px 18px; }
  /* The middle column a little wider, so its note keeps to one line. */
  [data-skills-tree] .htr-body { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr) minmax(0, 1fr); column-gap: 28px; }
  [data-skills-tree] .htr-list .htr-narrow { display: none; }
  [data-skills-tree] .tree { max-width: none; }
  [data-skills-tree] .vw { display: block !important; }
  [data-skills-tree] .vn { display: none !important; }
  [data-skills-tree] .run-hide,
  [data-skills-tree] .has-run > .tl-one { display: block; }
  [data-skills-tree] .tl-tri.is-last-n .tl-rail::before { height: 2px; }

  [data-skills-tree] .tl-card { position: relative; display: flex; flex-direction: column; padding: 12px 2% 12px; }
  /* The trimesters come first, straight under the path; the words follow. */
  [data-skills-tree] .tl-grid { order: 1; margin: 0; display: grid; column-gap: 1%; }
  [data-skills-tree] .tl-head { order: 2; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
  [data-skills-tree] .tl-foot { order: 3; margin-top: 8px; padding-top: 0; border-top: 0; }
  [data-skills-tree] .tl-wait,
  [data-skills-tree] .tl-snap { display: block; }
  [data-skills-tree] .tl-year { grid-row: 1; margin: 0 0 8px; }
  [data-skills-tree] .tl-tri { grid-row: 2; display: block; position: static; padding-bottom: 0; min-width: 0; }
  [data-skills-tree] .tl-run { display: none; }
  [data-skills-tree] .tl-rail { height: 16px; }
  [data-skills-tree] .tl-rail::before {
    left: -4px; right: -4px; top: 7px; bottom: auto; width: auto; height: 2px;
    background: repeating-linear-gradient(90deg, var(--dot) 0 4px, transparent 4px 8px);
  }
  [data-skills-tree] .tl-tri.is-done .tl-rail::before { background: var(--muted-small); }
  [data-skills-tree] .tl-tri.is-now .tl-rail::before { background: linear-gradient(90deg, var(--muted-small) 0 50%, transparent 50%), repeating-linear-gradient(90deg, var(--dot) 0 4px, transparent 4px 8px); }
  [data-skills-tree] .tl-tri.is-first .tl-rail::before { left: 50%; }
  [data-skills-tree] .tl-tri.is-last .tl-rail::before { right: 50%; }
  [data-skills-tree] .tl-node { left: 50%; top: 2px; margin-left: -6px; }
  [data-skills-tree] .is-empty.is-ahead .tl-node { left: 50%; top: 4px; margin-left: -4px; }
  [data-skills-tree] .tl-t { margin: 6px 0 8px; text-align: center; font-size: 11px; }
  [data-skills-tree] .tl-t b { display: block; margin: 0; font-size: 12px; }
  [data-skills-tree] .tl-short { display: inline; }
  [data-skills-tree] .tl-long,
  [data-skills-tree] .tl-empty {
    position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  /* An empty trimester is a narrow column: its month and year may take a line each. */
  [data-skills-tree] .tl-term { display: block; }
  [data-skills-tree] .tl-here { display: inline-block; margin: 4px 0 0; white-space: nowrap; }
  [data-skills-tree] .tl-stop,
  [data-skills-tree] .tl-own { padding: 6px 7px; font-size: 11.5px; }
  [data-skills-tree] .tl-tri > .tl-t,
  [data-skills-tree] .is-empty > .tl-t,
  [data-skills-tree] .has-own.is-empty > .tl-t { margin: 6px 0 8px; }
  /* Folded, a centred column under the node: T1, the month, a Next pill, the chip. Opening it never moves the
     rail, since a column's width comes from what it holds, folded or not. */
  [data-skills-tree] .tl-fold > summary { display: flex; flex-direction: column; align-items: center; gap: 5px; margin: 6px 0 8px; padding: 0; text-align: center; min-height: 0; flex-wrap: nowrap; }
  [data-skills-tree] .tl-fold > summary .tl-t { flex: none; }
  [data-skills-tree] .tl-fold > summary .tl-t .tl-nx { display: block; width: max-content; margin: 4px auto 0; }
  [data-skills-tree] .has-fold > .tl-rail .tl-node { top: 2px; }
  /* Always two lines, so every chip in a timeline is the same height and none wraps by chance: the shapes,
     the count and the chevron, then the word. */
  [data-skills-tree] .tl-chip { flex-direction: column; gap: 1px; min-height: 0; padding: 3px 8px; border-radius: 10px; }
  [data-skills-tree] .tl-chip::after { display: none; }
  [data-skills-tree] .tl-chip-n::after { display: inline-block; }
  [data-skills-tree] .tl-fold-b { margin-top: 0; }
  [data-skills-tree] .tl-mod { font-size: 12px; }
  [data-skills-tree] .tl-marks li { display: block; font-size: 11px; line-height: 1.3; }
  [data-skills-tree] .tl-marks li b { display: inline; font-size: 12px; }
  /* A module's list opens in its own column, one sub skill a line: only the script can lay it across the card
     and make room for it (with the script, below). */
  [data-skills-tree] .tl-pop { margin: 6px 0 2px; padding: 8px 8px 9px; }
  [data-skills-tree] .tl-pop-g { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  [data-skills-tree] .tl-pop-g ul { padding-left: 0; }
  [data-skills-tree] .tl-pop-g a,
  [data-skills-tree] .tl-pop-h { overflow-wrap: break-word; hyphens: auto; }
}
/* The hover card, where the script can put it away and there is a pointer to show it. */
@media (hover: hover) {
  @container skills-tree (width >= 790px) {
    html.st-js [data-skills-tree] .tip {
      display: block; position: absolute; right: 6px; top: calc(100% - 3px); z-index: 5; width: 330px;
      background: var(--surface); color: var(--ink); border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px 9px;
      box-shadow: 0 8px 24px rgba(31, 42, 68, 0.16); font-size: 12px; line-height: 1.35; text-align: left;
      opacity: 0; visibility: hidden; pointer-events: none;
      transition: opacity 0.12s ease-out, visibility 0s linear 0.12s;
    }
    html.st-js [data-skills-tree] .sk:not([open]) > .row:hover .tip,
    html.st-js [data-skills-tree] .sk:not([open]) > .row:focus-visible .tip {
      opacity: 1; visibility: visible; pointer-events: auto; transition: opacity 0.15s ease-out 0.35s, visibility 0s linear 0.35s;
    }
    html.st-js [data-skills-tree] .tree .sk.tip-off:not([open]) > .row .tip { opacity: 0; visibility: hidden; pointer-events: none; transition: none; }
    html.st-js [data-skills-tree] .tree.mod-hl:not(.from-strip) .tip { display: none; }
  }
}
@container skills-tree (width >= 511px) {
  [data-skills-tree] .lv table { table-layout: fixed; }
  [data-skills-tree] .lv th:nth-child(1) { width: 24%; }
  [data-skills-tree] .lv th:nth-child(2) { width: 66px; }
  [data-skills-tree] .lv th:nth-child(3) { width: 15%; }
  [data-skills-tree] .lv th:nth-child(4) { width: 56px; }
  [data-skills-tree] .lv th:nth-child(5) { width: 21%; }
}

/* ---------- a phone ---------- */
@container skills-tree (width < 511px) {
  /* Three boxes inside each other leave the words a narrow column; drop two. */
  [data-skills-tree] .tree-card { border: 0; border-radius: 0; padding: 0; overflow: visible; }
  [data-skills-tree] .summary { background: none; padding: 0; margin-top: 14px; }
  [data-skills-tree] .st-notes { padding: 8px 10px; }
  [data-skills-tree] .tree-area { margin: 18px -14px 0; padding: 12px 8px 14px; }
  /* The chart is scaled to about 0.9 on a phone; its labels start a size up so they land near 10px. */
  [data-skills-tree] .c-y,
  [data-skills-tree] .c-x { font-size: 11px; }
  [data-skills-tree] .growth,
  [data-skills-tree] .keys { padding-left: 6px; padding-right: 6px; }
  [data-skills-tree] .big { font-size: 38px; }
  [data-skills-tree] .box { padding: 14px; margin: 0 -4px; }
  [data-skills-tree] .tl-card { padding: 12px 10px 10px; }
  [data-skills-tree] .lv thead { display: none; }
  [data-skills-tree] .lv tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 10px; padding: 9px 0; border-bottom: 1px solid var(--border); }
  [data-skills-tree] .lv td { padding: 0; border: 0; }
  [data-skills-tree] .lv .c-name { grid-column: 1; }
  [data-skills-tree] .lv .c-mini { grid-column: 2; align-self: center; }
  [data-skills-tree] .lv .c-level { grid-column: 1; font-size: 12.5px; }
  [data-skills-tree] .lv .c-score { grid-column: 2; font-size: 12.5px; text-align: right; }
  [data-skills-tree] .lv .c-reach,
  [data-skills-tree] .lv .c-next { grid-column: 1 / -1; font-size: 12.5px; }
  /* The counts across the degree are heard, not shown: the tree's strip draws them. Own work stays in view; a
     cell with nothing else leaves the row. Two rules, so a browser without :has() still hides the counts. */
  [data-skills-tree] .lv .lv-reach {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  [data-skills-tree] .lv .c-reach.no-own:not(:has(.lv-own)) {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  [data-skills-tree] .lv-find { margin-bottom: 12px; }
  [data-skills-tree] .lv-q { font-size: 16px; }
  [data-skills-tree] .c-group { grid-template-columns: minmax(0, 1fr); }
  /* The journey on a phone: nine stops of about 33px, and a narrower gap between the years. A year's band
     takes two lines, its level word on the second; the pills keep inside their columns. */
  [data-skills-tree] .jr { --jr-space: 14px; }
  [data-skills-tree] .jr-year { margin: 0 0 8px; font-size: 11px; }
  [data-skills-tree] .jr-lv { display: block; white-space: nowrap; }
  [data-skills-tree] .jr-node { width: 26px; height: 26px; font-size: 12px; }
  [data-skills-tree] .jr-stop::before { top: 16px; }
  [data-skills-tree] .is-ahead .jr-node { margin: 8px 0; }
  [data-skills-tree] .is-quiet .jr-node { margin: 7px 0; }
  [data-skills-tree] .jr-pill { padding: 0 5px; }
  /* A long journey (a fourth year, more than nine columns): smaller stops, and a year's level word may wrap. */
  [data-skills-tree] .jr-long .jr-lv { white-space: normal; }
  [data-skills-tree] .jr-long .jr-node { width: 20px; height: 20px; font-size: 10.5px; }
  [data-skills-tree] .jr-long .jr-stop::before { top: 13px; }
  [data-skills-tree] .jr-long .is-ahead .jr-node { width: 10px; height: 10px; margin: 5px 0; }
  [data-skills-tree] .jr-long .is-quiet .jr-node { width: 12px; height: 12px; margin: 4px 0; }
  /* The key stacks: two items a row down to a small phone. */
  [data-skills-tree] .htr-body { padding: 12px; }
  [data-skills-tree] .htr-list { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
  [data-skills-tree] .lv .lv-own { margin-top: 0; }
  [data-skills-tree] .own-piece { grid-template-columns: 44px minmax(0, 1fr); gap: 8px; }
}
/* A small phone: "Year 1 ALU expects" keeps to one line above its level word, and during a look back the
   Then and Now pills keep a gap between them. A long journey's twelve columns take smaller stops still. */
@container skills-tree (width < 341px) {
  [data-skills-tree] .jr-year { font-size: 10.5px; }
  [data-skills-tree] .jr-year b { margin-right: 3px; }
  [data-skills-tree] .jr-pill { padding: 0 2px; font-size: 9.5px; letter-spacing: 0; }
  [data-skills-tree] .jr-long .jr-pill { padding: 0 1px; font-size: 9px; }
  [data-skills-tree] .jr-long .jr-t { font-size: 10.5px; }
  [data-skills-tree] .jr-long .jr-node { width: 16px; height: 16px; font-size: 9.5px; }
  [data-skills-tree] .jr-long .jr-stop::before { top: 11px; }
  [data-skills-tree] .jr-long .is-ahead .jr-node { width: 8px; height: 8px; margin: 4px 0; }
  [data-skills-tree] .jr-long .is-quiet .jr-node { width: 10px; height: 10px; margin: 3px 0; }
}
/* 320, a 1280 window at 400% zoom. The gaps between years take room from the stops, so the stops are smaller
   too: nodes keep apart and the line shows between them, and Then and Now keep a gap during a look back. The
   line's centre stays the node's (4px of padding, then half the node). A level word too long for its band
   wraps inside it. */
@container skills-tree (width < 291px) {
  [data-skills-tree] .jr { --jr-space: 8px; }
  [data-skills-tree] .jr-node { width: 22px; height: 22px; font-size: 11px; }
  [data-skills-tree] .jr-stop::before { top: 14px; }
  [data-skills-tree] .is-ahead .jr-node { margin: 6px 0; }
  [data-skills-tree] .is-quiet .jr-node { margin: 5px 0; }
  [data-skills-tree] .jr-pill { padding: 0 1px; font-size: 9px; letter-spacing: 0; }
  [data-skills-tree] .jr-year { font-size: 9.5px; }
  [data-skills-tree] .jr-lv { white-space: normal; }
}

/* ---------- Growth: every nudge in one place ----------
   The Meta skills lens's Growth view: the sub skills closest to the standard, what is coming up, the ideas for
   the student's own work and the work they have logged, in the tree's own words. It shares the tree's rules
   for those parts (the selectors above that start at both roots) and none of its script. One white card, a
   band for each part; with room, the first two side by side, as the tree's summary has them. No side rail,
   and never the brand red: nothing here is the standard's line. */
[data-growth] *,
[data-growth] *::before,
[data-growth] *::after { box-sizing: border-box; }
[data-growth] [hidden] { display: none !important; }
[data-growth] button { font-family: inherit; }
/* The app's links are the brand red; Growth's are ink, as the tree's are. */
[data-growth] a,
[data-growth] a:hover { color: inherit; }
[data-growth] a:focus-visible,
[data-growth] button:focus-visible,
[data-growth] summary:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
[data-growth] .visually-hidden { padding: 0; margin: -1px; border: 0; }
[data-growth] .gw-card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 18px 16px 20px; }
[data-growth] .gw-title { margin: 0; font-size: 19px; font-weight: bold; }
[data-growth] .gw-lead { margin: 8px 0 0; font-size: 13px; line-height: 1.5; color: var(--ink); max-width: 70ch; }
[data-growth] .gw-lead + .c-names { display: block; margin-top: 3px; font-size: 12.5px; }
[data-growth] .gw-top { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; margin-top: 16px; }
[data-growth] .gw-sec,
[data-growth] .own-sec { padding-top: 14px; border-top: 1px solid var(--border); }
[data-growth] .gw-card > .own-sec,
[data-growth] .gw-card > .gw-sec { margin-top: 18px; }
[data-growth] .gw-h,
[data-growth] .own-h { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 0 0 8px; font-size: 13.5px; font-weight: bold; color: var(--ink); }
[data-growth] .gw-close { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
[data-growth] .gw-close li { font-size: 13px; line-height: 1.45; color: var(--ink-soft); }
[data-growth] .gw-skill { font-weight: bold; color: var(--ink); text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px; }
[data-growth] .gw-skill:hover { text-decoration-color: currentColor; }
[data-growth] .gw-to { margin-left: 2px; font-size: 12px; color: var(--muted-small); white-space: nowrap; }
[data-growth] .gw-next { display: block; margin-top: 1px; font-size: 12.5px; }
[data-growth] .gw-next b { color: var(--ink); }
[data-growth] .gw-none { margin: 0; font-size: 13px; color: var(--ink-soft); max-width: 70ch; }
[data-growth] .gw-pieces { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
[data-growth] .gw-piece { font-size: 13px; line-height: 1.45; color: var(--ink-soft); }
[data-growth] .gw-piece b { color: var(--ink); }
[data-growth] .gw-piece .own-where { font-size: 12px; }
[data-growth] .gw-piece > .gw-line { display: block; font-size: 12.5px; }
[data-growth] .gw-more { margin-top: 10px; }
[data-growth] .gw-more > summary {
  display: inline-flex; align-items: center; gap: 6px; list-style: none; cursor: pointer; border-radius: 4px;
  font-size: 12.5px; font-weight: bold; color: var(--ink);
  text-decoration: underline; text-decoration-color: var(--dot); text-underline-offset: 2px;
}
[data-growth] .gw-more > summary::-webkit-details-marker { display: none; }
[data-growth] .gw-more > summary::marker { content: ""; }
[data-growth] .gw-more > summary:hover { text-decoration-color: currentColor; }
[data-growth] .gw-more > summary::after {
  content: ""; flex: none; display: inline-block; width: 5px; height: 5px; margin: -3px 2px 0 1px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg);
}
[data-growth] .gw-more[open] > summary::after { margin-top: 3px; transform: rotate(-135deg); }
[data-growth] .gw-more > .gw-pieces { margin-top: 10px; }
[data-growth] .gw-add { margin: 12px 0 0; }
/* Work not linked to a sub skill yet: one line under the list, each title a way to link it. */
[data-growth] .gw-unlinked { margin: 0; font-size: 13px; line-height: 1.45; color: var(--ink-soft); max-width: 70ch; }
[data-growth] :is(.gw-pieces, .gw-more) + .gw-unlinked { margin-top: 12px; }
@container growth (width >= 700px) {
  [data-growth] .gw-card { padding: 22px 22px 24px; }
  [data-growth] .gw-top { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 18px 28px; }
}
@container growth (width < 511px) {
  /* A card inside the lens's frame leaves the words a narrow column on a phone: drop it, as the tree does. */
  [data-growth] .gw-card { border: 0; border-radius: 0; padding: 0; }
  [data-growth] .c-group { grid-template-columns: minmax(0, 1fr); }
  [data-growth] .st-notes { padding: 8px 10px; }
}

/* ---------- with the script ----------
   html.st-js is set by the tree's own script as it starts, and stays on the page, so these rules hold across
   every swap. Each one is for something only the script can do. */
/* Tree or List: the switch chooses, so the list's own disclosure line goes, and the list shows only when chosen. */
html.st-js [data-skills-tree] .view-switch { display: inline-flex; }
html.st-js [data-skills-tree] .lv-wrap > summary { display: none; }
html.st-js [data-skills-tree] .lv { display: none; margin-top: 22px; scroll-margin-top: 12px; }
html.st-js [data-skills-tree][data-view-now="list"] .lv { display: block; }
html.st-js [data-skills-tree][data-view-now="list"] .tree-area { display: none; }
/* While a search is on, the list keeps a screen's height, so the page does not shrink under the box and, on a
   phone, drop it under the keyboard. */
html.st-js [data-skills-tree] .lv.is-finding { min-height: 100vh; }
/* Close: one sub skill open at a time. */
html.st-js [data-skills-tree] .tl-close { display: inline-block; }
/* The details shown are the ones the script chose, whatever the address says. */
html.st-js [data-skills-tree] .detail,
html.st-js [data-skills-tree] .detail:target { display: none; }
html.st-js [data-skills-tree] .detail.is-open { display: block; }
/* The keyboard tip beside How to read this, only while the keyboard is in the tree or on that summary, which is
   when the arrow keys it names work. */
html.st-js [data-skills-tree] .tree-area:has(.nb > summary:focus-visible) .kb-tip,
html.st-js [data-skills-tree] .tree-area:has(.sk > .row:focus-visible) .kb-tip,
html.st-js [data-skills-tree] .keys:has(.how-to-read > summary:focus-visible) .kb-tip { visibility: visible; }
/* Where the pill and the tip no longer fit side by side (a 320 frame is 1280 at 400% zoom), the tip sits under
   the pill, in the flow, and only while the keyboard is there. */
@media (hover: hover) {
  @container skills-tree (width < 350px) {
    [data-skills-tree] .kb-tip { position: static; display: none; width: max-content; max-width: 100%; margin: 6px 0 0; }
    html.st-js [data-skills-tree] .tree-area:has(.nb > summary:focus-visible) .kb-tip,
    html.st-js [data-skills-tree] .tree-area:has(.sk > .row:focus-visible) .kb-tip,
    html.st-js [data-skills-tree] .keys:has(.how-to-read > summary:focus-visible) .kb-tip { display: block; }
  }
}
/* While htmx fetches a row's timeline, its way to the page stays out of sight; it shows again only if nothing
   came back. */
html.st-js [data-skills-tree] .sk.htmx-request > .tl .tl-wait { visibility: hidden; }
/* A timeline and a module's list come in gently. Backwards, not both: a fill that outlasts the animation would
   keep a transform on the card, make it a stacking context, and trap the module list under the rows below. */
html.st-js [data-skills-tree] .sk[open] > .tl .tl-card:not(.tl-wait) { animation: st-in 0.26s ease-out backwards; }
html.st-js [data-skills-tree] .tl-also[open] > .tl-pop { animation: st-in 0.18s ease-out backwards; }
@keyframes st-in {
  from { opacity: 0; transform: translateY(-5px); }
  to { opacity: 1; transform: none; }
}
/* With room, a module's list is too wide for its column, so it lies across the card, opaque and above the
   other trimesters. The script makes room for it under the trimesters, so the card's words and the rows below
   move down rather than going under it. */
@container skills-tree (width >= 790px) {
  html.st-js [data-skills-tree] .tl-pop {
    position: absolute; left: 2%; right: 2%; z-index: 6; margin: 6px 0 4px; padding: 12px 16px 13px;
    box-shadow: 0 10px 28px rgba(31, 42, 68, 0.16);
  }
  html.st-js [data-skills-tree] .tl-pop-g { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px 18px; }
  html.st-js [data-skills-tree] .tl-pop-g ul { padding-left: 14px; }
  html.st-js [data-skills-tree] .tl-pop-g a,
  html.st-js [data-skills-tree] .tl-pop-h { overflow-wrap: normal; hyphens: manual; }
}

/* ---------- motion and forced colours ---------- */
@media (prefers-reduced-motion: reduce) {
  [data-skills-tree] *,
  [data-skills-tree] *::before,
  [data-skills-tree] *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}
/* Windows high contrast. The drawing keeps its shapes, filled or hollow, solid or dashed, in the system's
   own colours, and the stops and nodes that say "now" keep a ring where their fill and shadow are taken. */
@media (forced-colors: active) {
  [data-skills-tree] svg {
    forced-color-adjust: none;
    --hue: CanvasText !important; --tint: Canvas !important; --ink: CanvasText; --ink-soft: CanvasText;
    --muted-small: CanvasText; --surface: Canvas; --border: GrayText; --border-strong: GrayText;
    --band: Canvas; --now-bg: Canvas; --lit-bg: Canvas; --track: GrayText; --line: GrayText; --dot: GrayText;
  }
  [data-skills-tree] svg :is(.m-next, .m-ahead, .c-mark) { fill: Canvas; }
  [data-skills-tree] svg :is(.m-base, .c-grid) { stroke: GrayText; }
  [data-skills-tree] svg .stdline { stroke: Highlight; }
  [data-skills-tree] svg .stdpill { fill: Highlight; }
  [data-skills-tree] svg :is(.stdtext, .nowtext, .root-you) { fill: HighlightText; }
  [data-skills-tree] svg :is(.nowpill, .root) { fill: Highlight; stroke: Highlight; }
  [data-skills-tree] .jr-stop[aria-current="true"] .jr-node,
  [data-skills-tree] .is-now .tl-node,
  [data-skills-tree] .lp .current .lp-node { outline: 2px solid CanvasText; outline-offset: 2px; }
  [data-skills-tree] .row:focus-visible .fring { stroke: Highlight; }
  [data-skills-tree] .jr-gap { forced-color-adjust: none; background: GrayText; }
  /* The journey's line keeps its shape in system colours: solid behind, dashed ahead, and each year's own. */
  [data-skills-tree] .jr-stop::before { forced-color-adjust: none; background: repeating-linear-gradient(90deg, GrayText 0 4px, transparent 4px 8px); }
  [data-skills-tree] .jr-stop.is-done::before,
  [data-skills-tree] .jr-stop.is-now.is-last::before { background: CanvasText; }
  [data-skills-tree] .jr-stop.is-now::before { background: linear-gradient(90deg, CanvasText 0 50%, transparent 50%), repeating-linear-gradient(90deg, GrayText 0 4px, transparent 4px 8px); }
  [data-skills-tree] .jr-stop.is-now.is-first::before { background: repeating-linear-gradient(90deg, GrayText 0 4px, transparent 4px 8px); }
}
