body { margin: 0; padding: 0; color: var(--foreground); background: var(--background); font-family: sans-serif; font-size: 14px; } /* Fixed background layer, same construction as the landing page */ #bg { position: fixed; width: 100vw; height: 100vh; z-index: -1; background: var(--background); } #bg img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; opacity: 0; transition: opacity 3s linear; } #bg img.loaded { opacity: 1; } h1, h2, h3, h4, h5, h6 { color: var(--color1); margin-top: 10px; margin-bottom: 0; } h1 { margin-top: 0; font-size: 28px; } h2 { color: var(--color2); } p { margin-top: 2px; line-height: 1.5; } a { color: var(--color2); text-decoration: none; font-weight: bold; } a:hover { color: var(--color3); } em { color: var(--color3); } sup.fn { font-size: 10px; } sup.fn a { font-weight: normal; } pre { margin: 8px 0; max-width: 640px; } pre > code { border: 1px solid color-mix(in srgb, var(--foreground) 25%, transparent); display: block; padding: 8px 12px; overflow-x: auto; font-size: 13px; } article { max-width: 1024px; margin: 25px auto; padding: 20px; background: color-mix(in srgb, var(--background) 90%, transparent); box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.9); } @media (max-width: 1064px) { article { margin: 15px 12px; } } img { max-width: 100%; } math[display="block"] { margin: 12px 0 12px 24px; font-size: 17px; color: var(--color4); } aside.explainer { border-left: 3px solid var(--color4); background: color-mix(in srgb, var(--foreground) 5%, transparent); padding: 8px 12px; margin: 12px 0; font-size: 13px; } .rewrite-target { text-decoration: underline dashed var(--color3); text-underline-offset: 3px; } .rewrite-target::after { content: ' ✎'; color: var(--color3); font-size: 11px; } .attribution { font-size: 12px; opacity: 0.7; } .big-number { font-size: 26px; color: var(--color1); margin: 8px 0 4px 0; } /* Demo */ .needs-image { display: none; } .needs-image.visible { display: block; } #base .image-original img { max-width: 256px; min-width: 256px; } .sample { height: 48px; margin: 0 4px 4px 0; cursor: pointer; vertical-align: middle; } .sample:hover { outline: 2px solid var(--color1); } /* Comparison slider */ .compare { position: relative; max-width: 512px; overflow: hidden; touch-action: none; cursor: ew-resize; user-select: none; } .compare img { display: block; width: 100%; pointer-events: none; } /* The top image stretches to the base image's box, so differently sized results (8x8 thumbs, crops) stay comparable under the divider */ .compare .compare-b { position: absolute; top: 0; left: 0; height: 100%; object-fit: fill; clip-path: inset(0 0 0 50%); } .compare .compare-divider { position: absolute; top: 0; bottom: 0; left: 50%; width: 2px; margin-left: -1px; background: var(--color1); } .compare .compare-handle { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 28px; height: 28px; line-height: 28px; text-align: center; border-radius: 50%; background: var(--color1); color: var(--background); font-size: 15px; } .compare .compare-label { position: absolute; top: 6px; padding: 2px 6px; font-size: 11px; background: color-mix(in srgb, var(--background) 75%, transparent); color: var(--foreground); } .compare .compare-label.a { left: 6px; } .compare .compare-label.b { right: 6px; } /* Busy indicator while the worker renders a mutation */ .compare.busy::after { content: 'mutating…'; position: absolute; right: 8px; bottom: 8px; padding: 3px 9px; background: color-mix(in srgb, var(--background) 80%, transparent); color: var(--color1); font-size: 12px; animation: busy-pulse 1s ease-in-out infinite; } .distances.busy td { opacity: 0.35; } @keyframes busy-pulse { 50% { opacity: 0.35; } } /* Hash visualisation */ .hash-panel { display: flex; flex-flow: row wrap; gap: 24px; align-items: flex-start; } .hash-value { font-size: 18px; letter-spacing: 2px; } .hash-value.small { display: block; margin-top: 4px; font-size: 12px; letter-spacing: 1px; opacity: 0.8; } .bit-grid { display: grid; grid-template-columns: repeat(8, 20px); } .bit-grid.wide { grid-template-columns: repeat(12, 20px); } .bit-grid .bit { height: 20px; box-sizing: border-box; border: 1px solid var(--background); } .bit-grid.small { grid-template-columns: repeat(8, 13px); } .bit-grid.small .bit { height: 13px; } .bit-grid .bit.on { background: var(--foreground); } .bit-grid .bit.off { background: color-mix(in srgb, var(--foreground) 12%, transparent); } /* Changed bits keep their on/off brightness and get a red tint + border, so light-changed and dark-changed cells stay distinguishable */ .bit-grid .bit.diff { border-color: hsl(4 70% 55%); } .bit-grid .bit.on.diff { background: color-mix(in srgb, var(--foreground) 55%, hsl(4 70% 50%)); } .bit-grid .bit.off.diff { background: hsl(4 60% 50% / 0.25); } .heat-grid { display: grid; grid-template-columns: repeat(8, 32px); } .heat-grid > div { height: 32px; box-sizing: border-box; } .heat-grid.mini { grid-template-columns: repeat(8, 22px); } .heat-grid.mini > div { height: 22px; } .pixelated, #phash-resize img, .input-thumb img { image-rendering: pixelated; image-rendering: -moz-crisp-edges; } #phash-resize img { width: 128px; height: 128px; } .input-thumb img { width: 176px; height: 176px; } /* DCT extras */ .grid-overlay { position: relative; width: 256px; } .grid-overlay.mini { width: 176px; } #dct-basis-wrap { position: relative; display: inline-block; } .basis-hover { display: none; position: absolute; outline: 2px solid var(--color1); outline-offset: -1px; pointer-events: none; } #dct-basis { cursor: crosshair; } #dct-formula .formula-result { display: none; } #dct-formula.live .formula-result { display: inline; } #dct-formula.live .var-u, #dct-formula.live .var-v, #dct-formula.live .formula-value { color: var(--color1); } #image-dct .hover-cell { outline: 2px solid var(--color1); outline-offset: -2px; } #dct-zigzag { position: absolute; top: 0; left: 0; pointer-events: none; } #dct-zigzag polyline { stroke: var(--color1); stroke-width: 3; stroke-linejoin: round; } #dct-zigzag polyline.play { transition: stroke-dashoffset 2.5s ease-in-out; } #dct-basis { background: var(--background); } /* Reconstruction demos */ .recon-row { display: flex; flex-flow: row wrap; gap: 24px; align-items: flex-start; margin: 10px 0; } .recon-row figure { margin: 0; text-align: center; } .recon-row figcaption { font-size: 12px; opacity: 0.8; margin-top: 4px; } .recon-row canvas { width: 176px; height: 176px; image-rendering: pixelated; image-rendering: -moz-crisp-edges; } #recon-k { width: 256px; vertical-align: middle; } .recon-note { font-size: 12px; opacity: 0.7; margin-left: 8px; } #recon-zigzag { position: absolute; top: 0; left: 0; pointer-events: none; } #recon-zigzag polyline { stroke-width: 2.5; stroke-linejoin: round; transition: stroke-dashoffset 0.12s linear; } #recon-zigzag .zig-head { stroke: var(--color1); } #recon-zigzag .zig-tail { stroke: color-mix(in srgb, var(--foreground) 45%, transparent); } /* Tables */ table.facts { border-collapse: collapse; margin: 10px 0; } table.facts th, table.facts td { text-align: left; padding: 4px 14px 4px 0; border-bottom: 1px solid color-mix(in srgb, var(--foreground) 20%, transparent); font-size: 13px; } table.facts th { color: var(--color1); font-weight: normal; } .distances td { text-align: center; font-size: 18px; min-width: 64px; } .distances td.match { color: hsl(135 50% 45%); } .distances td.nomatch { color: hsl(4 70% 55%); } /* LSH demo */ .lsh-thumb img { height: 110px; margin-bottom: 6px; display: block; } .lsh-distance { font-size: 16px; } .lsh-distance .match { font-size: 22px; color: hsl(135 50% 45%); } .lsh-distance .nomatch { font-size: 22px; color: hsl(4 70% 55%); } /* Flip demo */ #flip-stage img { max-width: 256px; max-height: 256px; transition: transform 0.7s ease-in-out; } #flip-stage img.flipped { transform: scaleX(-1); } #ghost-canvas { transition: transform 0.4s ease-in-out; } #ghost-canvas.flipped { transform: scaleX(-1); } .flip-table th { color: var(--color1); font-weight: normal; text-align: left; padding-right: 12px; } .flip-table td { vertical-align: top; padding: 6px 12px 6px 0; } .flip-distance { font-size: 24px; } .flip-distance.match { color: hsl(135 50% 45%); } .flip-distance.nomatch { color: hsl(4 70% 55%); } /* Ranking */ .pool { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 4px; max-height: 330px; overflow-y: auto; margin: 10px 0; } .pool img { width: 100%; aspect-ratio: 1; object-fit: cover; cursor: pointer; display: block; } .pool img:hover { outline: 2px solid var(--color1); } .pool img.query { outline: 3px solid var(--color1); } .ranking-results h3 { margin-top: 14px; } .thumb-row { display: flex; flex-flow: row wrap; gap: 8px; } .thumb-row figure { width: 84px; margin: 0; text-align: center; } .thumb-row figure.hit { outline: 2px solid hsl(135 50% 45%); } .thumb-row img { width: 84px; height: 84px; object-fit: cover; display: block; } .thumb-row figcaption { font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Precision-recall charts */ .pr-controls { margin: 10px 0; } #pr-legend { display: flex; flex-flow: row wrap; gap: 4px 14px; margin-bottom: 8px; } .pr-group { display: flex; flex-flow: row wrap; gap: 4px; } .pr-chip { display: inline-flex; align-items: center; gap: 5px; border: 1px solid color-mix(in srgb, var(--foreground) 20%, transparent); background: none; color: var(--foreground); font-size: 11px; padding: 2px 7px; cursor: pointer; transition: opacity 0.15s; } .pr-chip.dim { opacity: 0.3; } .pr-chip.pinned { border-color: var(--color1); } .pr-slider { display: inline-block; margin: 4px 0; color: var(--color4); } .pr-slider input { width: 220px; vertical-align: middle; margin-left: 8px; } .pr-charts { display: flex; flex-flow: row wrap; gap: 12px; } .pr-charts figure { margin: 0; flex: 1 1 300px; max-width: 340px; } .pr-charts figcaption { color: var(--color1); font-size: 14px; margin-bottom: 2px; } .pr-svg { width: 100%; height: auto; background: color-mix(in srgb, var(--foreground) 3%, transparent); } .pr-grid { stroke: color-mix(in srgb, var(--foreground) 12%, transparent); stroke-width: 1; } .pr-tick { fill: color-mix(in srgb, var(--foreground) 55%, transparent); font-size: 9px; } .pr-axis { fill: color-mix(in srgb, var(--foreground) 70%, transparent); font-size: 11px; } .pr-line { fill: none; stroke-width: 1.8; transition: opacity 0.15s; } .pr-dot { stroke: var(--background); stroke-width: 2; transition: opacity 0.15s; } .pr-line.faded, .pr-dot.faded { opacity: 0.12; } #pr-tooltip { position: fixed; z-index: 10; background: color-mix(in srgb, var(--background) 92%, transparent); border: 1px solid var(--color1); color: var(--foreground); font-size: 12px; padding: 4px 8px; pointer-events: none; white-space: nowrap; } /* Retrieval demos */ .dist-figure, .toy-figure { margin: 10px 0; } .dist-figure figcaption, .toy-figure figcaption { font-size: 12px; opacity: 0.8; margin-top: 4px; } .dist-svg { max-width: 720px; } .dist-bar { fill: color-mix(in srgb, var(--foreground) 45%, transparent); } .dist-copy { fill: hsl(135 50% 45%); stroke: var(--background); stroke-width: 1; } .dist-region { fill: color-mix(in srgb, var(--color1) 10%, transparent); } .dist-thresh { stroke: var(--color1); stroke-width: 2; } .dist-readout, .toy-stats { margin-left: 12px; color: var(--color4); } .toy-node { fill: color-mix(in srgb, var(--foreground) 30%, transparent); transition: opacity 0.3s, fill 0.3s; } .toy-node.seen { fill: color-mix(in srgb, var(--foreground) 10%, var(--background)); stroke: var(--foreground); stroke-width: 2; } .toy-node.match { fill: hsl(135 50% 45%); } .toy-node.pruned { opacity: 0.15; } .toy-edge { stroke: color-mix(in srgb, var(--foreground) 45%, transparent); stroke-width: 1.5; transition: opacity 0.3s; } .toy-edge-label { fill: color-mix(in srgb, var(--foreground) 70%, transparent); font-size: 9px; transition: opacity 0.3s; } .toy-edge.pruned, .toy-edge-label.pruned { opacity: 0.15; } .big-stats .stat-note { font-size: 12px; opacity: 0.7; margin: 0; max-width: 220px; } .big-curve-svg { width: 250px; } .big-curve-line { stroke: var(--color2); } .big-curve-dot { fill: var(--color1); } /* Lists */ ul.loose-ends li, ol.references li { margin-bottom: 6px; line-height: 1.5; } ol.references li:target { outline: 1px dashed var(--color1); outline-offset: 4px; }