/* ============================================================================
   cand-rail.jsx — the candidate record's RIGHT RAIL: the Details field list
   (freshness, status, rate, availability, the "All details" fold, contact
   actions), the pending-updates review block, the Engagement link, Notes,
   Tasks, Pipeline and Files - plus the Activity pane behind the rail's second
   tab.

   Split out of screens-core.jsx's CandidateDetailScreen. Loaded AFTER
   screens-core.jsx, so RailFact / RailFold / RailSection (record-shell.jsx),
   FreshnessMenu / TechStackChips / Timeline / ActorChip / e8AgoLabel /
   e8FreshFieldLabel / e8FreshVal (screens-core.jsx) and DSc (shell.jsx) all
   resolve from the shared global scope at render time.

   These are the two panes RecordRail switches between. They were plain JSX
   VALUES (`const railDetails = (…)`) inside the screen; as components they add
   a React layer and no DOM node, and every store write, Undo and toast stays
   in cand-record.jsx - the rail is presentational, the shell owns the writes.

   No inline `style` here: a new .jsx carries an inline-style budget of 0
   (scripts/check-inline-style.mjs), so the styles that came across are classes
   in cand-rail.css that reproduce the same declarations exactly.
   ============================================================================ */

function CandRailDetails({
  c, cmeta, listMeta, prof, D, fresh, reqRequested, headerStage, linkedInUrl, liveLists,
  placement, placementCid, humanNoteRows, pipeSubs, pipeApps, pipeTotal, candFiles,
  filesTrigRef, cap, requestReverify, resolveConflict, commitRecordField, commitAvailability,
  openRailActivity, setFilesMode, setDebriefFor,
}) {
  /* Piece 9. The pane used to be ONE unlabelled run of ten label/value rows with the
     "All details" fold buried in the middle of it, so Name/Phone/Email read as an afterthought
     below a disclosure they have nothing to do with. Two captioned groups instead - the same
     uppercase-caption grammar every section BELOW already used, which is the point: the Details
     pane was the only block in the rail with no head at all. */
  /* R143: the sections live inside `.e8-cand-rail-cols` so the pane can pair them into two
     columns when it is WIDE - which only ever happens in the bottom sheet (see cand-rail.css).
     The footnote stays outside it: it is one line about the whole pane, not a section. */
  return (
    <div className="e8-cand-rail-pane">
      <div className="e8-cand-rail-cols">
      {/* THE INSTRUCTION MUST MATCH THE ROWS. "click a value to edit" was a blanket promise that
          half the pane broke: Freshness owns its own popover control, Status belongs to the stage
          workflow, and Name is deliberately read-only (see Contact below) - so four of eight rows
          did nothing when clicked. The legend now names the MARK rather than the gesture: the same
          pencil, in the same ink, that every editable value carries. It is true by construction -
          a row without the pencil is not editable, and a row with it is.
          A LEGEND, NOT A SENTENCE, because of 2px: `.e8-rrail-sec-act` is `flex: none`, so the
          caption beside it absorbs every extra character. In the 234px desktop rail the head has
          146px to spare and "marks what you can edit" measured 148 - it wrapped "AT A GLANCE"
          onto two lines. This measures 71. */}
      <RailSection title="At a glance" action={(
        /* BARE comment, not `{...}`: this is an EXPRESSION position (inside `action={( … )}`),
           where the braces are an object literal and not a JSX comment - it is a parse error,
           and it was one here until check-jsx-parse said so.
           The glyph is aria-hidden, so the legend alone would read as "= editable" to a screen
           reader. The title carries the whole sentence for hover AND for AT; the per-row
           "<value> - click to edit" titles RailFact already sets do the rest. */
        <span className="e8-cand-rail-edithint" title="A pencil marks a value you can edit">
          <span className="material-symbols-outlined e8-cand-rail-hintic" aria-hidden="true">edit</span>
          = editable
        </span>
      )}>
        <div className="e8-rrail-fact">
          <span className="e8-rrail-fact-k">Freshness</span>
          {/* Freshness rendered at --ui-text-sm in TERTIARY ink while every value beside it was
              --ui-text-base in primary, so the one fact that says whether to trust the rest of
              the pane read as disabled. .e8-cand-rail-freshv puts it back on the value scale. */}
          <span className="e8-ui-push e8-cand-rail-freshv">
            {fresh ? <FreshnessMenu c={c} cmeta={cmeta} fresh={fresh} reqRequested={reqRequested} onReverify={requestReverify} /> : <span className="e8-rrail-fact-v">—</span>}
          </span>
        </div>
        <RailFact label="Status" value={headerStage} />
        <RailFact label="Rate" value={c.rate || ''} display={c.rate ? c.rate + ' W2' : null} editable
          validate={(v) => (!v ? 'Enter a rate, or press Esc' : null)}
          onCommit={commitRecordField('rate', 'Rate')} placeholder="Unknown — add" />
        <RailFact label="Availability" value={cmeta.availability || ''} editable
          validate={(v) => (!v ? 'Enter availability, or press Esc' : null)}
          onCommit={commitAvailability} placeholder="Unknown — add" />
        {/* Location is EDITABLE now. It is the fact a recruiter corrects most after rate - a
            candidate relocates, or the record was seeded from a résumé header - and it was inert
            under a header that promised the opposite. It writes through the same generic
            `matches` committer as Rate/Phone/Email (cand-record.jsx:836), so it gets the same
            Undo, the same fact-edit note and the same audit entry; nothing new to keep in step.
            Status stays read-only on purpose: the stage is moved by the workflow, not typed. */}
        <RailFact label="Location" value={c.location || ''} editable
          validate={(v) => (!v ? 'Enter a location, or press Esc' : null)}
          onCommit={commitRecordField('location', 'Location')} placeholder="Unknown — add" />
        {/* R125 design order: the fold sits ABOVE the identity facts - "All details · 6" opens
            Source · Work auth · Owner · Languages · Skills · Lists & campaigns and flips to
            "Fewer details". Keep the count in step with the facts rendered below. */}
        <RailFold label="All details" count={6}>
          <RailFact label="Source" value={listMeta.source || (typeof E8_ENTRY_SOURCE_LABEL !== 'undefined' && E8_ENTRY_SOURCE_LABEL[cmeta.entrySource]) || 'Unknown'} />
          {cmeta.workAuth ? (
            <RailFact label="Work auth"
              display={(() => {
                const p = (cmeta.fieldProv || {}).workAuthNoSponsorship || (cmeta.fieldProv || {}).workAuth;
                const prov = p ? ((p.source === 'candidate' ? 'candidate-verified' : 'recruiter-entered') + ' · ' + e8AgoLabel(p.verifiedAt)) : 'unverified';
                const v = cmeta.visa || {};
                const tip = cmeta.workAuthNoSponsorship === 'No' && v.type
                  ? v.type + ' · expires ' + v.expires + ' · I-140: ' + v.i140 + ' · ' + prov
                  : prov;
                return <span title={tip}>{cmeta.workAuth}{cmeta.workAuthNoSponsorship === 'No' ? ' · visa on file' : ''}</span>;
              })()}
              value={cmeta.workAuth}
              meta={(() => {
                const p = (cmeta.fieldProv || {}).workAuthNoSponsorship || (cmeta.fieldProv || {}).workAuth;
                return p && p.verifiedAt ? e8AgoLabel(p.verifiedAt) : null;
              })()} />
          ) : (
            <button type="button" className="e8-unknown-ask e8-cand-rail-askbtn" onClick={requestReverify}>Work auth unknown - ask</button>
          )}
          <RailFact label="Owner" value={listMeta.owner || 'Unassigned'} />
          <RailFact label="Languages" value={prof.languages.join(', ')} />
          <div className="e8-cand-rail-foldblk">
            <div className="e8-rrail-sec-head"><span className="e8-rrail-sec-title">Skills</span></div>
            <TechStackChips skills={prof.techStack} />
          </div>
          <div className="e8-cand-rail-foldblk">
            <div className="e8-rrail-sec-head"><span className="e8-rrail-sec-title">Lists &amp; campaigns</span></div>
            {liveLists.length ? (
              <div className={'e8-cand-rail-listpills' + (prof.campaigns.length ? ' is-spaced' : '')}>
                {liveLists.map((l) => (
                  <button
                    key={l.id}
                    type="button"
                    className="e8-listpill"
                    title={l.visibility === 'private' ? 'Only you' : (l.owner ? 'Shared - by ' + l.owner : 'Shared')}
                    onClick={() => navigate('list/' + l.id)}
                  >
                    <span className="material-symbols-outlined" style={{ fontSize: 'var(--ui-icon-xs)' }}>{l.visibility === 'private' ? 'lock' : 'bookmark'}</span>
                    {l.name}
                  </button>
                ))}
              </div>
            ) : null}
            {prof.campaigns.length ? prof.campaigns.map((cp) => (
              <button key={cp.name} type="button" className="e8-applrow" onClick={() => navigate('sequences')}>
                <span className="e8-cand-rail-campname">{cp.name}</span>
                <span className="e8-ui-static e8-ui-push"><DSc.Badge tone="neutral">{cp.state}</DSc.Badge></span>
              </button>
            )) : null}
            {!liveLists.length && !prof.campaigns.length ? <window.Text as="div" size="sm" tone="secondary">Not on any list or sequence.</window.Text> : null}
          </div>
        </RailFold>
      </RailSection>

      <RailSection title="Contact">
        {/* Name is READ-ONLY this round: candidate names are denormalized across submissions,
            sequences, approvals, conversations and files - a matches-only write would desync
            five collections. A transactional rename helper is its own round. */}
        <RailFact label="Name" value={c.name} />
        <RailFact label="Phone" value={c.phone || ''} editable
          validate={(v) => (!v ? 'Enter a phone number, or press Esc' : (String(v).replace(/\D/g, '').length < 7 ? 'That does not look like a phone number' : null))}
          onCommit={commitRecordField('phone', 'Phone')} placeholder="Add" />
        <RailFact label="Email" value={c.email || ''} editable
          validate={(v) => (!v ? 'Enter an email, or press Esc' : (!/^\S+@\S+\.\S+$/.test(v) ? 'That does not look like an email' : null))}
          onCommit={commitRecordField('email', 'Email')} placeholder="Add" />
        <div className="e8-glance-acts">
          {c.email
            ? <a className="e8-glance-ic" href={'mailto:' + c.email} title={'Email ' + c.email}><span className="material-symbols-outlined" aria-hidden="true">mail</span></a>
            : <span className="e8-glance-ic is-off" title="No email on file"><span className="material-symbols-outlined" aria-hidden="true">mail</span></span>}
          {c.phone
            ? <a className="e8-glance-ic" href={'tel:' + String(c.phone).replace(/[^+\d]/g, '')} title={'Call ' + c.phone}><span className="material-symbols-outlined" aria-hidden="true">call</span></a>
            : null}
          {linkedInUrl
            ? <a className="e8-glance-ic" href={linkedInUrl} target="_blank" rel="noreferrer" title="Open LinkedIn profile"><span className="material-symbols-outlined" aria-hidden="true">open_in_new</span></a>
            : null}
        </div>
      </RailSection>

      {/* R107 T3: pending updates from a portal submit - flagged, reviewable, undoable. */}
      {(() => {
        const pend = Array.isArray(cmeta.pendingConflicts) ? cmeta.pendingConflicts : [];
        if (!pend.length) return null;
        return (
          <RailSection title="Pending updates from candidate" count={pend.length}>
            <div className="e8-cand-rail-pendhint">
              The candidate reported these in their portal. Accept to apply the new value, or keep the current one.
            </div>
            <div className="e8-cand-rail-pendlist">
              {pend.map((cf) => (
                <div key={cf.field} className="e8-cand-rail-pendcard">
                  <window.Row gap={8} wrap>
                    <window.Text size="sm" weight="semibold">{e8FreshFieldLabel(cf.field)}</window.Text>
                    <span className="e8-ui-push"><DSc.Badge tone="warning" dot>flagged</DSc.Badge></span>
                  </window.Row>
                  <window.Text as="div" size="sm" tone="secondary" mt={4}>
                    {e8FreshVal(cf.old)} <window.Text tone="tertiary">-&gt;</window.Text> <window.Text as="b" weight="semibold">{e8FreshVal(cf['new'])}</window.Text>
                  </window.Text>
                  <window.Row gap={6} align="stretch" mt={8} className="e8-cand-rail-inline">
                    <DSc.Button variant="primary" size="sm" icon="check" onClick={() => resolveConflict(cf.field, 'accept')}>Accept</DSc.Button>
                    <DSc.Button variant="ghost" size="sm" onClick={() => resolveConflict(cf.field, 'keep')}>Keep current</DSc.Button>
                  </window.Row>
                </div>
              ))}
            </div>
          </RailSection>
        );
      })()}

      {/* R104 nit C: placed candidate -> a navigable link to the engagement they became. */}
      {placement && placementCid ? (
        <RailSection title="Engagement">
          <button type="button" className="e8-applrow" onClick={() => navigate('consultant/' + placementCid)}>
            <span className="e8-ui-shrink">
              <window.Text size="sm" weight="medium" block>Now a consultant</window.Text>
              <window.Text size="xs" tone="tertiary" block>{placement.eng ? placement.eng.role + ' · ' + placement.eng.client : 'View engagement'}</window.Text>
            </span>
            <window.Row as="span" gap={6} className="e8-cand-rail-inline e8-ui-static e8-ui-push">
              <DSc.Badge tone="success" dot>Placed</DSc.Badge>
              <span className="material-symbols-outlined e8-cand-rail-chev">chevron_right</span>
            </window.Row>
          </button>
        </RailSection>
      ) : null}

      {(() => {
        /* R142: Notes moved from BELOW Pipeline to the top of the rail's work sections.
           The reviewer's words were "notes are at the bottom right-hand side of that bar... more
           necessary and important on day to day use than lost at the bottom of the page", and she
           was right: Notes sat under Pipeline, showed 5 of N with no way to reach the rest, and
           printed the true total in its header while silently truncating.
           Two changes, both lifted from the JOB rail rather than invented - it is the surface she
           praised: (1) a bounded list with an EXPLICIT tail, so the count in the header is now a
           door rather than a claim; (2) the same "All notes · N" action shape the Files section
           immediately below has always had. Cap is 3, matching the rail's other lists.
           Tasks moves with it: the two were already adjacent and are the same kind of thing -
           what you did and what you owe - so splitting them to satisfy the ordering would have
           traded one incoherence for another.
           R125: rows open the rich NoteDoc window (dockable on desktop) - raw notes, not the
           merged event shapes, so the doc gets the real editable record. */
        /* R142 batch 4: human-written notes only - a list of "Rate updated" rows is not the
           "notes matter day to day" surface. Reuses the set the Activity segment already derived
           rather than repeating the filter; they were byte-identical chains over the same rows. */
        const railNotes = humanNoteRows;
        const openDoc = (n) => { if (window.e8OpenNoteDoc) window.e8OpenNoteDoc({ noteId: n.id }); };
        const NOTES_SHOWN = 3;
        return (
          <RailSection title="Notes" count={railNotes.length}
            /* Lands the rail on the NOTES segment, not on whatever segment was last open: the
               action says "All notes", and Activity defaults to "all". */
            action={railNotes.length > NOTES_SHOWN ? (
              <button type="button" className="e8-link e8-cand-rail-more"
                onClick={() => openRailActivity('notes')}>All notes · {railNotes.length}</button>
            ) : null}>
            {railNotes.length ? railNotes.slice(0, NOTES_SHOWN).map((n, i) => (
              <div key={n.id} role="button" tabIndex={0} className={'e8-rrail-noterow e8-cand-rail-noterow' + (i ? ' is-sep' : '')}
                title="Open the full note"
                onClick={() => openDoc(n)}
                onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openDoc(n); } }}>
                <div className="e8-link e8-cand-rail-notetitle">{n.title}</div>
                {(n.points || []).length ? <div className="e8-cand-rail-notepts">{n.points.join(' · ')}</div> : null}
                <window.Row gap={6} mt={5}>
                  <ActorChip name={n.author || n.by || 'You'} ai={!!n.ai} />
                  <window.Text size="xs" tone="tertiary" className="tnum e8-ui-push">{n.when || (window.e8AgoLabel && n.ts ? window.e8AgoLabel(n.ts) : '')}</window.Text>
                </window.Row>
              </div>
            )) : (
              /* Piece 10 empty states. "No notes on this record yet." states a fact and asks for
                 nothing; every empty in this rail did the same. One shape now - a line that says
                 what the block is FOR, then the block's own add row directly under it. */
              <div className="e8-cand-rail-empty">Nothing written down yet. Notes are what the next person on this record reads first.</div>
            )}
            {/* R126: same add-row anatomy as Tasks - a "+" hiding in the header while Tasks
                spells out "Add task" read as two different systems. */}
            <button type="button" className="e8-rrail-addrow" onClick={() => cap.open({ target: 'note', entityLabel: c.name, refType: 'candidate', refId: c.id })}>
              <span className="material-symbols-outlined" aria-hidden="true">add</span>
              Add note
            </button>
          </RailSection>
        );
      })()}

      {/* Tasks: the SAME model + selector as the Work queue (bare = no card-in-card). */}
      {window.RecordTasksRail ? <window.RecordTasksRail refType="candidate" refId={c.id} bare /> : null}

      {/* R111 B1: ONE Pipeline list - applications + submissions merged. */}
      <RailSection title="Pipeline" count={pipeTotal}>
        {pipeApps.map((a, i) => (
          <button key={'a' + i} type="button" className="e8-applrow" onClick={() => navigate('job/' + a.jobId + '/overview')}>
            <span className="e8-ui-shrink">
              <span className="e8-cand-rail-rowtitle">{a.job}</span>
              <window.Text size="xs" tone="tertiary" block>{a.jobId} · {a.client}</window.Text>
            </span>
            <window.Row as="span" gap={6} className="e8-cand-rail-inline e8-ui-static e8-ui-push">
              <DSc.Badge tone={a.tone || 'info'} dot>{a.stage}</DSc.Badge>
              <window.Text size="xs" tone="tertiary" className="tnum">{a.when}</window.Text>
            </window.Row>
          </button>
        ))}
        {pipeSubs.length || pipeApps.length ? pipeSubs.map((s) => {
          const hist = (Array.isArray(s.stageHistory) && s.stageHistory.length) ? s.stageHistory : null;
          const last = hist ? hist[hist.length - 1] : null;
          const when = last && last.at != null ? e8AgoLabel(last.at) : (s.when || '');
          return (
            <React.Fragment key={s.id}>
              <button type="button" className="e8-applrow e8-cand-rail-subrow" onClick={() => navigate('job/' + s.jobId + '/submissions')}>
                <span className="e8-ui-shrink">
                  <span className="e8-cand-rail-rowtitle">{s.job}</span>
                  <window.Text size="xs" tone="tertiary" block>{s.jobId} · {s.client}</window.Text>
                  <window.Text block mt={6}><DSc.StageCell stages={D.submissionStages} current={s.stage} /></window.Text>
                </span>
                <window.Text size="xs" tone="tertiary" className="tnum e8-ui-static e8-ui-push">{when}</window.Text>
              </button>
              {(s.stage | 0) >= 2 ? (
                <div className="e8-dbf-row">
                  {s.acceptOnBehalf ? <DSc.Badge tone="success" dot>Pre-authorized · {s.acceptOnBehalf.rate}</DSc.Badge> : null}
                  {(window.e8SubDebriefs ? window.e8SubDebriefs(s) : (s.debrief ? [s.debrief] : [])).map((d) => (
                    <DSc.Badge key={d.round || 1} tone="info">R{d.round || 1}{d.went ? ' · ' + d.went : ' · Debriefed'}</DSc.Badge>
                  ))}
                  {(s.stage | 0) === (D.submissionStages || []).indexOf('Interview') ? (() => {
                    const roundNo = (s.interview && s.interview.round) || 1;
                    const current = window.e8SubDebriefFor ? window.e8SubDebriefFor(s, roundNo)
                      : (s.debrief && (s.debrief.round || 1) === roundNo ? s.debrief : null);
                    return <DSc.Button variant="ghost" size="sm" icon="record_voice_over"
                      onClick={() => setDebriefFor({ sub: s, round: roundNo })}>{current ? 'Edit current debrief' : 'Log current debrief'}</DSc.Button>;
                  })() : null}
                </div>
              ) : null}
            </React.Fragment>
          );
        }) : (
          <React.Fragment>
            <div className="e8-cand-rail-empty">Not in any process yet. Put {String(c.name).split(' ')[0]} in front of a job to start one.</div>
            {/* The only empty in the rail that had no way out at all. e8OpenCreate is the same
                host the record's own Submit button falls back to (cand-record.jsx:192), so this
                opens the REAL deduped submission dialog prefilled to this candidate - not a
                toast, and not a second submit path to keep in step. */}
            <button type="button" className="e8-rrail-addrow"
              onClick={() => {
                if (window.e8OpenCreate) window.e8OpenCreate('submission', { prefillCand: c.id });
                else navigate('jobs');
              }}>
              <span className="material-symbols-outlined" aria-hidden="true">add</span>
              Submit to a job
            </button>
          </React.Fragment>
        )}
      </RailSection>

      {/* Files: a summary here; the full workflow (CV toolkit, link file, view résumé) lives
          in the overlay behind "All files · N" - it does not fit a 300px rail. */}
      <RailSection title="Files"
        action={candFiles.length ? (
          <button type="button" ref={filesTrigRef} className="e8-link e8-cand-rail-more"
            onClick={() => setFilesMode('list')}>All files · {candFiles.length}</button>
        ) : null}>
        {candFiles.length ? candFiles.slice(0, 2).map((f) => (
          <button key={f.id || f.name} type="button" className="e8-applrow" onClick={() => setFilesMode('list')}>
            <span className="material-symbols-outlined e8-cand-rail-fileic">{f.kind || 'description'}</span>
            <span className="e8-cand-rail-filename">{f.name}</span>
            <window.Text size="xs" tone="tertiary" className="tnum e8-ui-static e8-ui-push">{f.when}</window.Text>
          </button>
        )) : (
          <React.Fragment>
            {/* Copy is FROZEN by scripts/test-candidate-files.mjs:19, which matches this exact
                sentence; only the chassis moves to the shared empty class. Files was already
                the one block that invited the first item - it is the shape the other three
                were brought up to, not the one being changed. */}
            <div className="e8-cand-rail-empty">No files on this record yet.</div>
            <button type="button" ref={filesTrigRef} className="e8-rrail-addrow" onClick={() => setFilesMode('add')}>
              <span className="material-symbols-outlined" aria-hidden="true">add</span>
              Add a résumé or file
            </button>
          </React.Fragment>
        )}
      </RailSection>

      {/* Lists & campaigns live inside the "All details" fold now, per the design. */}
      </div>

      {/* "click any dashed fact to edit" was the ONLY edit affordance, and it lived ~840px below
          the facts it described. The pencil on each editable value says it where the value is;
          the footnote keeps the half a recruiter cannot see anywhere else. */}
      <div className="e8-rrail-footnote">every edit lands in Activity</div>
    </div>
  );
}

