/* ═══════════════════════════════════════════════════════════════
   NODE GRAPH STYLES — experience + skills
   Sebastian Brown — sebastianbrown.me

   Shared by index.html and the two standalone proof pages, so the
   graphs can never drift apart visually. Assumes the site's CSS
   variables (--void, --ash, --mono …) are already defined.
   ═══════════════════════════════════════════════════════════════ */

/* ── shared: filter chips ── */
.controls{display:flex;flex-wrap:wrap;gap:8px;margin:32px 0 8px}
.chip{
  font-family:var(--mono);font-size:12px;letter-spacing:.06em;
  color:var(--fog);background:transparent;cursor:pointer;
  border:1px solid var(--border);border-radius:var(--r-pill);
  padding:7px 14px;transition:color .2s ease,border-color .2s ease,background .2s ease;
}
.chip:hover{color:var(--white);border-color:var(--rail)}
.chip.on{color:var(--white);border-color:transparent;background:var(--shell)}

/* One curve and duration for every fade in the graphs, so the lines,
   the titles and the whole group all settle together instead of at
   three different speeds. */
:root{ --fade: .42s cubic-bezier(.4,0,.2,1); }

/* ── shared: graph canvas + connectors ── */
.graph{position:relative;margin-top:40px}
.graph svg.links{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}
.graph svg.links path{
  fill:none;stroke-width:1.6;stroke-linecap:round;
  opacity:.55;transition:opacity var(--fade),stroke-width var(--fade);
}
.graph.drawing svg.links path{stroke-dasharray:var(--len);stroke-dashoffset:var(--len)}
.graph.lit svg.links path{stroke-dashoffset:0;
  transition:stroke-dashoffset 1.1s cubic-bezier(.22,.7,.25,1) var(--delay),opacity var(--fade)}
.graph.focus svg.links path{opacity:.08}
.graph.focus svg.links path.active{opacity:.85;stroke-width:2.1}

/* ── shared: the spine node (a year, or a skill category) ── */
.node{
  display:inline-flex;align-items:center;gap:9px;
  font-family:var(--mono);font-size:15px;font-weight:500;color:var(--white);
  background:var(--elevated);border-radius:var(--r-pill);
  padding:8px 16px;white-space:nowrap;
  box-shadow:rgba(255,255,255,.1) 0 0 0 1px inset;
}
.node .dot{width:7px;height:7px;border-radius:50%;flex:none}
.node{transition:box-shadow var(--fade),background var(--fade)}
.yeargroup.active .node,.cat.active .node{
  background:var(--shell);
  box-shadow:rgba(255,255,255,.22) 0 0 0 1px inset;
}


/* ═══════════ EXPERIENCE ═══════════ */

.yeargroup{display:grid;grid-template-columns:104px 1fr;position:relative;margin-bottom:34px;
  transition:opacity var(--fade)}
.yearcell{position:relative;display:flex;align-items:center}
.credits{padding:0 0 0 76px}
.credit{position:relative;padding:9px 0;transition:opacity var(--fade)}
.credit .line{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;
  padding-bottom:7px;border-bottom:1px solid var(--border);
}
.credit .t{font-size:16px;font-weight:500;color:var(--white);letter-spacing:-0.2px}
.credit .r{font-size:13px;color:var(--ash)}
.credit .m{font-family:var(--mono);font-size:11px;color:var(--fog);letter-spacing:.04em}
.credit .tag{
  font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--fog);border:1px solid var(--border);border-radius:var(--r-btn);padding:2px 7px;
}

/* Weight = title profile + role seniority, never medium.
   Tier 1 is what should be read first.                             */
.credit.t1 .t{font-size:19px;font-weight:500;color:var(--white);letter-spacing:-0.34px}
.credit.t1 .r{font-size:13.5px;color:var(--ash)}
.credit.t1 .tag{color:var(--white);border-color:rgba(255,255,255,.34)}
.credit.t1 .line{border-bottom-color:#4a4653}
.credit.t2 .t{font-size:16px;font-weight:500;color:#e8e6ea}
.credit.t2 .r{font-size:13px;color:var(--ash)}
.credit.t3 .t{font-size:14.5px;font-weight:400;color:var(--ash)}
.credit.t3 .r{font-size:12.5px;color:var(--fog)}
.credit.t3 .tag{opacity:.72}

.graph.focus .credit{opacity:.18}
.graph.focus .yeargroup.active .credit{opacity:1}


/* ═══════════ SKILLS ═══════════ */

.cat{display:grid;grid-template-columns:150px 1fr;position:relative;margin-bottom:40px;
  transition:opacity var(--fade)}
.catcell{position:relative;display:flex;align-items:center}
.groups{padding-left:74px}
.grp{display:grid;grid-template-columns:168px 1fr;margin-bottom:4px}
.grp.flat{grid-template-columns:0 1fr}
.grpcell{position:relative;display:flex;align-items:center}
.grpname{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ash);white-space:nowrap;padding-right:14px}
.grp:not(.flat) .items{padding-left:56px}

.item{padding:8px 0}
.item .t{font-size:16px;color:var(--white);font-weight:400;letter-spacing:-0.2px;
  padding-bottom:6px;border-bottom:1px solid var(--border);display:block}
.item ul{list-style:none;margin-top:7px}
.item li{font-size:13px;color:var(--fog);line-height:1.45;padding:2px 0 2px 15px;
  position:relative;max-width:66ch}
.item li::before{content:"";position:absolute;left:0;top:11px;width:7px;height:1px;background:var(--border)}

.graph.focus .cat{opacity:.16}
.graph.focus .cat.active{opacity:1}


/* ═══════════ RESPONSIVE ═══════════ */

@media (max-width:820px){
  .yeargroup{grid-template-columns:1fr;margin-bottom:26px}
  .yearcell{margin-bottom:14px;display:block}
  .credits{padding:0 0 0 28px}
  .credit .t{font-size:15px}
  .credit.t1 .t{font-size:16.5px}

  .cat{grid-template-columns:1fr;margin-bottom:30px}
  .catcell{margin-bottom:14px}
  .groups{padding-left:26px}
  .grp,.grp.flat{grid-template-columns:1fr}
  .grpcell{margin:10px 0 4px}
  .grp:not(.flat) .items{padding-left:18px}
  .item .t{font-size:15px}
}

@media (prefers-reduced-motion:reduce){
  .graph.drawing svg.links path{stroke-dashoffset:0 !important}
}
