overview· xtz deposits· fa deposits· xtz withdrawals· xtz fast withdrawals· fa withdrawals· design
Bridge indexing · design system

Design system

Color — two axes

Axis 1 · HUE = runtime

L1 / bridge--l1
EVM L2--evm
Michelson L2--mich
alias / NAC--alias
feed / kernel--feed
system / legacy--sys

Axis 2 · ACCENT = indexed

indexed ✓--idx
planned ◔--planned

Encoding — legend

Legend
Hue L1 / bridge L2 EVM L2 Michelson kernel / feed
Decision indexed planned not indexed
Status legacy · remains in mainnet

Layout and verification

one object = one node

One on-chain object = one node in the standard format (§3 · Node dictionary). Paired events (Token Mint/Burn) — as a separate node.

self-check before showing

Mermaid captures the geometry (overflow / collisions / a “missed arrow” are impossible). Before showing — verify the render has no console errors and that line statuses/colors are in place; screenshot the diagram by uid (take_snapshot → take_screenshot).

Mermaid

flowchart TD
  U(["User"]):::actor
  K["<b class='t'>Kernel parse_routing</b>"]:::ker
  subgraph R["L2 · EVM · ACTUAL"]
    direction TB
    E["<span class='glyph'>✓</span><b class='t'>Value Transfer</b><span class='s'>Blockscout · transaction · 0x…feed</span><span class='ix'>✓ etherlink.on_xtz_deposit</span><span class='md'>✚ EtherlinkDepositOperation</span>"]:::evm
    F["<b class='t'>Event Deposit</b><span class='s'>Blockscout · event · 0xff…01</span>"]:::evm
    E --> F
  end
  M["<span class='glyph'>◔</span><b class='t'>Event Deposit</b><span class='s'>TzKT · event · tz1Ke2h7…</span><span class='pln'>◔ planned: tezos.events</span>"]:::mich
  L["<b class='t'>Value Transfer</b><span class='s'>Blockscout · transaction · 0x00…00</span>"]:::evm

  K -->|has code → queue| E
  K -->|Michelson · tz1| M
  K -.->|old kernel| L
  U -.->|initiates deposit| K

  class E indexed
  class M planned
  class F faded
  class L legacy
  class L faded
  class U faded
  class K faded

  classDef l1 fill:#e8836b1f,stroke:#e8836b,stroke-width:1.5px;
  classDef evm fill:#5aa6e01f,stroke:#5aa6e0,stroke-width:1.5px;
  classDef mich fill:#6fbf731f,stroke:#6fbf73,stroke-width:1.5px;
  classDef ker fill:#d9a83c21,stroke:#d9a83c,stroke-width:1.5px;
  classDef sys fill:#8b919c1f,stroke:#8b919c,stroke-width:1.5px;
  classDef indexed stroke-width:2px;
  classDef planned stroke-width:2px;
  classDef faded stroke-width:1.5px;
  classDef legacy stroke-width:1.5px;
  classDef actor fill:transparent,stroke:#e8836b,stroke-width:1.5px;

  linkStyle 0 stroke:#5aa6e0,stroke-width:2.4px;
  linkStyle 1 stroke:#5aa6e0,stroke-width:2.4px;
  linkStyle 2 stroke:#6fbf73,stroke-width:2.4px;
  linkStyle 3 stroke:#5aa6e0,stroke-width:2.4px,stroke-dasharray:6 5,opacity:0.55;
  linkStyle 4 stroke:#e8836b,stroke-width:2.4px,stroke-dasharray:6 5,opacity:0.55;

1 · Node HUE — classDef, applied inline

// fill = hue-bg (.12 alpha, 8-digit hex), stroke = hue
classDef l1   fill:#e8836b1f,stroke:#e8836b,stroke-width:1.5px;
classDef evm  fill:#5aa6e01f,stroke:#5aa6e0,stroke-width:1.5px;
classDef mich fill:#6fbf731f,stroke:#6fbf73,stroke-width:1.5px;
classDef ker  fill:#d9a83c21,stroke:#d9a83c,stroke-width:1.5px;
classDef sys  fill:#8b919c1f,stroke:#8b919c,stroke-width:1.5px;

NODE["…"]:::evm   // hue — inline on the node
⚠️ Pitfall: do not write color: in classDef. Mermaid turns it into the rule .class span{color … !important}, which overrides all per-line colors inside the node (handler/source turn white). Text color is set only by themeCSS (§3); classDef is the node's border/fill.

2 · DECISION — one line per node

