intelligence/wiki-page.ex
Wiki page
A company wiki page with cited claims and the evidence each one comes from.
# in the module that renders the template
use EHVisuals
<div class="h-96 rounded-xl border border-border">
<.intelligence_wiki_page animated />
</div>
Props
| Prop | Type | Default | What it does |
|---|---|---|---|
breadcrumb |
string | "Wiki / Operations / Returns" |
|
title |
string | "How returns are handled" |
|
meta |
string | "Written from 3 sources · updated 2 days ago" |
|
evidence |
string | "Evidence" |
|
sources |
list | [%{title: "Returns SOP, section 4", kind: "Document"}, %{title: "Ops sync with Delivery", kind: "Meeting"}, ...] |
Up to three `%{title, kind}`. |
Frame props, shared by every composition
| Prop | Type | Default | What it does |
|---|---|---|---|
animated |
boolean | false |
Turns motion on. Without it the composition renders in its final, still state. |
trigger |
"mount" | "in-view" | "in-view-repeat" | "in-view" |
When the entrance plays: on page load, once when scrolled into view, or every time it comes back into view. |
hover |
boolean | false |
Enables the hover micro-interactions the composition supports. |
glow |
boolean | true |
The warm incandescent halo behind the composition. |
fade_out |
boolean | false |
Fades the bottom edge into the surface underneath. |
isometric |
boolean | false |
Tilts the composition into the isometric plane of the platform stack. |
theme |
"dark" | "light" | "dark" |
`dark` for the site canvas, `light` for the cream reversed surface. |
class |
string | nil |
Extra classes for the frame. |
rest |
global | — |
Any other HTML attribute, set on the frame. |
Source
Two files. Copy them into your app if you would rather own the code than depend on the library.
lib/eh_visuals/intelligence/wiki-page.ex
defmodule EHVisuals.Intelligence.WikiPage do
@moduledoc """
A wiki page the company wrote about itself, with every claim cited.
"""
use EHVisuals.Composition,
name: "intelligence/wiki-page",
title: "Wiki page",
description: "A company wiki page with cited claims and the evidence each one comes from."
@sources [
%{title: "Returns SOP, section 4", kind: "Document"},
%{title: "Ops sync with Delivery", kind: "Meeting"},
%{title: "returns_2026", kind: "Table"}
]
# Text lines as {width, citation number or nil}.
@lines [{300, nil}, {206, 1}, {282, nil}, {148, 2}]
attr(:breadcrumb, :string, default: "Wiki / Operations / Returns")
attr(:title, :string, default: "How returns are handled")
attr(:meta, :string, default: "Written from 3 sources · updated 2 days ago")
attr(:evidence, :string, default: "Evidence")
attr(:sources, :list, default: @sources, doc: "Up to three `%{title, kind}`.")
attr(:label, :string,
default: "A wiki page with two cited claims and three sources listed as evidence"
)
frame_attrs()
@spec intelligence_wiki_page(map()) :: Phoenix.LiveView.Rendered.t()
def intelligence_wiki_page(assigns) do
rows = assigns.sources |> Enum.take(3) |> Enum.with_index()
assigns =
assigns
|> assign(:lines, Enum.with_index(@lines))
|> assign(:rows, rows)
|> assign(:height, 198 + length(rows) * 30 + 12)
~H"""
<.frame name="intelligence/wiki-page" label={@label} {frame_opts(assigns)}>
<svg viewBox={"0 0 360 #{@height}"}>
<g class="ehv-h-lift">
<rect class="ehv-card ehv-a-rise" x="0.5" y="0.5" width="359" height={@height - 1} rx="12" />
<text class="ehv-mono ehv-a-fade ehv-i-1" x="20" y="31" font-size="8.5">
{String.upcase(@breadcrumb)}
</text>
<text class="ehv-t-strong ehv-a-fade ehv-i-2" x="20" y="58" font-size="16">{@title}</text>
<text class="ehv-t-3 ehv-a-fade ehv-i-2" x="20" y="77" font-size="11">{@meta}</text>
<g :for={{{width, cite}, index} <- @lines} class={"ehv-a-fade ehv-i-#{index + 3}"}>
<rect
class={"ehv-fill-soft ehv-a-grow-x ehv-i-#{index + 3}"}
x="20"
y={96 + index * 16}
width={width}
height="6"
rx="3"
/>
<g :if={cite}>
<rect
class="ehv-fill-lime-soft"
x={26 + width}
y={92 + index * 16}
width="16"
height="14"
rx="4"
/>
<text
class="ehv-mono ehv-t-lime"
x={34 + width}
y={102 + index * 16}
font-size="8"
text-anchor="middle"
>
{cite}
</text>
</g>
</g>
<line class="ehv-line-faint" x1="20" x2="340" y1="168.5" y2="168.5" />
<text class="ehv-mono ehv-a-fade ehv-i-6" x="20" y="188" font-size="8.5">
{String.upcase(@evidence)}
</text>
<g :for={{source, index} <- @rows} class={"ehv-a-rise ehv-i-#{index + 7}"}>
<rect
class="ehv-fill-lime-soft"
x="20"
y={198 + index * 30}
width="18"
height="18"
rx="5"
/>
<text
class="ehv-mono ehv-t-lime"
x="29"
y={210.5 + index * 30}
font-size="8.5"
text-anchor="middle"
>
{index + 1}
</text>
<text x="48" y={211 + index * 30} font-size="12">{source.title}</text>
<text class="ehv-mono" x="340" y={211 + index * 30} font-size="8" text-anchor="end">
{String.upcase(source.kind)}
</text>
</g>
</g>
</svg>
</.frame>
"""
end
end
assets/css/intelligence/wiki-page.css
/* intelligence/wiki-page */
.ehv-intelligence-wiki-page { --ehv-max-w: 380px; }