function CandRailActivity({ c, cap, tl, railMovement, railNoteEvs, actSeg, setActSeg }) {
  return (
    <div className="e8-cand-rail-pane e8-cand-rail-actpane">
      <DSc.SubTabs
        items={[
          { id: 'all', label: 'All', count: tl.length },
          { id: 'movement', label: 'Movement', count: railMovement.length || undefined },
          { id: 'notes', label: 'Notes', count: railNoteEvs.length || undefined },
        ]}
        active={actSeg === 'files' ? 'all' : actSeg} onChange={setActSeg}
      />
      <div className="e8-cand-rail-actbody">
        {actSeg === 'notes' ? (
          railNoteEvs.length ? <Timeline events={railNoteEvs} quiet /> : (
            <div className="e8-cand-rail-emptypad">
              {/* WAVE-3 SEAM FIX — ONE SENTENCE FOR ONE EMPTY BLOCK. Notes has two empties in
                  this rail, one tab apart on the same record: the Details pane says "Nothing
                  written down yet. Notes are what the next person on this record reads first."
                  and this one said "Notes land here and in the Details sections." Two voices for
                  one state, and the second one described the FILING SYSTEM rather than telling
                  the recruiter anything about the candidate. The shapes legitimately differ - a
                  line inside a section there, a full-pane `EmptyState` here - but the sentence
                  should not, so this pane borrows the other one verbatim. */}
              <DSc.EmptyState icon="sticky_note_2" title="No notes yet" body="Nothing written down yet. Notes are what the next person on this record reads first."
                cta={<DSc.Button variant="secondary" size="sm" className="e8-empty-cta" icon="note_add" onClick={() => cap.open({ target: 'note', entityLabel: c.name, refType: 'candidate', refId: c.id })}>Add the first note</DSc.Button>} />
            </div>
          )
        ) : (
          <Timeline events={actSeg === 'movement' ? railMovement : tl} quiet />
        )}
      </div>
      <div className="e8-rrail-footnote">edits &amp; audit live here — their one home</div>
    </div>
  );
}

Object.assign(window, { CandRailDetails, CandRailActivity });