class NODE indexed   // ✓ teal glyph + teal handler line
class NODE planned   // ◔ amber glyph
class NODE faded     // not indexed (opacity .45)
class NODE legacy    // dashed border; multiple lines per node allowed
⚠️ Pitfall: a comma in class is a list of NODES, not classes. class NODE evm,indexed reads as “class indexed for nodes NODE and evm” — the hue won't arrive. That's why hue is inline :::evm and decision is one line per class.

3 · Node dictionary — HTML label + themeCSS

NODE["<span class='glyph'></span><b class='t'>Event Withdrawal</b><span class='s'>Blockscout · event · 0xff…02</span><span class='ix'>✓ etherlink.on_withdraw</span><span class='md'>✚ EtherlinkWithdrawOperation</span>"]:::evm

// lines: .t name · .s source (source · type · address) · .ix handler (teal) · .md model · .pln planned (amber)
// themeCSS (inside mermaid.initialize) — line colors:
.nodeLabel .t   { display:block; white-space:nowrap; font-weight:600; color:#eef0f3; padding-right:20px } // name
.nodeLabel .s   { display:block; white-space:nowrap; font-size:9.5px; color:#7c828e } // source
.nodeLabel .ix  { display:block; font-size:9.5px; color:#3ed6c0 }   // handler (teal)
.nodeLabel .md  { display:block; font-size:9.5px; color:#7c828e }   // model
.nodeLabel .pln { display:block; font-size:9.5px; color:#d9a83c }   // planned (amber)
.nodeLabel .glyph { position:absolute; top:-2px; right:0; font-size:17px; font-weight:700 }
.node.indexed .nodeLabel .glyph { color:#3ed6c0 }  // ✓ teal
.node.planned .nodeLabel .glyph { color:#d9a83c }  // ◔ amber
.node.faded   { opacity:.45 }
.node.legacy rect { stroke-dasharray:5 4 }
Node lines do not wrap. white-space:nowrap on every line + keeping them short: the node grows wider, not taller, and doesn't break the layout. source — strictly source · type · address, nothing more. The trailing name (method, event, entrypoint, notes like input=0x / 4-arg / → receiver) lives in the title and is not repeated in source: it only widens the node. The shorter the source line, the narrower the node — and node width, multiplied across side-by-side columns, is what drives the whole diagram's width.
Address — hash or alias, no strict rule. Both read fine: a truncated hash (0xff…01, tz1Ke2h7…) or a role alias (rollup, gateway, tez-ticketer). A hash earns its place when it distinguishes several similar contracts (0xff…01 XTZBridge vs 0xff…02 FABridge); an alias is clearer when there's a single well-known contract and the hash would distinguish nothing. Multi-word aliases are hyphenated.
Title stays short. Forms: Call Contract.method, Event Name, or a role label (Transfer Ticket, Value Transfer, Rollup cement). No runtime prefix (Tezos … — the hue already encodes the runtime) and no parenthetical qualifiers ((mint) / (burn) — disambiguation belongs in the source address).
No stray "why / when" lines. A node says what is indexed. Free-text notes about conditions or phase (only if code present, Block 3, proxy specified?, bridge.rs:401-507) don't read at node size and just clutter — if something needs explaining, extend the graphic, not the node. This isn't a ban on conditions or roadmap: recurring structural facts get a defined encoding here first (a hue, a glyph, a dedicated line class — the way roadmap is already carried by color + status glyphs), and only then appear in nodes. Until it's in this standard, it doesn't go in a node.

4 · ARROW — linkStyle by declaration order

linkStyle 0 stroke:#5aa6e0,stroke-width:2.4px;                                   // evm
linkStyle 3 stroke:#5aa6e0,stroke-width:2.4px,stroke-dasharray:6 5,opacity:.55; // legacy
Mermaid trade-off: the condition label on the arrow stays neutral gray (per-label color matching the runtime hue isn't available out of the box). A deliberate concession for the mermaid medium.

5 · Actor — capsule (stadium node)

SP(["Service Provider"]):::actor
class SP faded
classDef actor fill:transparent,stroke:#e8836b,stroke-width:1.5px;

6 · Init — canonical block (extracted into mermaid-init.js)

import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
mermaid.initialize({
  startOnLoad:false, securityLevel:'loose', theme:'base',
  themeCSS,                                  // the CSS string from §3
  themeVariables:{
    fontFamily:'JetBrains Mono, monospace', fontSize:'12px',
    lineColor:'#565c67', clusterBkg:'transparent',
    clusterBorder:'#1e212a', edgeLabelBackground:'#0e1014',
  },
  flowchart:{ htmlLabels:true, curve:'basis', nodeSpacing:42, rankSpacing:58, padding:10, useMaxWidth:false },
});
await mermaid.run({ querySelector:'.mermaid' });