Skip to content

Diagram style guide: draw.io and Lucid with the AWS look

Status: v0.1, researched 2026-10-17. Scope: everything an implementer needs to emit AWS-flavoured network diagrams as draw.io (.drawio) and Lucid (.lucid) files without consulting anything else. This file contains no program code; the kind registry in section 5 is the contract the exporters implement.

0. How to read this document

0.1 Evidence tags

Every non-obvious statement carries one tag so the implementer knows how far to trust it.

Tag Meaning
[SRC] Copied from the draw.io source at the pinned commit in 0.2 (file and line given).
[DOC] Read from the Lucid developer documentation (raw markdown pulled on 2026-10-17).
[PNG] Measured on the pixels of the reference diagram. Flat fills are exact within about 2 units per channel; thin lines are anti-aliased, so only their nominal colour is inferred.
[SEE] Observed by looking at the reference diagram.
[KNOWN] Standard mxGraph / draw.io behaviour, not re-checked in this research.
[INFER] Derived by a stated rule. Must be confirmed by a test before it is relied on.
[REC] A decision proposed by this document, not a fact about the formats. Change it freely.

0.2 Sources and pins

What Where Pin
AWS reference page https://docs.aws.amazon.com/managedservices/latest/onboardingguide/malz-network-arch.html fetched 2026-10-17
Reference diagram https://docs.aws.amazon.com/images/managedservices/latest/onboardingguide/images/AMS_MALZ_NET_FLOW-2.png PNG 1196 x 1099 (the same path under /managedservices/... answers 302 to this URL)
Flow legend image https://docs.aws.amazon.com/images/managedservices/latest/onboardingguide/images/AMS_MALZ_NET_FLOW_LEGEND.png PNG 849 x 403
draw.io AWS sidebar github.com/jgraph/drawio, branch dev, commit 9034053fba80a435e27d68d374bc564b83917ae9 (2026-10-08T21:48:17Z), files src/main/webapp/js/diagramly/sidebar/Sidebar-AWS4.js (2553 lines) and Sidebar-AWS4b.js (1061 lines) every Lxxxx in this file is a line of Sidebar-AWS4.js at that commit
Lucid Standard Import https://developer.lucid.co/docs/overview-si, pages-si, shapes-si, lines-si, reference-si, standard-library-si, container-library-si, aws-2024-library, images-si overview updated 2026-05-20, AWS 2024 page updated 2026-04-18

The AMS page carries an end-of-support notice for AMS Advanced (2027-06-30). The values measured on its diagram are copied into this file so the guide survives the page.

0.3 What could not be checked

  • The draw.io stencil file aws4.xml is not at src/main/webapp/stencils/aws4.xml (HTTP 404 at the pinned commit, and stencils/ has no file with "aws" in its name). Icon names below are verified by their use in the sidebar only, not against the stencil definitions.
  • Nothing was rendered (no draw.io, no Lucid account). The reference PNG is the only drawing that was looked at.
  • The Lucid AWS 2024 page says it lists "the full per-category catalog" but shows two examples per category and no other retrievable page lists the rest. Class names outside section 3.4 "verified" are [INFER].
  • The AWS Architecture Icons licence terms were not read (see 3.6 before bundling any icon file).

1. The reference diagram

1.1 What the page says

"Networking account architecture" of the AMS multi-account landing zone. Two images: the diagram and a legend of seven numbered traffic flows. The text explains: standard VPCs are DMZ, shared services and application; all ingress and egress goes through the DMZ except traffic from the trusted network (VPN or Direct Connect from on premises); administrators reach resources through bastions; workloads live in private subnets reachable through public load balancers; public egress leaves through NAT gateways in the egress VPC of the Networking account and then the Internet gateway, or alternatively over VPN or Direct Connect. The legend image also explains the account roles (master, Networking as routing hub, Shared Services, customer accounts).

1.2 Composition [SEE]

Outside AWS (left column)
  "AWS Managed Services (AMS)" box x2 (corporate data center group)
      client icons ("Administration/Operations", "Administration"), users icon ("Corporate Users")
  "External Users" (users icon) --> "Internet" (cloud icon)
AWS Cloud group titled with the account name (three of them)
  Networking Account
    Region
      DMZ VPC               IGW on its left border; 3 AZ bands; one public subnet per AZ holding "DMZ Bastion"
      Networking Egress VPC IGW on its left border; 3 AZ bands; per AZ a public subnet (NAT gateway)
                            and a private subnet (TGW Network Interface)
      Transit Gateway and AWS Direct Connect (service icons) in the Region, outside the VPCs
  Shared Services Account
    Region
      Shared Services VPC   3 AZ bands x 3 private subnets (Customer Bastion / Active Directory / EPS)
  Application Account A
    Region
      Application Account A VPC   IGW on its left border; 3 AZ bands x (public subnet, private subnet with
                                  "Application Instances"); two Elastic Load Balancing icons on the
                                  public/private boundary

1.3 Rules visible in the picture [SEE]

  • Accounts are top-level boxes in a grid. The hub (Transit Gateway) sits between them, Direct Connect between the on-premises box and the hub, and the Internet and on-premises actors form a column at the far left.
  • Nesting is exactly account (AWS Cloud group) > Region > VPC > Availability Zone > subnet > icons.
  • An Availability Zone is a horizontal band across the whole VPC width; the bands are stacked (AZ 1 on top). Inside a band the subnets are columns, and the same role occupies the same column in every band.
  • Subnets are filled rectangles without outline, with a square lock icon in the top-left corner and the label to its right. AZ and Region are dashed outlines without fill. A VPC is a thin solid outline with a square cloud-and-lock icon in the corner.
  • Icon captions are centred under each icon; long names wrap on two or three lines.
  • An Internet gateway sits on the VPC border (half inside, half outside), never inside a subnet. A NAT gateway is inside a public subnet; network interfaces are inside private subnets.
  • Transit Gateway and Direct Connect are Region-level service icons placed outside every VPC.
  • Arrows are orthogonal, solid, with one solid-triangle head at the destination, all the same mid-grey and about 2 px thick. They cross account and Region borders and never run through a caption: they use the gutters between boxes.
  • Seven coloured discs with a white digit sit on the arrows; the legend explains each number. The legend is a separate bordered table (arrow and disc on the left, text on the right), not part of the drawing.
  • White background, no shadows, no gradient on groups, no rounded corners on groups, a plain sans-serif face.

1.4 Palette measured on the PNG [PNG]

Element Value Note
Public subnet fill #E9F3E6 64,632 flat pixels
Private subnet fill #E6F2F8 99,438 flat pixels
Public subnet corner square #3F8624 flat
Private subnet corner square #127EBA (nominal #147EBA) flat
Region corner square #127EBA (nominal #147EBA) the Region and AZ outlines are dashed blue (seen; their pixels are anti-aliased tints, so the nominal value is the library one, #147EBA)
VPC corner square #4D27AA the thin outline has tints consistent with the same purple (inferred)
Account corner tab #242F3E (nominal #232F3E) white "aws" mark
Account outline neutral grey (R=G=B in every sampled pixel): two adjacent pixels #AFAFAF and #8E8E8E, a line of roughly 1.3 px at the PNG scale; nominal about #6A6A6A
On-premises box corner square #596B85 (nominal #5A6C86), outline blue-grey nominal #7D8998
Networking service icon square (TGW, Direct Connect, ELB) vertical gradient, top #7B49D7, bottom #4E26AC, white glyph
Networking glyph (IGW, NAT, ENI) purple, nominal #4D27AA [INFER] from anti-aliased pixels
Compute glyph (EC2 chip) a darker orange than today's #ED7100; the era value was #D05C17 [INFER]
Users and client glyphs #263140 (nominal #232F3E)
Internet cloud glyph #000000
Arrow #6A6A6A, about 2 px centre pixel exact, neighbours at about 40 %
Caption dark grey or black, about 11 to 12 px, centred below the icon

Flow badges (disc about 18 px, white bold digit) and the legend rows, paraphrased:

# Disc Flow
1 #0073F3 Internet-bound egress of application and shared-services VPCs: TGW, egress VPC NAT, IGW
2 #03A811 Application VPC to shared-services VPC through the TGW
3 #7F6000 Internal traffic from shared services to application and networking VPCs through the TGW
4 #DA4DD5 Ingress from the Internet through the managed IGW to the DMZ bastions, then to application and shared-services VPCs through the TGW
5 #FF0000 Ingress over Direct Connect (customer administrators) and customer bastions to application instances through the TGW
6 #FFBE00 Ingress over Direct Connect (corporate users) to application instances through the TGW
7 #00D8C8 Ingress from the Internet (external users) through the IGW and public load balancers to application instances

1.5 The article look against the current official look

