(???) svg xmlns="http://www.w3.org/2000/svg" viewBox="-200 -80 440 520"
(???) fill="#f9f4f2" stroke-width="2"
(???) font-family="Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace"
(???) font-size="12"
(???) dominant-baseline="middle" text-anchor="middle">
(???) <title>ZIP file layout</title>
(???) <defs>
(???) <style>
(???) .file1, .file2, .directory {
(???) cursor: pointer;
(???) }
(???) /* note that this only works when the svg is loaded directly or through an object tag */
(???) :has(.file1:hover) .file1 polyline:not(.hitbox) {
(???) stroke-dasharray: 6px 4px;
(???) animation: marching-ants .6s linear infinite;
(???) }
(???) :has(.file1:hover) .file1 polyline:not(.hitbox) #hatch {
(???) stroke-width: 4px;
(???) }
(???) <!--
(???) :has(.file1:hover) .file1 rect {
(???) fill: white;
(???) } -->
(???) :has(.file2:hover) .file2 polyline:not(.hitbox) {
(???) stroke-dasharray: 6px 4px;
(???) animation: marching-ants .6s linear infinite;
(???) }
(???) :has(.directory:hover) .directory polyline:not(.hitbox) {
(???) stroke-dasharray: 6px 4px;
(???) animation: marching-ants .6s linear infinite;
(???) }
(???) @keyframes marching-ants {
(???) to { stroke-dashoffset: -10px; }
(???) }
(???) </style>
(???) <marker id="arrow"
(???) markerWidth="10" markerHeight="10"
(???) refX="7" refY="5"
(???) markerUnits="strokeWidth"
(???) orient="auto-start-reverse">
(???) <path d="M 2 2 L 8 5 L 2 8" fill="none"
(???) stroke-width="1" stroke="#86cfe4" stroke-linecap="round"/>
(???) </marker>
(???) <pattern id="hatch" width="8" height="8" patternTransform="rotate(-45)"
(???) patternUnits="userSpaceOnUse">
(???) <line x1="8" stroke="#86cfe4"/>
(???) </pattern>
(???) </defs>
(???) <rect x="-200" y="-80" fill="#27a2cc" width="100%" height="100%"/>
(???) <rect fill="#86cfe4"/> <!-- sea blue light TODO (for hover of alles bold font + dikkere hatch) t -->
(???) <text y="-45" font-size="16">ZIP file layout</text>
(???) <!-- line text -->
(???) <!-- <text x="20" y="242" font-size="10">offset</text>-->
(???) <!-- file 1 -->
(???) <g transform="translate(-120, 0)" class="file1" aria-label="File header 1">
(???) <rect stroke="#f9f4f2" width="240" height="30"/>
(???) <text fill="#27a2cc" x="120" y="15">File header 1</text>
(???) </g>
(???) <g transform="translate(-120, 31)" class="file1" aria-label="Compressed file data 1">
(???) <rect fill="url(#hatch)" width="240" height="100"/> <!-- TODO overlaps file header 1 by 1px -->
(???) <rect fill="#27a2cc" x="30" y="20" width="180" height="30"/>
(???) <text x="120" y="35" font-size="10">Compressed file data 1</text>
(???) </g>
(???) <!-- file 2 -->
(???) <g transform="translate(-120, 135)" class="file2" aria-label="File header 2">
(???) <rect stroke="#f9f4f2" width="240" height="30"/>
(???) <text fill="#27a2cc" x="120" y="15">File header 2</text>
(???) </g>
(???) <g transform="translate(-120, 166)" class="file2" aria-label="Compressed file data 2">
(???) <rect fill="url(#hatch)" width="240" height="100"/>
(???) <rect fill="#27a2cc" x="30" y="20" width="180" height="30"/>
(???) <text x="120" y="35" font-size="10">Compressed file data 2</text>
(???) </g>
(???) <!-- directory -->
(???) <!-- have more height because the contain more bytes then the file headers -->
(???) <g transform="translate(-120, 270)" class="file1"
(???) aria-label="Directory entry 1"> <!-- TODO could also add class 'directory' because directory trailer links to it -->
(???) <rect width="240" stroke="#f9f4f2" height="40"/>
(???) <text fill="#27a2cc" x="120" y="20">Directory entry 1</text>
(???) <polyline stroke="transparent" stroke-width="15" fill="none" stroke-linejoin="round"
(???) points="240,20 280,20 280,-270 250,-270" class="hitbox"/>
(???) <polyline stroke="#86cfe4" fill="none" stroke-linejoin="round"
(???) points="240,20 280,20 280,-270 250,-270"
(???) marker-end="url(#arrow)"/> <!-- aria-label could be 'has an offset to the file header ' -->
(???) </g>
(???) <g transform="translate(-120, 315)" class="file2">
(???) <rect width="240" stroke="#f9f4f2" height="40"/>
(???) <text fill="#27a2cc" x="120" y="20">Directory entry 2</text>
(???) <polyline stroke="transparent" stroke-width="15" fill="none" stroke-linejoin="round"
(???) points="240,20 320,20 320,-180 250,-180" class="hitbox"/>
(???) <polyline stroke="#86cfe4" fill="none" stroke-linejoin="round"
(???) points="240,20 320,20 320,-180 250,-180"
(???) marker-end="url(#arrow)"/> <!-- aria-label could be 'has an offset to the file header ' -->
(???) </g>
(???) <g transform="translate(-120, 360)" class="directory" aria-label="Directory trailer">
(???) <rect fill="transparent" stroke="#f9f4f2" width="240" height="30"/>
(???) <text x="120" y="15" font-size="10">Directory trailer</text>
(???) <polyline stroke="transparent" stroke-width="15" fill="none" stroke-linejoin="round"
(???) points="0,15 -40,15 -40,-90 -10,-90" class="hitbox"/>
(???) <polyline stroke="#86cfe4" fill="none" stroke-linejoin="round"
(???) points="0,15 -40,15 -40,-90 -10,-90"
(???) marker-end="url(#arrow)"/> <!-- aria-label could be 'has an offset to first directory entry' -->
(???) </g>
(???) /svg>