The article is drawn with the 2019 to 2021 icon release. The draw.io library shipped today (dev, pinned above) uses the newer palette. Sidebar-AWS4b.js also holds a 2018 grey set ("AWS18 / Groups (light)", #879196 and #AAB7B8 outlines, L171-203 of that file); it is not the article look and is ignored here.

Element Article [PNG] Current library [SRC]
Region outline blue #147EBA, dashed teal #00A4A6, dashed (label #147EBA)
AZ outline blue #147EBA, dashed the same
Private subnet fill #E6F2F8, square #147EBA fill #E6F6F7, square #00A4A6
Public subnet fill #E9F3E6, square #3F8624 fill #F2F6E8, square #7AA116, label #248814
VPC #4D27AA #8C4FFF (label #AAB7B8)
Service icons gradient squares flat squares in the category colour (Networking #8C4FFF)
Compute glyph darker orange #ED7100

[REC] Implement two style profiles. article is the default because the product owner asked for the look of the article; aws2024 is the library as shipped. Sections 2 and 3 give both.

2. draw.io (mxGraph) format

2.1 File skeleton [KNOWN]

A .drawio file is XML: mxfile > one diagram per page > mxGraphModel > root > cells. The two root cells (id="0" and id="1" parent="0") are mandatory and every top-level cell has parent="1". Uncompressed XML opens in draw.io desktop and in app.diagrams.net, so v1 never compresses. Use page="0" (infinite canvas, no page boundaries) because network diagrams are wider than any paper size.

Complete minimal example, profile article, using the canonical styles of 2.3 and 2.4 without their points=[...] hint list (that list only declares connection points in the editor and does not change rendering [KNOWN]):

<mxfile host="vpcatlas" version="0.1.0" type="device">
  <diagram id="overview" name="Overview">
    <mxGraphModel dx="1200" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" math="0" shadow="0" background="#FFFFFF">
      <root>
        <mxCell id="0" />
        <mxCell id="1" parent="0" />
        <mxCell id="inet-1" value="Internet" style="sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#232F3D;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.internet;" vertex="1" parent="1">
          <mxGeometry x="60" y="190" width="64" height="64" as="geometry" />
        </mxCell>
        <mxCell id="acct-1" value="Networking &amp; Egress (111111111111)" style="outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_aws_cloud_alt;strokeColor=#232F3E;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#232F3E;dashed=0;" vertex="1" parent="1">
          <mxGeometry x="200" y="40" width="700" height="460" as="geometry" />
        </mxCell>
        <mxCell id="reg-1" value="eu-west-1" style="outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_region;strokeColor=#147EBA;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#147EBA;dashed=1;" vertex="1" parent="acct-1">
          <mxGeometry x="20" y="40" width="660" height="400" as="geometry" />
        </mxCell>
        <mxCell id="vpc-1" value="vpc-0a1b2c (10.0.0.0/16)" style="outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_vpc2;strokeColor=#4D27AA;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#4D27AA;dashed=0;" vertex="1" parent="reg-1">
          <mxGeometry x="60" y="40" width="380" height="330" as="geometry" />
        </mxCell>
        <mxCell id="az-1" value="Availability Zone euw1-az1" style="fillColor=none;strokeColor=#147EBA;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#147EBA;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;pointerEvents=0;" vertex="1" parent="vpc-1">
          <mxGeometry x="20" y="40" width="340" height="150" as="geometry" />
        </mxCell>
        <mxCell id="sn-pub-1" value="Public subnet 1" style="outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.group;grIcon=mxgraph.aws4.group_security_group;grStroke=0;strokeColor=#3F8624;fillColor=#E9F3E6;verticalAlign=top;align=left;spacingLeft=30;fontColor=#3F8624;dashed=0;" vertex="1" parent="az-1">
          <mxGeometry x="10" y="30" width="150" height="110" as="geometry" />
        </mxCell>
        <object label="nat-0a1b2c" id="nat-1" account="111111111111" region="eu-west-1">
          <mxCell style="sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#4D27AA;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.nat_gateway;" vertex="1" parent="sn-pub-1">
            <mxGeometry x="51" y="34" width="48" height="48" as="geometry" />
          </mxCell>
        </object>
        <mxCell id="igw-1" value="igw-0a1b2c" style="sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#4D27AA;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.internet_gateway;" vertex="1" parent="reg-1">
          <mxGeometry x="36" y="150" width="48" height="48" as="geometry" />
        </mxCell>
        <mxCell id="tgw-1" value="tgw-0d4e5f" style="sketch=0;outlineConnect=0;fontColor=#232F3E;fillColor=#4E26AC;gradientColor=#7B49D7;gradientDirection=north;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.transit_gateway;" vertex="1" parent="reg-1">
          <mxGeometry x="520" y="140" width="64" height="64" as="geometry" />
        </mxCell>
        <mxCell id="e1" value="" style="edgeStyle=orthogonalEdgeStyle;html=1;rounded=0;elbow=vertical;endArrow=none;startArrow=none;strokeColor=#6A6A6A;strokeWidth=2;" edge="1" parent="1" source="inet-1" target="igw-1">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
        <mxCell id="e2" value="attachment" style="edgeStyle=orthogonalEdgeStyle;html=1;rounded=0;elbow=vertical;endArrow=none;startArrow=none;strokeColor=#6A6A6A;strokeWidth=2;labelBackgroundColor=#FFFFFF;fontSize=11;exitX=1;exitY=0.5;entryX=0;entryY=0.5;" edge="1" parent="1" source="vpc-1" target="tgw-1">
          <mxGeometry relative="1" as="geometry" />
        </mxCell>
      </root>
    </mxGraphModel>
  </diagram>
</mxfile>

2.2 Cells [KNOWN] (container flags [SRC])

  • Vertex: vertex="1", a style, an optional value (the label) and an mxGeometry x y width height as="geometry". Edge: edge="1", source and target ids, and <mxGeometry relative="1" as="geometry"/>; waypoints go in <Array as="points"><mxPoint x="" y=""/></Array> inside that geometry.
  • Nesting: a child names its container in parent, and its x, y are relative to the container's top-left corner, never absolute. Writing absolute coordinates for children is the commonest bug.
  • Container flags copied from the library group templates (L259): container=1;pointerEvents=0;collapsible=0; recursiveResize=0. container=1 makes the editor treat the shape as a drop target, collapsible=0 removes the fold icon, recursiveResize=0 keeps children untouched when the group is resized, and pointerEvents=0 lets a click on the empty interior reach what is underneath.
  • Draw order is document order inside one parent (later is on top). Emit a container before its children and emit all edges last, with parent="1", so lines are painted over every group fill. [REC] Give every edge parent="1" and absolute waypoints: the layout engine already knows absolute positions, and an edge whose endpoints live in different containers is drawn correctly this way.
  • Attach edges to sides with exitX, exitY, entryX, entryY (each 0 to 1; exitX=1;exitY=0.5 is the middle of the right side). Without them draw.io picks the nearest perimeter point.
  • Icons on a group border (IGW): [REC] make them a child of the group that contains both halves (the Region in the example) instead of giving a VPC child a negative offset, so the icon is not tied to the VPC's bounds.
  • Escaping: attribute values need &amp; &lt; &gt; &quot;. With html=1 a line break in value is the escaped markup &lt;br&gt;; with html=0 it is &#xa;.
  • Metadata: wrap a cell in <object label="..." id="..." any_key="value"> (as the example does for the NAT gateway) to keep resource id, account, region and ARN visible under "Edit Data". [KNOWN] Older files use UserObject; do not emit it.
  • Ids: unique within the file, no spaces. [REC] Use the AWS id prefixed by account and region when the same id can appear twice (a shared TGW seen from two accounts).
  • Pages: one diagram per page (id unique, name shown on the tab).

2.3 Style strings: grammar and canonical bases

A style is a list of key=value; pairs; order does not matter and a later duplicate wins. Colours are #RRGGBB or none; flags are 0 or 1. All AWS shapes are shape=mxgraph.aws4.<name>. Four bases are used by the library; the exact strings follow.

G_BASE (group base, L259). Append group;grIcon=mxgraph.aws4.<grIcon>;<colours>:

points=[[0,0],[0.25,0],[0.5,0],[0.75,0],[1,0],[1,0.25],[1,0.5],[1,0.75],[1,1],[0.75,1],[0.5,1],[0.25,1],[0,1],[0,0.75],[0,0.5],[0,0.25]];outlineConnect=0;gradientColor=none;html=1;whiteSpace=wrap;fontSize=12;fontStyle=0;container=1;pointerEvents=0;collapsible=0;recursiveResize=0;shape=mxgraph.aws4.

S_BASE (service icon, a coloured square with a white glyph; Networking, L1828). Append resourceIcon;resIcon=mxgraph.aws4.<name>;. strokeColor=#ffffff is the glyph colour and fillColor the square:

sketch=0;points=[[0,0,0],[0.25,0,0],[0.5,0,0],[0.75,0,0],[1,0,0],[0,1,0],[0.25,1,0],[0.5,1,0],[0.75,1,0],[1,1,0],[0,0.25,0],[0,0.5,0],[0,0.75,0],[1,0.25,0],[1,0.5,0],[1,0.75,0]];outlineConnect=0;fontColor=#232F3E;fillColor=#8C4FFF;strokeColor=#ffffff;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;shape=mxgraph.aws4.

R_BASE (resource glyph, a bare coloured glyph; Networking, L1827). Append <name>;:

sketch=0;outlineConnect=0;fontColor=#232F3E;gradientColor=none;fillColor=#8C4FFF;strokeColor=none;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;fontSize=12;fontStyle=0;aspect=fixed;pointerEvents=1;shape=mxgraph.aws4.

X_BASE (general glyph, L117): R_BASE with fillColor=#232F3D. Used for Internet, users, clients.

Category fill colours [SRC], the only thing that changes between palettes: Networking #8C4FFF (L1827-1828), Compute and Containers #ED7100 (L587, L873), Security #DD344C (L2032-2033), Storage and Cloud Financial Management #7AA116 (L2182, L497), Database #C925D1 (L971), Management and Governance #E7157B (L1517), general #232F3D / #5A6C86 (L117-118). The label colour is always fontColor=#232F3E.

article profile: in S_BASE replace fillColor=#8C4FFF; by fillColor=#4E26AC;gradientColor=#7B49D7; gradientDirection=north; (dark at the bottom, light at the top; values from 1.4) and in R_BASE use fillColor=#4D27AA. Service icons outside Networking (Network Firewall, RAM, EC2) keep the library colour: the era gradients of those categories were not measured. [INFER] that gradientDirection=north puts fillColor at the bottom as measured.

Sizes [SRC]: the library draws service icons and glyphs at 78 x 78 (a few glyphs are 70 to 77 wide or 74 to 77 high) and groups at 130 x 130 as a placeholder. aspect=fixed is set, so shapes scale; see 4.2 for the sizes the diagrams use.

2.4 Groups

Profile aws2024: G_BASE + tail.

Kind Tail after G_BASE L
AWS Cloud (logo variant, first in the palette) group;grIcon=mxgraph.aws4.group_aws_cloud_alt;strokeColor=#232F3E;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#232F3E;dashed=0; 265
AWS Cloud (second variant) the same with grIcon=mxgraph.aws4.group_aws_cloud 267
Region group;grIcon=mxgraph.aws4.group_region;strokeColor=#00A4A6;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#147EBA;dashed=1; 269
VPC group;grIcon=mxgraph.aws4.group_vpc2;strokeColor=#8C4FFF;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#AAB7B8;dashed=0; 277
Private subnet group;grIcon=mxgraph.aws4.group_security_group;grStroke=0;strokeColor=#00A4A6;fillColor=#E6F6F7;verticalAlign=top;align=left;spacingLeft=30;fontColor=#147EBA;dashed=0; 279
Public subnet group;grIcon=mxgraph.aws4.group_security_group;grStroke=0;strokeColor=#7AA116;fillColor=#F2F6E8;verticalAlign=top;align=left;spacingLeft=30;fontColor=#248814;dashed=0; 281
Corporate data center group;grIcon=mxgraph.aws4.group_corporate_data_center;strokeColor=#7D8998;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#5A6C86;dashed=0; 285
Server contents the same with grIcon=mxgraph.aws4.group_on_premise 283
AWS Account (pink) group;grIcon=mxgraph.aws4.group_account;strokeColor=#CD2264;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#CD2264;dashed=0; 295
EC2 instance contents group;grIcon=mxgraph.aws4.group_ec2_instance_contents;strokeColor=#D86613;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#D86613;dashed=0; 289
Auto Scaling group groupCenter;grIcon=mxgraph.aws4.group_auto_scaling_group;grStroke=1;strokeColor=#D86613;fillColor=none;verticalAlign=top;align=center;fontColor=#D86613;dashed=1;spacingTop=25; 275

Plain rectangles (full style, no base):

Kind Style L
Availability Zone fillColor=none;strokeColor=#147EBA;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#147EBA;whiteSpace=wrap;html=1; 271
Security group fillColor=none;strokeColor=#DD3522;verticalAlign=top;fontStyle=0;fontColor=#DD3522;whiteSpace=wrap;html=1; 273
Generic group, dashed fillColor=none;strokeColor=#5A6C86;dashed=1;verticalAlign=top;fontStyle=0;fontColor=#5A6C86;whiteSpace=wrap;html=1; 301
Generic group, filled fillColor=#EFF0F3;strokeColor=none;dashed=0;verticalAlign=top;fontStyle=0;fontColor=#232F3D;whiteSpace=wrap;html=1; 303

The four plain templates lack container=1. [REC] Append container=1;collapsible=0;recursiveResize=0; pointerEvents=0; to them, as the example does for the AZ.

Profile article: same shapes and icons, colours replaced (tails, after G_BASE):

Kind Tail
Region group;grIcon=mxgraph.aws4.group_region;strokeColor=#147EBA;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#147EBA;dashed=1;
VPC group;grIcon=mxgraph.aws4.group_vpc2;strokeColor=#4D27AA;fillColor=none;verticalAlign=top;align=left;spacingLeft=30;fontColor=#4D27AA;dashed=0;
Private subnet group;grIcon=mxgraph.aws4.group_security_group;grStroke=0;strokeColor=#147EBA;fillColor=#E6F2F8;verticalAlign=top;align=left;spacingLeft=30;fontColor=#147EBA;dashed=0;
Public subnet group;grIcon=mxgraph.aws4.group_security_group;grStroke=0;strokeColor=#3F8624;fillColor=#E9F3E6;verticalAlign=top;align=left;spacingLeft=30;fontColor=#3F8624;dashed=0;
AWS Cloud, AZ, corporate data center unchanged

Notes. In a group shape strokeColor paints the outline and the corner square, and grStroke=0 hides the outline (the subnets of the article have none). The article's account box has a navy tab and a thin grey outline; one style cannot give both, so keep #232F3E [REC]. Which of the two AWS Cloud grIcon values draws the dark tab with the "aws" mark was not rendered: the logo variant is group_aws_cloud_alt [INFER] (first entry of the palette, and the one named in the project brief). A subnet whose route table has no default route is still drawn as a private subnet; say "isolated" in its label instead of inventing a style [REC].

2.5 Icons

Service icons (S_BASE + resourceIcon;resIcon=mxgraph.aws4.<name>;, 78 x 78 in the library):

Kind <name> L
Transit Gateway transit_gateway 1869
Site-to-Site VPN site_to_site_vpn 1855
Direct Connect direct_connect 1863
Elastic Load Balancing (generic) elastic_load_balancing 1857
PrivateLink vpc_privatelink 1845
Route 53 route_53 1843
Amazon VPC (service icon) vpc 1847
Client VPN client_vpn 1853
Cloud WAN cloud_wan 1861
VPC Lattice vpc_lattice 1849
CloudFront cloudfront 1841
Global Accelerator global_accelerator 1865
Verified Access verified_access 1871
Network Firewall (Security palette, fillColor=#DD344C) network_firewall 2072
Resource Access Manager (#DD344C) resource_access_manager 2078
Directory Service (Security palette, #DD344C) directory_service none, see below
EC2 (Compute palette, #ED7100) ec2 595

directory_service has no line in the pinned library file. It was found in the installed draw.io desktop app, where the Directory Service entry of the AWS 19 library is shape=mxgraph.aws4.resourceIcon;resIcon=mxgraph.aws4.directory_service;; a made-up name searched the same way was not found. [INFER] for other builds of the app.

Resource glyphs (R_BASE + <name>;, 78 x 78 unless noted):

Kind <name> L
Internet gateway internet_gateway 1916
NAT gateway nat_gateway 1920
VPC peering connection peering 1928
VPN gateway vpn_gateway 1962
VPN connection (70 x 78) vpn_connection 1960
Customer gateway customer_gateway 1902
Transit gateway attachment transit_gateway_attachment 1914
VPC endpoints (interface and gateway) endpoints 1908
Endpoint (singular; meaning in the AWS set not verified) endpoint 1876
Elastic network interface elastic_network_interface 1906
Network ACL network_access_control_list 1926
Route table (78 x 76) route_table 1898
Shield (the square of a security group on the VPC level pages) shield not checked
Router router 1950
Flow logs flow_logs 1910
Traffic mirroring vpc_traffic_mirroring 1964
Application Load Balancer application_load_balancer 1944
Network Load Balancer network_load_balancer 1968
Gateway Load Balancer gateway_load_balancer 1948
Classic Load Balancer classic_load_balancer 1946
Route 53 Resolver route_53_resolver 1892
Route 53 Resolver DNS Firewall route_53_resolver_dns_firewall 1894
Route 53 hosted zone (78 x 77) hosted_zone 1888
VPC carrier gateway vpc_carrier_gateway 1890
Cloud WAN core network edge cloud_wan_core_network_edge 1936
Cloud WAN segment cloud_wan_segment_network 1934
EC2 instance chip (Compute palette, #ED7100) instance2 740
EC2 instances (same base) instances 742

General glyphs (X_BASE + <name>;): internet (L185; variants internet_alt1 L187, internet_alt2 L189), users (L223), user (L221), client (L143), mobile_client (L201), corporate_data_center (L149), traditional_server (L219), generic_firewall (L177). For an on-premises box use the Corporate data center group of 2.4, not the glyph.

Not in the library: egress-only Internet gateway (reuse internet_gateway, label "egress-only"), prefix list, Resolver rule, RAM share (use the resource_access_manager service icon as an annotation), Direct Connect gateway (reuse direct_connect). Checks run on these tables: every cited line contains its name, and a made-up name (zz_not_a_shape) matched zero lines in the same lookup.

Service layer icons (registry.SERVICE_KINDS, same S_BASE style, service_rows and the VPC pages draw them; the names follow the library naming and are [KNOWN] only after a render of one cell per kind):

Kind <name>
WAF web ACL waf
ACM certificate certificate_manager
API Gateway api_gateway
ECS ecs
Fargate fargate
EKS eks
Auto Scaling auto_scaling2
RDS rds
Aurora aurora
ElastiCache elasticache
EFS elastic_file_system
Lambda lambda
S3 s3
DynamoDB dynamodb
CloudTrail cloudtrail
GuardDuty guardduty
AWS Config config
CloudWatch cloudwatch_2
KMS key_management_service
ECR ecr

2.6 Edges, badges, legend

Library arrows [SRC] (palette "AWS / Arrows", L87-113), for example "Default (right)": edgeStyle=orthogonalEdgeStyle;html=1;endArrow=block;elbow=vertical;startArrow=none;endFill=1;strokeColor=#545B64;rounded=0;. Variants only change startArrow / endArrow (block, open, openThin) and startFill / endFill.

[REC] The article draws every arrow in one grey and tells flows apart with numbered discs. Keep that: kinds differ by pattern, width, heads and label, not by colour. The reference draws flows, so every edge but the association ends in a filled block head at its target, and a kind that runs both ways (peering, VPN, Direct Connect) has one at each end. The corner is thin and rounded. Common prefix for all kinds: edgeStyle=orthogonalEdgeStyle;rounded=1;arcSize=8;orthogonalLoop=1;jettySize=auto;html=1;elbow=vertical;labelBackgroundColor=#FFFFFF;fontSize=11;fontColor=#232F3E;fontFamily=Helvetica; plus the colour strokeColor=#6A6A6A (profile article) or #545B64 (profile aws2024).

Edge kind Append Meaning
link strokeWidth=2;startArrow=none;endArrow=block;endFill=1; attachment or connection (TGW to VPC, IGW to Internet, DX gateway to TGW); the head is at the target
flow strokeWidth=2;startArrow=none;endArrow=block;endFill=1; directed traffic, only when flows are drawn (as in the article)
peering strokeWidth=2;dashed=1;dashPattern=8 4;startArrow=block;startFill=1;endArrow=block;endFill=1; VPC peering, label with the pcx- id and the state when it is not active
vpn strokeWidth=2;dashed=1;dashPattern=2 3;startArrow=block;startFill=1;endArrow=block;endFill=1; Site-to-Site VPN tunnel pair
dx strokeWidth=2;startArrow=block;startFill=1;endArrow=block;endFill=1; Direct Connect: on-premises to the DX gateway, DX gateway to the TGW
xaccount strokeWidth=2;dashed=1;dashPattern=12 3 2 3;startArrow=none;endArrow=block;endFill=1; link between two different accounts (dash-dot; label with the last 4 digits of the other account)
association strokeWidth=1;dashed=1;dashPattern=4 4;startArrow=none;endArrow=none; route-table entry, subnet to route-table or NACL association; thin and optional

An edge is exported with its kind as type and, when the layout keeps the full text of a label it had to cut, that text as detail (a cell does the same with detail and name).

Flow disc [REC] (the disc of the reference measures about 18 px and wears one of seven colours; the exporters draw 24 px, registry.FLOW_MARKER_SIZE, and the colour of their flow, see 2.7): a separate vertex, not an edge label, with no connector, centred on the longest segment of its edge (at the middle, or a quarter along it when the edge has a label), size 24 x 24, 28 px (FLOW_MARKER_STEP) between the centres of two discs on one edge and 12 px (FLOW_MARKER_MARGIN) between a disc and a bend or an end, style (registry.flow_marker(n): the fill is registry.badge_color(n); the example has the fallback fill) ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#232F3E;strokeColor=none;fontColor=#FFFFFF;fontStyle=1;fontSize=12;align=center;verticalAlign=middle;.

Legend [REC]: a "Generic group, filled" rectangle (white fill, outline #7D8998), one row per edge kind in use (a 60 px sample edge and its name), one row per subnet colour and, when the page numbers flows, a "Traffic flows" block (2.7). See 4.6 for its position and content.

2.7 Flow numbers and edge labels

Flow numbers [REC] are derived, not supplied. The reference numbers seven scenarios by hand; the atlas has no route analysis, so it numbers what an edge is: the layout gives each kind of traffic a number in a fixed order, only the kinds a page draws are numbered, and a kind keeps its number on every page (a page may skip numbers).

# Traffic Edges that carry it
1 Internet ingress Internet to IGW
2 NAT egress private subnet to NAT gateway to IGW; with no explicit edge for the NAT path, the disc sits on the Internet-to-IGW edge of the VPC that has a NAT gateway
3 Transit Gateway attachment attachment to hub, cross-account attachments included
4 Direct Connect / VPN on-premises to DX gateway or VGW to hub
5 VPC peering the peering edges
6 Shared prefix list / RAM the stubs of external accounts
  • Every edge of a kind carries Edge.flow = [number]; an edge that serves several kinds lists them all and gets one disc per number. Both formats draw the same discs: same id (<edge id>~b<number>), centre and size.
  • One colour per flow, as in the reference (registry.FLOW_COLORS, read through registry.badge_color(n)), with a white bold 12 px digit and no outline. Above 7 the seven colours come round again; a number below 1 keeps the dark #232F3E (registry.FLOW_MARKER_FILL). The swatch of a flow in the legend has the colour of its disc, and Lucid fills the disc with the same colour.
# Colour Fill
1 blue #1E73E8
2 green #2E8B57
3 ochre #8B6914
4 pink #D946EF
5 red #D7263D
6 orange #F59E0B
7 turquoise #0FB5AE
  • Several discs per edge [REC]: a disc of each flow of the edge sits at the middle of every segment of at least 160 px (registry.FLOW_SEGMENT_MIN), and at least once, on the longest segment, whatever its length (a quarter along it when the edge has a label). registry.flow_marker_sets gives the sets of centres, the first on the longest segment; registry.flow_marker_centers is the same list flattened (the first count centres are the first set), registry.flow_discs adds the ids (<edge id>~b<number> for the first disc of a flow, <edge id>~b<number>.<order> for the later ones, as drawio.marker_discs writes them). Given rectangles to avoid (icons with their captions, labels, other discs), a set slides along its segment to the nearest free place.
  • Legend [REC]: when a page has numbered edges, the legend gets a "Traffic flows" heading and one row per number in use, in number order, each a 24 px disc plus a title (Internet ingress, NAT egress, Transit Gateway attachment, Direct Connect / VPN, VPC peering, Shared prefix list / RAM). The disc sits in the column of the swatches (registry.LEGEND_DISC_X, 42 px from the left edge of the legend). The layout writes a row as a swatch and a text row that both carry meta["flow"] set to the number (the text starts with a circled digit, as layout._add_legend does), as one text box inside the legend whose label is "<number> <title>" (meta["marker"] is a synonym of flow), or as a swatch whose label is only the number. registry.legend_discs settles the rows for both exporters: the swatch is the disc when there is one, otherwise the text row gets a disc of its own, and the text row keeps its title without the number. The disc has id <row id>~b<number> (the swatch keeps its own id); in draw.io it is a child of the legend, in Lucid nesting is geometric, so it simply lies inside it. A text row that begins with a digit but is not inside a legend stays text.
  • Edge labels [REC]: the layout sets Edge.label_t (0 at the source, 1 at the target) and both exporters put the label there: draw.io with <mxGeometry x="2 * t - 1" relative="1">, Lucid with the position of the line text (t). Lucid supports the position, so nothing is lost. A label_t outside 0 to 1 is clamped, an invalid one counts as 0.5 (no x is written), and an edge without a label gets neither. The disc of a labelled edge sits a quarter along its longest segment so that the middle stays free, but label_t may point elsewhere: the layout has to keep a label clear of the disc positions that registry.flow_marker_centers gives.

3. Lucid (Standard Import)

3.1 Package and import path [DOC]

  • A .lucid file is a ZIP whose root holds document.json. Optional folders: images/ (referenced by file name only, never with a directory) and data/ (CSV collections, not used here).
  • Limits: whole ZIP contents 50 MB, images/ 50 MB, data/ 1 MB, document.json 2 MB (a search-engine summary of the docs said 1 MB; the raw overview page says 2 MB). [REC] Stay under 1 MB per page file by splitting large networks into several pages.
  • Import goes through the REST API only; the documentation describes no UI import for this format: POST https://api.lucid.co/v1/documents with Authorization: Bearer <OAuth 2.0 access token> and a multipart body file=@import.lucid;type=x-application/vnd.lucid.standardImport, title=..., product=lucidchart (required; the other value is lucidspark) and an optional parent folder id. [REC] v1 only writes the file; a push command would need the user's own token and is out of scope.
  • Lucid's sample repository has a "Network Diagram Example" under lucidsoftware/sample-lucid-rest-applications, path standard-import/demo-files/network (not read).
  • The docs warn that an unchanged import file "may produce varying results over time". Tests must assert the JSON, never the rendering.

3.2 document.json schema [DOC]

  • Top level: version (Number, required; the value 1 is [INFER], check it in the sample above), pages (required, at least one) and collections (optional).
  • Ids: 1 to 36 characters from A-Z a-z 0-9 - _ . ~, unique across every object of the file (pages, shapes, lines, layers). AWS ids such as subnet-0123456789abcdef0 fit; ARNs do not, so hash long keys.
  • Page: id and title required. Optional settings (size as {"type":"custom","w":N,"h":N} with N from 1 to 20,000 px, infiniteCanvas, autoTiling (default true, ignored when infiniteCanvas is true), fillColor) and the arrays shapes, lines, groups, layers, dataBackedShapes, customData.
  • Coordinates are absolute page coordinates, x to the right and y downwards. Lucid has no parent-relative coordinates: convert every draw.io child position to absolute before writing. boundingBox is {x, y, w, h} plus an optional rotation (degrees, clockwise).
  • Shape common properties: id, type, boundingBox (required); style, text, actions, customData ([{"key","value"}]), linkedData, opacity (integer 0 to 100), note, zIndex (integer, default 0).
  • style: fill ({"type":"color","color":"#RRGGBB"} or {"type":"image","ref":"file.png","imageScale":"fit"}; scales are fit, fill, stretch, original, tile; gradients are not documented), stroke ({"color","width","style"}, style being solid, dashed or dotted; defaults 1 px solid black), rounding (an integer equal to twice the corner radius in px) and textColor. Colours are hex RGB or RGBA.
  • text is a string that may contain HTML: <br> <b> <i> <s> <u> <a> <ol> <ul> <li> and <p style="font-size:9pt;text-align:left;color:#232F3E">. Defaults: Liberation Sans 10 pt, centred both ways. Not documented: text padding and any "label below the shape" option.
  • Standard-library shape types: rectangle (takes style), text (no style), hotspot (no text), image (requires stroke and image), stickyNote.

3.3 Lines [DOC]

Property Notes
id, lineType, endpoint1, endpoint2 required; lineType is straight, elbow or curved
stroke {"color":"#6A6A6A","width":2,"style":"solid"}
text array of {"text":"1","position":0.5,"side":"middle"}; side is top, middle or bottom, and middle puts the line behind the text
joints / elbowControlPoints absolute {x,y} control points for straight / elbow lines (elbow points must form right angles)
customData, linkedData, zIndex as for shapes

Endpoints always carry type and style. shapeEndpoint: shapeId plus an optional position {x,y} with x and y from 0 to 1 over the shape (0,0 is top-left, 1,0.5 the middle of the right side); with no position on either end the line is a "smart line" that picks its own attachment points. lineEndpoint: lineId and a position number from 0 to 1. positionEndpoint: an absolute position {x,y}. The 22 endpoint styles are none, aggregation, arrow, hollowArrow, openArrow, async1, async2, closedSquare, openSquare, bpmnConditional, bpmnDefault, closedCircle, openCircle, composition, exactlyOne, generalization, many, nesting, one, oneOrMore, zeroOrMore, zeroOrOne. The docs warn that a shape endpoint takes a position object while a line endpoint takes a plain number; swapping them is a JSON parse error.

3.4 The AWS 2024 library [DOC]

type is namedShape (icons) or namedContainer (groups), plus a required className that always ends with AWS2024. A container owns the shapes whose bounding boxes lie inside its own ("place other shapes within the container's bounding box to nest them"); there is no parent field.

Verified class names, copied from the library page:

Kind type className
AWS Cloud, logo variant (see note) namedContainer AWSCloudAltAWS2024 (also AWSCloudAWS2024, AWSCloudAltDarkAWS2024, AWSCloudDarkAWS2024)
Region namedContainer RegionAWS2024
VPC namedContainer VirtualPrivateCloudVPCAWS2024
Availability Zone namedContainer AvailabilityZoneAWS2024
Public subnet namedContainer PublicSubnetAWS2024
Private subnet namedContainer PrivateSubnetAWS2024
Security group namedContainer SecurityGroupAWS2024
AWS account namedContainer AWSAccountAWS2024
Corporate data center namedContainer CorporateDataCenterAWS2024
Generic group namedContainer GenericGroupAWS2024
Auto Scaling group, EC2 instance contents, server contents namedContainer AutoScalingGroupAWS2024, EC2InstanceContentsAWS2024, ServerContentsAWS2024
Internet gateway namedShape ResAmazonVPCInternetGatewayAWS2024
NAT gateway namedShape ResAmazonVPCNATGatewayAWS2024
Application Load Balancer namedShape ResElasticLoadBalancingApplicationLoadBalancerAWS2024
Network Load Balancer namedShape ResElasticLoadBalancingNetworkLoadBalancerAWS2024
Amazon VPC service icon namedShape ArchAmazonVirtualPrivateCloudAWS2024
Route 53, CloudFront, API Gateway, EC2, WAF namedShape ArchAmazonRoute53AWS2024, ArchAmazonCloudFrontAWS2024, ArchAmazonAPIGatewayAWS2024, ArchAmazonEC2AWS2024, ArchAWSWAFAWS2024
Client VPN, App Mesh (category examples) namedShape ArchAWSClientVPNAWS2024, ArchAWSAppMeshAWS2024

Which of the Cloud variants draws the logo tab was not rendered ([INFER] that it matches draw.io: the Alt one). Whether text on a namedContainer becomes its title is also undocumented ([INFER] yes).

Naming rule [INFER]: the class is the official AWS asset file name without separators or size suffix, plus AWS2024; Arch is a 64 px service icon and Res a 48 px resource icon. It reproduces every verified pair: Res_Amazon-VPC_NAT-Gateway gives ResAmazonVPCNATGatewayAWS2024; Res_Elastic-Load-Balancing_Application-Load-Balancer gives ResElasticLoadBalancingApplicationLoadBalancerAWS2024; Arch_Amazon-Simple-Storage-Service gives ArchAmazonSimpleStorageServiceAWS2024; Arch_AWS-Identity-and-Access-Management gives ArchAWSIdentityandAccessManagementAWS2024 (note the lower-case "and"); Arch_Amazon-Route-53 gives ArchAmazonRoute53AWS2024. The asset file names come from memory, because the AWS package was not opened.

Candidate names derived with that rule, not confirmed by any page ([INFER], keep them in a data file, not in code):

Kind Candidate className
Transit Gateway ArchAWSTransitGatewayAWS2024
Transit gateway attachment ResAWSTransitGatewayAttachmentAWS2024
Site-to-Site VPN ArchAWSSiteToSiteVPNAWS2024
VPN connection, VPN gateway, customer gateway ResAmazonVPCVPNConnectionAWS2024, ResAmazonVPCVPNGatewayAWS2024, ResAmazonVPCCustomerGatewayAWS2024
Direct Connect ArchAWSDirectConnectAWS2024
VPC peering connection ResAmazonVPCPeeringConnectionAWS2024
VPC endpoints ResAmazonVPCEndpointsAWS2024
PrivateLink ArchAWSPrivateLinkAWS2024
Network interface, network ACL, router ResAmazonVPCElasticNetworkInterfaceAWS2024, ResAmazonVPCNetworkAccessControlListAWS2024, ResAmazonVPCRouterAWS2024
Flow logs, traffic mirroring ResAmazonVPCFlowLogsAWS2024, ResAmazonVPCTrafficMirroringAWS2024
Gateway and Classic Load Balancer ResElasticLoadBalancingGatewayLoadBalancerAWS2024, ResElasticLoadBalancingClassicLoadBalancerAWS2024
Elastic Load Balancing service icon ArchElasticLoadBalancingAWS2024
Network Firewall ArchAWSNetworkFirewallAWS2024
Route 53 Resolver, hosted zone, route table ResAmazonRoute53ResolverAWS2024, ResAmazonRoute53HostedZoneAWS2024, ResAmazonRoute53RouteTableAWS2024
Resource Access Manager ArchAWSResourceAccessManagerAWS2024
Internet, users, client (general icons) unknown; use the image fallback of 3.6

Test plan for the data file [REC]: generate a probe.lucid with one shape per candidate on a grid, the class name as a separate caption, import it with the call of 3.1 and mark each class ok or blank in the data file. Behaviour for an unknown className (import error, silent drop or blank box) is not documented, so the exporter must treat an unverified class as "use fallback".

3.5 Nesting, order and captions

  • Parents must be listed with a lower zIndex than their children [REC]: cloud 0, region 1, VPC 2, AZ 3, subnet 4, icons 10, captions 11, lines 20, badges 30. Order inside the arrays is not relied on.
  • The container library (rectangleContainer, roundedRectangleContainer, pillContainer, circleContainer, diamondContainer, braceContainer, bracketContainer, swimLanes) has containerTitle, magnetize (default true: children move with the container) and assistedLayout. Those properties are documented for that library only; do not assume namedContainer shares them. Do not set assistedLayout, which would re-grid the children on first open.
  • Captions [REC]: write icon captions as separate text shapes (about 64 px wide, 20 px high, centred, just below the icon). The placement of a namedShape's own text is not documented, so it is not relied on.
  • A circular badge is a rectangle of 24 x 24 with rounding 24 (twice the 12 px radius), fill and stroke the colour of the flow (registry.badge_color), textColor #FFFFFF and the digit in a bold white 9 pt paragraph (the 12 px of draw.io). The discs of the legend rows are the same shape. [INFER] that this renders as a disc.

3.6 Fallback: icon as an image, and icon licensing

Two documented ways to show a picture: a rectangle whose style.fill is {"type":"image","ref":"nat.png", "imageScale":"fit"}, or an image block (its stroke and image properties are required; [INFER] that image takes the same object as the fill, and that stroke.width 0 is accepted). ref is the file name inside images/, no directory. Accepted media: jpeg/jpg, png, gif, bmp, tiff, svg (an SVG is converted to PNG on import). The caption rule of 3.5 applies unchanged.

Licensing [REC]: the terms of the AWS Architecture Icons (aws.amazon.com/architecture/icons) were not read. Until they are, do not commit AWS icon files to the repository or bake them into the container image. The draw.io output needs no image file (the shapes are stencils built into draw.io) and the library path of 3.4 needs none either; only this fallback does, so make it optional and pluggable (an --icons-dir option that points at a folder the user downloaded themselves).

3.7 Minimal complete example

All class names here are from the verified list. Coordinates are absolute: the five containers have the same boxes as the draw.io example of 2.1 (child offsets added up); the icons are placed differently and a load balancer is added. Captions are separate text shapes.

{
  "version": 1,
  "pages": [
    {
      "id": "page1",
      "title": "Overview",
      "settings": { "size": { "type": "custom", "w": 1200, "h": 800 } },
      "shapes": [
        { "id": "acct1", "type": "namedContainer", "className": "AWSCloudAltAWS2024", "zIndex": 0,
          "boundingBox": { "x": 200, "y": 40, "w": 700, "h": 460 }, "text": "Networking and Egress (111111111111)" },
        { "id": "reg1", "type": "namedContainer", "className": "RegionAWS2024", "zIndex": 1,
          "boundingBox": { "x": 220, "y": 80, "w": 660, "h": 400 }, "text": "eu-west-1" },
        { "id": "vpc1", "type": "namedContainer", "className": "VirtualPrivateCloudVPCAWS2024", "zIndex": 2,
          "boundingBox": { "x": 280, "y": 120, "w": 380, "h": 330 }, "text": "vpc-0a1b2c (10.0.0.0/16)" },
        { "id": "az1", "type": "namedContainer", "className": "AvailabilityZoneAWS2024", "zIndex": 3,
          "boundingBox": { "x": 300, "y": 160, "w": 340, "h": 150 }, "text": "Availability Zone euw1-az1" },
        { "id": "snpub1", "type": "namedContainer", "className": "PublicSubnetAWS2024", "zIndex": 4,
          "boundingBox": { "x": 310, "y": 190, "w": 150, "h": 110 }, "text": "Public subnet 1" },
        { "id": "igw1", "type": "namedShape", "className": "ResAmazonVPCInternetGatewayAWS2024", "zIndex": 10,
          "boundingBox": { "x": 256, "y": 224, "w": 48, "h": 48 },
          "customData": [ { "key": "resourceId", "value": "igw-0a1b2c" } ] },
        { "id": "nat1", "type": "namedShape", "className": "ResAmazonVPCNATGatewayAWS2024", "zIndex": 10,
          "boundingBox": { "x": 322, "y": 224, "w": 48, "h": 48 },
          "customData": [ { "key": "resourceId", "value": "nat-0a1b2c" } ] },
        { "id": "alb1", "type": "namedShape", "className": "ResElasticLoadBalancingApplicationLoadBalancerAWS2024", "zIndex": 10,
          "boundingBox": { "x": 392, "y": 224, "w": 48, "h": 48 } },
        { "id": "cap-igw1", "type": "text", "zIndex": 11,
          "boundingBox": { "x": 248, "y": 274, "w": 64, "h": 20 },
          "text": "<p style=\"font-size:9pt;color:#232F3E\">igw-0a1b2c</p>" },
        { "id": "cap-nat1", "type": "text", "zIndex": 11,
          "boundingBox": { "x": 314, "y": 274, "w": 64, "h": 20 },
          "text": "<p style=\"font-size:9pt;color:#232F3E\">nat-0a1b2c</p>" }
      ],
      "lines": [
        { "id": "ln1", "lineType": "elbow", "zIndex": 20,
          "endpoint1": { "type": "shapeEndpoint", "style": "none", "shapeId": "igw1", "position": { "x": 1, "y": 0.5 } },
          "endpoint2": { "type": "shapeEndpoint", "style": "none", "shapeId": "nat1", "position": { "x": 0, "y": 0.5 } },
          "stroke": { "color": "#6A6A6A", "width": 2, "style": "solid" } }
      ]
    }
  ]
}

3.8 draw.io to Lucid mapping

Concept draw.io Lucid
Group G_BASE + tail, or plain rectangle namedContainer + className
Icon S_BASE / R_BASE / X_BASE namedShape + className, else the image fallback
Icon caption label below (verticalLabelPosition=bottom) separate text shape
Position relative to the parent absolute on the page
Order document order explicit zIndex
link, flow edge endArrow=block;endFill=1;startArrow=none lineType elbow, endpoint1 style none, endpoint2 style arrow
peering, vpn, dx edge startArrow=block;startFill=1;endArrow=block;endFill=1 both endpoint styles arrow
open / openThin heads endArrow=open / openThin openArrow
Dash dashed=1;dashPattern=8 4 or 2 3 stroke.style dashed or dotted (the pattern length is not settable)
Width, colour strokeWidth=2;strokeColor=#6A6A6A stroke.width 2, stroke.color #6A6A6A
Edge label value with labelBackgroundColor text entry with side middle
Metadata <object ...> attributes customData [{key,value}]
Profile colours style strings of 2.3 and 2.4 fixed by the library; the article profile cannot recolour namedContainer shapes unless style overrides them, which is undocumented for named shapes ([INFER] Lucid draws its AWS 2024 colours)

4. Layout rules (AWS style)

Facts seen in the article are tagged [SEE]. Everything else here is a recommendation ([REC]): the article is a hand-drawn picture, the product lays out discovered networks automatically.

4.1 Hierarchy

Outermost first: page, then the external column (Internet, users, on-premises) and the account clouds, then account (AWS Cloud group), Region, VPC, Availability Zone band, subnet column, icons with captions [SEE]. Resources that belong to no subnet (gateways, endpoints of type gateway, Transit Gateway, Direct Connect, VPN, firewalls) attach at the level named in 4.3. A resource has exactly one parent.

4.2 Metrics

Item Value
Grid 10 px (gridSize="10"); group x, y, width, height are multiples of 10
Resource glyph 48 x 48 (AWS guideline, recalled from memory; the library default is 78)
Service icon 64 x 64 (same remark; library default 78)
Group corner icon drawn by the shape, about 30 px; the label is shifted with spacingLeft=30 [SRC]
Group label 12 px, top, left-aligned; the AZ label is centred [SEE]; VPC and subnet labels use two lines (name, then CIDR)
Group padding left, right, bottom 20; top 40, and 50 for VPC and subnet because of the two-line label
Gap between sibling groups 20 between AZ bands and between subnet columns, 40 between VPCs, 60 between accounts
Icon cell icon width plus 24 px of horizontal gap; 32 px under the icon for the caption
Caption 12 px, centred, wrapped at 120 px, at most 3 lines; text is the Name tag, else the id
Subnet width = max(170, icons per row x (icon + 24) + 40), at most 3 icons per row; height = 50 + rows x (icon + 32 + 16) + 20
AZ band height = 30 (title strip) + tallest subnet + 10; width = VPC inner width
Edge 2 px; flow badge 18 x 18 [PNG]

4.3 Where each kind goes

Kind Parent Position
Internet, users, on-premises boxes page left column, outside every account, vertically centred on what they connect to [SEE]
Account cloud page a grid; the account that owns the Transit Gateway is placed so the TGW is central [SEE]
Region account one per Region in use; stacked vertically when there are several
VPC Region side by side, ordered by the TGW they attach to, then by name
AZ VPC bands stacked top to bottom, sorted by AZ id [SEE]
Subnet AZ columns by role (public first, then private, then isolated and others); one role, one column, in every band [SEE]. Role = default route target: IGW means public
NAT gateway its public subnet centred in the subnet [SEE]
Interesting network interfaces (TGW attachment, interface endpoint, load balancer, firewall endpoint, Resolver endpoint) their subnet grouped by kind; the other ENIs are a count in the subnet label (+12 ENIs)
Internet gateway Region straddling the left border of its VPC, centred on the public subnets; link to the Internet icon [SEE]
Virtual private gateway Region straddling the left border of its VPC, below the IGW
Gateway endpoint (S3, DynamoDB) Region straddling the bottom border of the VPC, caption names the service
Load balancer VPC one icon in the subnet of the first AZ it spans; association edges to the other subnets are optional; the label carries the scheme
Transit Gateway Region of its owner between the VPCs it joins, outside every VPC, centred [SEE]
Direct Connect, VPN Region on the on-premises-facing side (left), between the on-premises box and the TGW or VGW [SEE]
Customer gateway on-premises group inside the on-premises box
Network Firewall endpoint firewall subnet one per AZ; the firewall policy is a Region-level icon
Resolver endpoint subnet the ENIs of the subnets it uses
VPC peering edge peering edge between the facing borders of the two VPC groups
Security group, network ACL none many-to-many, so never nested as groups; metadata and counts only (detail full adds NACL icons)

4.4 Edges

  • All edges: parent="1", absolute waypoints, orthogonal only, no diagonal segment; no edge runs through an icon or a caption: route along the gutters between groups [SEE].
  • Gateway links leave toward the outside (left). TGW attachment links leave a VPC from its right or bottom border toward the TGW. Parallel edges are staggered by 10 px.
  • One edge per pair of nodes and kind; parallel attachments collapse into one edge labelled with x N.
  • Peering and VPN edges are labelled with the resource id; a state other than active / available is written in the label.
  • Edge kinds and their patterns are in 2.6; heads: link none, flow one at the destination, peering both.

4.5 External accounts

Anything referenced but not owned by an audited account goes in its own AWS Cloud group per external account id, outside the audited accounts. Cases: a TGW owned elsewhere and shared through RAM, an attachment or peering whose accepter or requester account differs, an endpoint service of another account, shared Resolver rules or prefix lists. Style [REC]: the Cloud group plus dashed=1;strokeColor=#7D8998;fontColor=#5A6C86;, title External account 222222222222 (plus alias when known), containing only the referenced stubs: a stub VPC group (dashed outline, CIDR when the API returned one) or an icon labelled tgw-... (owner 222222222222, shared by RAM). Edges to stubs use the normal kinds. When more than one account appears on a page, label AZs with the AZ id (euw1-az1), because AZ names map to different physical zones in different accounts.

4.6 Legend

Bottom-left of the page, 40 px under the lowest account, 300 px wide, a "Generic group, filled" rectangle titled "Legend". Rows: the edge kinds present (60 px sample plus name), the subnet colours present (24 px square plus "public" or "private"), the external-account sample, the "Traffic flows" block if flows are numbered (a heading, then a 24 px disc and a title per number, 2.7), and a footer with tool name and version, account ids and the UTC timestamp. With a diff, the "Changes" block of 4.8 sits between the flows and the footer.

4.7 Pages and detail levels

  • Page 1 "Overview": account clouds, Regions, VPCs as single boxes with their CIDR (no AZ or subnet detail), the TGW, Direct Connect, VPN and peering edges, and the external accounts.
  • One page per account and Region with full detail. A VPC moves to its own page when it has more than 6 subnet columns or about 60 icons [REC].
  • Detail levels: overview, vpc, subnet (default), full (adds ENIs, route tables, NACLs and route associations).
  • Levels [REC]: the account level (this section: the Global page and one page per Region) and the VPC level, one page per VPC (4.9).
  • Lucid: one page per draw.io page; stay under 20,000 px per side and under 1 MB of JSON per file [DOC].

4.8 Change highlighting

A diff between two scans can be drawn on the pages of the newer one. build_layout, layout_of, drawio.render and lucid.render take three optional arguments: changes (a GraphDiff), previous (the older graph) and since (the date of the older scan, default previous.generated_at). With changes=None nothing below applies: the files are the ones of a run without a diff (tests/test_diff_highlight.py checks it). A ready Layout cannot take changes, because the marks are made while the pages are built.

What is marked. The layout reads the ids of added, changed and removed (the id of each resource change; a graph key account/region/type/id works as well) and the ends of edges_added. A box whose meta["resource"] is in added or changed gets meta["change"] = added or changed. An icon that stands for several interfaces (meta["members"]) is added when all of them are new and changed when only some are new or changed. An edge gets meta["change"] = added when the attachment of its link (via) is new, when both ends of the link are new, when one of its ends is a new box, or when an added edge of the diff names the ends of its link (a cross-account link included). Nothing moves: a highlighted page has the geometry of the plain one, apart from the legend. A layout with changes is cached apart from the plain one, so one never leaks into the other.

Colours and elements. Added #1D8102, changed #FF9900, removed #D13212; 3 px for a border and for a new edge.

Element draw.io Lucid
Box added or changed the cell keeps its style and gains change; over it a transparent frame cell (<id>~f, type change_frame, strokeWidth=3, pointerEvents=0): on the border of a group, 3 px outside an icon style.stroke of the shape: the colour, width 3
Badge a pill cell (<id>~n, type change_badge) with NEW or CHANGED, 14 px high, right-aligned with the frame and 2 px above its top edge a rectangle shape <id>~n, same box and text
New edge strokeColor and strokeWidth=3 appended to its style (a later key wins) stroke.color and stroke.width
Removed resource a card beside the legend the same card

The frame is a cell of its own because the AWS service icons paint their pictogram with the stroke colour: a green stroke on the icon would turn the glyph green. Frame and badge hang from the page, not from the box, and name their box in highlights. Lucid draws the border on the shape itself, so it has no frame. Every highlight cell is an <object> with type, change and highlights; the cell of the box keeps its own object and gains change (change is the last of the metadata keys, after name; customData in Lucid).

Legend. Between the flows and the footer, a "Changes" block: a row Changes since 2026-10-16 09:12 UTC: +3 −1 ~5 (added, removed, changed; the minus is U+2212; without a date: Changes: +3 −1 ~5), a swatch with the border of each colour in use ("New", "Changed" and, when cards are drawn, "Removed") and, when resources were removed but no old graph was given, the note Not drawn: N removed, see history. The counts are those of the whole diff, not of the page. The swatches take their border width from meta["stroke_w"].

Removed resources. They are not in the newer graph, so the layout has no place for them. With previous each one gets a dashed card (#D13212 border, #FDF3F1 fill, name and type · id) in a grid of three columns beside the legend under the heading Removed since <date>: at most 24 per page and then one card +N more, see history. The overview lists all of them, a Region page those of its Region. The details come from the diff (name, type, account, region); for a bare id they are read from previous.

4.9 VPC level pages

The account level (4.7) shows every VPC of an account and Region next to the others. The VPC level (exporters/vpc_level.py, build_vpc_pages(gv, plan, profile, detail, stamp, version, *, changes=None, previous=None, since=None)) draws one VPC per page and in full. A page is named <VPC name> (<account alias>) (the account id when the account has no alias) and has the id vpc-<start of the VPC id>; both are unique, and Page.region is the Region of the VPC.

  • Left column: the Internet icon (flow 1 to each internet gateway), one vpc_stub per peer VPC (name, CIDR and Region) and one Transit Gateway icon per hub the VPC attaches to. On the left border of the VPC, from the top: internet gateways, virtual private gateways and peering icons (each peering icon is joined to its stub). Gateway endpoints are centred on the bottom border.
  • The VPC: the zone bands and subnet columns of the account level, but a subnet holds every workload and every interface endpoint as an icon of its own, named after the workload or the service (no "N interface endpoints" icon), up to 48 icons per subnet (the last one stands for the rest). The first row of a subnet is its corner row: the route table icon (its name) at the left corner and the network ACL icon (its name, "N in / M out" as the sub-title) at the right corner. A workload or endpoint icon has the sub-title sg: N and meta["sg"], the security group ids separated by commas.
  • Right panels, top aligned with the VPC. First a card per route table of the VPC: the name ("(main)" for the main table), a Destination | Target | State header, the routes (the local one first, at most 12, then a "+N more" line whose full text is in detail) and the subnets it serves. The target is its short type (igw, nat, pcx, tgw, vpce, vgw, eni, local) and its name or short id. Then a card per security group in use: the name, the id, "N inbound / M outbound" and at most 6 inbound rules as proto port <- source. A card keeps its text in Box.sublabel, one line per line break, with no-break spaces between the columns, and is set in a monospace font because both exporters print a label as plain text.
  • assoc edges (thin grey dashed line, no heads, no disc) join each subnet to the card of its route table (the main table when the subnet has no explicit association). Each leaves the bottom border of its subnet, runs along the empty strip below the subnets of its zone (a lane of its own, 4 px from the next), crosses the right border of the VPC and follows a vertical line of its own (10 px from the next) to the left border of the card. No icon and no caption lies on that way, so these lines need no router; the router draws the other edges.
  • Internet, peering and Transit Gateway edges are routed like those of the account level and numbered like them (flows 1, 5 and 3).
  • Legend: the account-level legend, with a row for the assoc edge and for the route table, network ACL and security group squares.

4.10 Lines behind icons

An edge never bends around an icon. The router (layout._Router) prices a track that passes an icon on a border it does not end in at ICON_COST (40), and a track through an icon inside a subnet at WORKLOAD_COST (240), so a free track of the same length wins and a line crosses an icon only when no clean track exists. The drawing then cuts the line at the outline of the icon block (behind.pieces), so the line seems to run behind the icon. An icon on a border gets a white backing and a white caption background, and the line of the container it sits on stops at it too. The rules and their numbers are in Q25 of diagram-quality.md.

4.11 Service layer: edge lane and rows

The service nodes of the model (model.SERVICE_TYPES) are drawn by service_rows in three places, and their rules are Q56 to Q62 of diagram-quality.md. The reference architectures draw an edge of users, Route 53, CloudFront, WAF and the load balancer, a row of regional services above the VPCs and numbered flows; the atlas keeps that order.

Place What Order and caption
Edge lane Under the title of each Region frame (on the Global page: above the accounts) Users, Route 53, CloudFront, web ACL, API Gateway; a service icon is 64 px (a web ACL 48), captions are the name and one detail line
Badges A WAF web ACL that protects a distribution, Shield, an ACM certificate: 32 px icons in a column to the right of their service One-word caption (WAF, Shield, ACM); the legend row Badge: WAF, Shield, ACM
API VPC link A 48 px border icon on the right border of its VPC The API Gateway reaches it, it reaches the internal balancer
Regional row Below the lane, inside the Region frame Lambda without VPC (one icon, a count), S3 buckets one by one then "N other buckets", DynamoDB, ECR, KMS
Account row In the band of the last Region frame, beside the regional row CloudTrail, GuardDuty, AWS Config, CloudWatch, each with its key attribute (trails, enabled, recorder on, alarms)

Edges of the layer use the SERVICE_EDGE_KINDS styles of the registry (serves, origin, protects, integrates; the users reach the zone by a plain flow edge). They differ by dash and head, never by colour, as the network edges do. Their flows are numbered 8, 9 and 10 (ingress, API, database), after the seven network flows, and wear the SERVICE_FLOW_COLORS (teal, violet, magenta) so that a disc never has the colour of a network flow.

5. Kind registry (the contract)

grp: entries are in 2.4, svc:, res: and gen: entries in 2.5, V marks a verified Lucid class and I an inferred one (3.4), img means image fallback. Sizes are w x h in draw.io units; groups are sized by the layout.

Kind draw.io Lucid Size Parent
account grp:aws_cloud_alt AWSCloudAltAWS2024 (V) fit page
account_external grp:aws_cloud_alt + dashed grey (4.5) AWSCloudAltAWS2024 (V) fit page
region grp:region RegionAWS2024 (V) fit account
vpc grp:vpc2 VirtualPrivateCloudVPCAWS2024 (V) fit region
vpc_stub grp:vpc2 + dashed=1 VirtualPrivateCloudVPCAWS2024 (V) fit external account
az plain AZ rectangle AvailabilityZoneAWS2024 (V) fit vpc
subnet_public grp:public_subnet PublicSubnetAWS2024 (V) fit az
subnet_private grp:private_subnet PrivateSubnetAWS2024 (V) fit az
on_prem grp:corporate_data_center CorporateDataCenterAWS2024 (V) fit page
legend generic group, filled GenericGroupAWS2024 (V) 300 x fit page
igw res:internet_gateway ResAmazonVPCInternetGatewayAWS2024 (V) 48 x 48 region
nat res:nat_gateway ResAmazonVPCNATGatewayAWS2024 (V) 48 x 48 subnet
tgw svc:transit_gateway ArchAWSTransitGatewayAWS2024 (I) 64 x 64 region
tgw_attachment res:transit_gateway_attachment ResAWSTransitGatewayAttachmentAWS2024 (I) 48 x 48 subnet
vgw res:vpn_gateway ResAmazonVPCVPNGatewayAWS2024 (I) 48 x 48 region
cgw res:customer_gateway ResAmazonVPCCustomerGatewayAWS2024 (I) 48 x 48 on_prem
vpn svc:site_to_site_vpn ArchAWSSiteToSiteVPNAWS2024 (I) 64 x 64 region
dx svc:direct_connect ArchAWSDirectConnectAWS2024 (I) 64 x 64 region
peering res:peering (only when drawn as a node) ResAmazonVPCPeeringConnectionAWS2024 (I) 48 x 48 region
endpoint_interface res:endpoints ResAmazonVPCEndpointsAWS2024 (I) 48 x 48 subnet
endpoint_gateway res:endpoints ResAmazonVPCEndpointsAWS2024 (I) 48 x 48 region
privatelink_service svc:vpc_privatelink ArchAWSPrivateLinkAWS2024 (I) 64 x 64 region or external
alb res:application_load_balancer ResElasticLoadBalancingApplicationLoadBalancerAWS2024 (V) 48 x 48 subnet
nlb res:network_load_balancer ResElasticLoadBalancingNetworkLoadBalancerAWS2024 (V) 48 x 48 subnet
gwlb res:gateway_load_balancer ResElasticLoadBalancingGatewayLoadBalancerAWS2024 (I) 48 x 48 subnet
clb res:classic_load_balancer ResElasticLoadBalancingClassicLoadBalancerAWS2024 (I) 48 x 48 subnet
nfw svc:network_firewall ArchAWSNetworkFirewallAWS2024 (I) 64 x 64 region
nfw_endpoint svc:network_firewall at 48 ArchAWSNetworkFirewallAWS2024 (I) 48 x 48 subnet
resolver_endpoint res:route_53_resolver ResAmazonRoute53ResolverAWS2024 (I) 48 x 48 subnet
hosted_zone res:hosted_zone ResAmazonRoute53HostedZoneAWS2024 (I) 48 x 48 region
eni res:elastic_network_interface ResAmazonVPCElasticNetworkInterfaceAWS2024 (I) 48 x 48 subnet
eni_group res:instances (Compute #ED7100) ArchAmazonEC2AWS2024 (V; the class of ec2) 48 x 48 subnet (the "N instances" icon that stands for the workload interfaces beyond the first three)
instance res:instance2 (Compute #ED7100) ArchAmazonEC2AWS2024 (V; the class of ec2) 48 x 48 subnet (one workload interface; caption = Name tag)
directory svc:directory_service (Security #DD344C) ArchAWSDirectoryServiceAWS2024 (I; by the naming pattern, drawn as a red square until verified) 48 x 48 subnet (a directory interface)
route_table res:route_table ResAmazonRoute53RouteTableAWS2024 (I) 48 x 48 vpc (detail full)
nacl res:network_access_control_list ResAmazonVPCNetworkAccessControlListAWS2024 (I) 48 x 48 subnet (detail full)
sg svc:shield (Security #DD344C; the library has no security group icon, so the square wears the shield) ArchAWSShieldAWS2024 (I) 48 x 48 VPC level page (legend row)
card white box, #545B64 outline, monospace 10 px text GenericGroupAWS2024 (V) fit page (VPC level)
ram_share svc:resource_access_manager at 48 ArchAWSResourceAccessManagerAWS2024 (I) 48 x 48 region (annotation)
internet gen:internet img 64 x 64 page
users gen:users img 64 x 64 page
client gen:client img 48 x 48 on_prem
ec2 (off by default) res:instance2 ArchAmazonEC2AWS2024 (V; service icon, the chip-glyph class is unconfirmed) 48 x 48 subnet

Edge kinds: link, flow, peering, vpn, dx, xaccount, association, assoc (2.6, 3.8 and 4.9; assoc is #9AA0A6, 1 px, dashed 2 2, no heads, in every profile). Profiles: article (default) and aws2024 (2.3, 2.4, 1.5).

6. Checks and open items

6.1 How to verify an exporter (none of this was run during the research)

  1. xmllint --noout on every .drawio; then open it in draw.io desktop and export a PNG with its command line (drawio -x -f png) [KNOWN]. A blank rectangle where an icon should be means the shape name does not exist in the installed stencil set: every shape= and resIcon= value must come from the registry.
  2. Compare the render with 1.2 to 1.4: nesting, subnet colours, dashed Region and AZ, IGW on the VPC border, TGW outside the VPCs, grey arrows.
  3. JSON-level checks for Lucid: ids unique and 36 characters at most, every shapeId exists, endpoint positions inside 0..1, version present, file under 1 MB, zIndex increasing with depth; then run the probe.lucid import of 3.4 and record which classes render.
  4. Layout invariants that unit tests can assert: every child box lies inside its container box, no two icons overlap, one role per subnet column, AZ bands sorted by id, all edge segments axis-aligned, no edge segment crosses a caption box.

6.2 Not verified (carried into the project backlog)

  1. aws4.xml is not at the expected path, so icon names are checked against the sidebar only, and nothing was rendered.
  2. Which of group_aws_cloud and group_aws_cloud_alt draws the dark tab with the "aws" mark.
  3. Outline colours of Region, AZ and VPC in profile article are nominal values inferred from anti-aliased 1 px lines; fills, corner squares, arrows and badges were measured. Networking and Compute glyph colours of the era are inferred.
  4. That gradientDirection=north puts fillColor at the bottom (as measured), and the era gradients of non-Networking categories.
  5. object wrappers, exitX/entryX, page="0" and uncompressed XML are standard draw.io behaviour, not re-checked here.
  6. About 30 Lucid AWS 2024 class names are derived by a rule that matched 5 of 5 known pairs; the catalog page does not exist in any retrievable form, and the behaviour for an unknown className is undocumented.
  7. Lucid: which Cloud variant draws the logo, whether text on a named container is its title, where a namedShape draws its own text, and whether named shapes accept style overrides.
  8. Lucid: the value of version (1), the exact image block object and stroke.width 0, and that a rectangle with rounding equal to its side renders as a disc.
  9. Lucid: no UI import is documented; the OAuth scope needed by the REST call, and the groups and layers pages, were not read. document.json is capped at 2 MB per the raw page (1 MB in a secondary summary).
  10. AWS Architecture Icons licence terms were not read; do not bundle icon files until they are.
  11. Icon sizes 48 and 64 and the group margins are recalled guidelines or recommendations, not measured; the reference PNG is downscaled, so its pixel sizes are only relative.
  12. The asset file names behind the Lucid naming rule come from memory.
  13. The seven flows of the reference legend are paraphrased and not copied: the atlas numbers the kinds of traffic it can see (2.7) and does no route analysis.
  14. The draw.io numbers are for branch dev at the pinned commit; the sidebar is what the editor offers and may drift from AWS naming. Re-run the lookup when the pin changes.

6.3 Suggested build order

Kind registry and the two style profiles as data files; layout engine producing absolute boxes and waypoints; draw.io writer; legend; Lucid writer with the image fallback; the probe import for class names; invariant tests.