Document Purpose: Explain the human readability problem with XBRL, the official solutions (Inline XBRL, OIM), viewer technologies, and rendering approaches for making XBRL instances human-readable
Last Updated: January 2026
Target Audience: XBRL implementers, regulators, filing preparers, tool developers
The Fundamental Problem:
XBRL was designed for machine consumption, not human reading. Raw XBRL-XML is virtually unreadable by humans.
Example - Same Data, Two Views:
Traditional XBRL-XML (Machine-Readable):
<xbrli:xbrl>
<xbrli:context id="ctx_2024_Q4">
<xbrli:entity>
<xbrli:identifier scheme="http://www.sec.gov/CIK">0001234567</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:instant>2024-12-31</xbrli:instant>
</xbrli:period>
</xbrli:context>
<xbrli:unit id="USD">
<xbrli:measure>iso4217:USD</xbrli:measure>
</xbrli:unit>
<us-gaap:Assets contextRef="ctx_2024_Q4" unitRef="USD" decimals="-3">
250000000
</us-gaap:Assets>
<us-gaap:Liabilities contextRef="ctx_2024_Q4" unitRef="USD" decimals="-3">
150000000
</us-gaap:Liabilities>
<!-- ... 5,000 more facts ... -->
</xbrli:xbrl>
Human wants to see:
ACME Corporation
Balance Sheet
As of December 31, 2024
(in thousands of USD)
Assets $250,000
Liabilities $150,000
Stockholders' Equity $100,000
The Evolution of Solutions:
Key Official Specifications:
Result:
XBRL data can now be consumed by humans through standard web browsers while remaining fully machine-readable.
Problem 1: Separation of Context and Data
<!-- The fact -->
<us-gaap:CashAndCashEquivalents contextRef="c1" unitRef="USD">
5000000
</us-gaap:CashAndCashEquivalents>
<!-- The context (100 lines earlier) -->
<xbrli:context id="c1">
<xbrli:entity>
<xbrli:identifier scheme="http://www.sec.gov/CIK">0001234567</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:instant>2024-12-31</xbrli:instant>
</xbrli:period>
</xbrli:context>
Human must:
For 5,000 facts, this is impossible!
Problem 2: No Presentation Structure
Facts in XBRL-XML are typically unordered:
<us-gaap:Liabilities>150000000</us-gaap:Liabilities>
<us-gaap:StockholdersEquity>100000000</us-gaap:StockholdersEquity>
<us-gaap:Assets>250000000</us-gaap:Assets>
Human expects:
Assets 250,000
Liabilities 150,000
Stockholders' Equity 100,000
Presentation order is defined in separate linkbase file!
Problem 3: Cryptic Concept Names
<us-gaap:CashAndCashEquivalentsAtCarryingValue>5000000</us-gaap:CashAndCashEquivalentsAtCarryingValue>
Human wants to see:
Cash and Cash Equivalents: $5,000
Labels are in separate linkbase file!
Problem 4: Dimensional Complexity
<context id="c_segment_retail">
<entity>
<identifier>0001234567</identifier>
<segment>
<xbrldi:explicitMember dimension="us-gaap:StatementBusinessSegmentsAxis">
company:RetailSegmentMember
</xbrldi:explicitMember>
</segment>
</entity>
<period><instant>2024-12-31</instant></period>
</context>
<us-gaap:Revenues contextRef="c_segment_retail">100000000</us-gaap:Revenues>
Human wants:
Revenue - Retail Segment: $100,000
Problem 5: File Size
Typical SEC 10-K:
Opening in text editor crashes most computers!
Scenario 1: Analyst Reviewing Filing
Task: Compare company's revenue across segments
Without viewer:
├─ Download 25 MB XBRL file
├─ Cannot open in text editor (too large)
├─ Write Python script to extract facts
├─ Match contextRefs to contexts
├─ Resolve dimension members
├─ Filter for revenue concept
├─ Group by segment dimension
├─ Format output
Time: 2-3 hours
With viewer:
├─ Open in browser
├─ Navigate to revenue section
├─ View segment breakdown
Time: 2 minutes
Scenario 2: Regulator Reviewing Submission
Task: Verify capital adequacy disclosures
Without viewer:
├─ Parse XML manually
├─ Find specific templates
├─ Cross-check calculations
├─ Verify dimensional breakdowns
Practical? NO
With viewer:
├─ Open rendered view
├─ Navigate to capital templates
├─ Review table-by-table
├─ Check calculations visually
Practical? YES
Scenario 3: Company Preparing Filing
Task: Review draft filing before submission
Without viewer:
├─ Trust the software
├─ Hope it's correct
├─ Cannot visually verify
Risk: HIGH
With viewer:
├─ Generate HTML preview
├─ Review as humans will see it
├─ Catch errors visually
├─ Verify presentation
Risk: LOW
Inline XBRL embeds XBRL facts directly in HTML documents, making them:
Official Specification: Inline XBRL 1.1 (2013, updated 2024)
Status: Recommendation by XBRL International
Adoption: Mandatory for SEC filings (since 2019), widely adopted globally
Traditional Approach:
┌─────────────────┐ ┌─────────────────┐
│ HTML Document │ │ XBRL Instance │
│ (Human View) │ │ (Machine Data) │
│ │ │ │
│ Two separate │ │ Two separate │
│ files that │ ≠ │ files that │
│ must be kept │ │ must be kept │
│ synchronized │ │ synchronized │
└─────────────────┘ └─────────────────┘
Inline XBRL Approach:
┌────────────────────────────────────────┐
│ Single Inline XBRL Document │
│ (.html with embedded XBRL tags) │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Human View │ │ Machine Data │ │
│ │ (HTML/CSS) │ │ (XBRL tags) │ │
│ │ │ │ │ │
│ │ Same file, │ │ Same file, │ │
│ │ always │═══│ always │ │
│ │ synchronized │ │ synchronized │ │
│ └──────────────┘ └──────────────┘ │
└────────────────────────────────────────┘
Simple Inline XBRL Document:
<!DOCTYPE html>
<html xmlns:ix="http://www.xbrl.org/2013/inlineXBRL"
xmlns:xbrli="http://www.xbrl.org/2003/instance"
xmlns:us-gaap="http://fasb.org/us-gaap/2024">
<head>
<title>ACME Corporation - 10-K Filing</title>
<style>
table { border-collapse: collapse; }
td { padding: 8px; border: 1px solid #ccc; }
.right { text-align: right; }
</style>
</head>
<body>
<!-- Hidden XBRL header section -->
<ix:header>
<ix:hidden>
<ix:references>
<link:schemaRef xlink:href="https://xbrl.fasb.org/us-gaap/2024/us-gaap-2024.xsd"/>
</ix:references>
</ix:hidden>
</ix:header>
<!-- Visible content with embedded XBRL -->
<h1>ACME Corporation</h1>
<h2>Consolidated Balance Sheet</h2>
<p>As of <ix:nonNumeric name="dei:DocumentPeriodEndDate" format="ixt:datelongus">
December 31, 2024
</ix:nonNumeric></p>
<p>(in thousands of U.S. Dollars)</p>
<table>
<tr>
<th>Assets</th>
<th></th>
</tr>
<tr>
<td>Current Assets:</td>
<td></td>
</tr>
<tr>
<td>Cash and Cash Equivalents</td>
<td class="right">
$<ix:nonFraction name="us-gaap:CashAndCashEquivalentsAtCarryingValue"
contextRef="AsOf2024-12-31"
unitRef="USD"
decimals="-3"
format="ixt:numcommadot">
5,000
</ix:nonFraction>
</td>
</tr>
<tr>
<td>Accounts Receivable</td>
<td class="right">
$<ix:nonFraction name="us-gaap:AccountsReceivableNetCurrent"
contextRef="AsOf2024-12-31"
unitRef="USD"
decimals="-3"
format="ixt:numcommadot">
3,000
</ix:nonFraction>
</td>
</tr>
<tr>
<td><strong>Total Assets</strong></td>
<td class="right">
<strong>$<ix:nonFraction name="us-gaap:Assets"
contextRef="AsOf2024-12-31"
unitRef="USD"
decimals="-3"
format="ixt:numcommadot">
250,000
</ix:nonFraction></strong>
</td>
</tr>
</table>
<!-- Hidden contexts -->
<ix:hidden>
<xbrli:context id="AsOf2024-12-31">
<xbrli:entity>
<xbrli:identifier scheme="http://www.sec.gov/CIK">0001234567</xbrli:identifier>
</xbrli:entity>
<xbrli:period>
<xbrli:instant>2024-12-31</xbrli:instant>
</xbrli:period>
</xbrli:context>
<xbrli:unit id="USD">
<xbrli:measure>iso4217:USD</xbrli:measure>
</xbrli:unit>
</ix:hidden>
</body>
</html>
When viewed in browser:
ACME Corporation
Consolidated Balance Sheet
As of December 31, 2024
(in thousands of U.S. Dollars)
Assets
Current Assets:
Cash and Cash Equivalents $5,000
Accounts Receivable $3,000
Total Assets $250,000
When extracted by XBRL processor:
<us-gaap:CashAndCashEquivalentsAtCarryingValue contextRef="AsOf2024-12-31" unitRef="USD" decimals="-3">
5000000
</us-gaap:CashAndCashEquivalentsAtCarryingValue>
<us-gaap:AccountsReceivableNetCurrent contextRef="AsOf2024-12-31" unitRef="USD" decimals="-3">
3000000
</us-gaap:AccountsReceivableNetCurrent>
<us-gaap:Assets contextRef="AsOf2024-12-31" unitRef="USD" decimals="-3">
250000000
</us-gaap:Assets>
1. Dual Purpose
2. Transformation Formats
<!-- Display: "December 31, 2024" -->
<!-- Data: "2024-12-31" -->
<ix:nonNumeric name="dei:DocumentPeriodEndDate" format="ixt:datelongus">
December 31, 2024
</ix:nonNumeric>
<!-- Display: "5,000" -->
<!-- Data: "5000000" (in base units) -->
<ix:nonFraction name="us-gaap:Cash" decimals="-3" format="ixt:numcommadot">
5,000
</ix:nonFraction>
<!-- Display: "Yes" -->
<!-- Data: "true" -->
<ix:nonNumeric name="dei:CurrentFiscalYearEndDate" format="ixt:booleantruefalse">
Yes
</ix:nonNumeric>
3. Hidden Elements
<ix:hidden>
<!-- Context definitions -->
<!-- Unit definitions -->
<!-- Footnotes -->
<!-- Technical metadata -->
</ix:hidden>
4. Continuation
<!-- Long text broken across multiple locations -->
<ix:continuation id="note1">
This is the first part of the footnote...
</ix:continuation>
<!-- Later in document -->
<ix:continuation continuedAt="note1">
...and this is the continuation.
</ix:continuation>
SEC (United States):
HMRC (United Kingdom):
ESMA (European Union):
Other Jurisdictions:
An XBRL Viewer is software that:
Types of Viewers:
┌─────────────────────────────────────────────┐
│ 1. Browser-Based Viewers │
│ ├─ JavaScript/HTML viewers │
│ ├─ Run in web browser │
│ └─ Example: SEC Inline XBRL Viewer │
│ │
│ 2. Desktop Application Viewers │
│ ├─ Native applications │
│ ├─ More features │
│ └─ Example: Arelle, Fujitsu XWand │
│ │
│ 3. Online Viewers │
│ ├─ Web services │
│ ├─ Upload and view │
│ └─ Example: XBRL Cloud, Workiva │
│ │
│ 4. Embedded Viewers │
│ ├─ Component libraries │
│ ├─ Integrate into applications │
│ └─ Example: JavaScript widgets │
└─────────────────────────────────────────────┘
The SEC provides an official inline XBRL viewer:
Features:
Example Interface:
┌─────────────────────────────────────────────────────────┐
│ SEC EDGAR Viewer [Search] │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────┬───────────────────────────┐ │
│ │ Document View │ XBRL Details │ │
│ ├────────────────────────┼───────────────────────────┤ │
│ │ │ │ │
│ │ ACME Corporation │ Selected Fact: │ │
│ │ Balance Sheet │ │ │
│ │ │ Concept: │ │
│ │ Assets │ us-gaap:Assets │ │
│ │ Cash $5,000 ←─┼─→ Value: 250000000 │ │
│ │ Receivables $3,000 │ Unit: USD │ │
│ │ Total $250,000 │ Period: 2024-12-31 │ │
│ │ │ Decimals: -3 │ │
│ │ [Click any value to │ │ │
│ │ see XBRL details] │ Calculations: │ │
│ │ │ ✓ Balance verified │ │
│ └────────────────────────┴───────────────────────────┘ │
│ │
│ Navigation: │
│ • Financial Statements │
│ ├─ Balance Sheet │
│ ├─ Income Statement │
│ └─ Cash Flow │
│ • Notes to Financial Statements │
│ ├─ Note 1: Summary of Significant Accounting │
│ └─ Note 2: Revenue Recognition │
└─────────────────────────────────────────────────────────┘
Arelle is the most widely-used open-source XBRL processor with sophisticated viewing capabilities.
Viewer Features:
1. Multiple View Modes:
├─ Facts List (all facts in document)
├─ Presentation View (structured by taxonomy)
├─ Dimensional View (breakdown by dimensions)
├─ Calculation View (with verification)
└─ Formula Results (validation outcomes)
2. Navigation:
├─ Taxonomy tree navigation
├─ Fact filtering
├─ Search across concepts
└─ Jump to related facts
3. Analysis Tools:
├─ Dimensional breakdowns
├─ Calculation checking
├─ Duplicate detection
├─ Coverage analysis
4. Export Options:
├─ HTML reports
├─ Excel spreadsheets
├─ JSON export
└─ CSV export
Approach 1: Presentation Linkbase-Driven
public class PresentationRenderer {
public HTML renderInstance(XBRLInstance instance) {
// Get presentation linkbase
PresentationLinkbase presentation =
instance.getTaxonomy().getPresentationLinkbase();
HTML html = new HTML();
// Iterate through presentation networks
for (Network network : presentation.getNetworks()) {
html.addSection(network.getRole().getDefinition());
// Render hierarchically
renderTree(network.getRootConcepts(), instance, html, 0);
}
return html;
}
private void renderTree(List<Concept> concepts,
XBRLInstance instance,
HTML html,
int level) {
for (Concept concept : concepts) {
// Get facts for this concept
List<Fact> facts = instance.getFacts(concept);
// Render concept with facts
html.addRow(
indent(level) + concept.getLabel(),
formatFacts(facts)
);
// Render children recursively
List<Concept> children = concept.getChildren();
if (!children.isEmpty()) {
renderTree(children, instance, html, level + 1);
}
}
}
}
Approach 2: Table Linkbase-Driven (for COREP/FINREP)
public class TableRenderer {
public HTML renderTable(String tableId, XBRLInstance instance) {
// Get table definition from Table Linkbase
Table table = instance.getTaxonomy()
.getTableLinkbase()
.getTable(tableId);
// Extract table structure
Axis rowAxis = table.getRowAxis();
Axis colAxis = table.getColumnAxis();
HTML html = new HTML();
html.startTable();
// Render column headers
html.startRow();
html.addCell(""); // Corner cell
for (Member col : colAxis.getMembers()) {
html.addHeader(col.getLabel());
}
html.endRow();
// Render rows
for (Member row : rowAxis.getMembers()) {
html.startRow();
html.addHeader(row.getLabel());
// Render cells
for (Member col : colAxis.getMembers()) {
Fact fact = instance.getFact(
table.getConcept(),
buildContext(row, col)
);
html.addCell(format(fact));
}
html.endRow();
}
html.endTable();
return html;
}
}
Approach 3: Custom Templates
<!-- Mustache template for balance sheet -->
<h2>{{companyName}}</h2>
<h3>Consolidated Balance Sheet</h3>
<p>As of {{reportDate}}</p>
<table>
<tr>
<th>Assets</th>
<th class="amount"></th>
</tr>
{{#assets}}
<tr>
<td style="padding-left: {{indent}}em">{{label}}</td>
<td class="amount">{{value}}</td>
</tr>
{{/assets}}
<tr class="total">
<td><strong>Total Assets</strong></td>
<td class="amount"><strong>{{totalAssets}}</strong></td>
</tr>
</table>
Open Information Model (OIM) is an abstract representation of XBRL data, independent of XML syntax.
Official Specification: OIM 1.0 (2021)
Status: Recommendation by XBRL International
Purpose:
Key Insight:
XBRL is NOT about XML syntax
XBRL is about the DATA MODEL
OIM defines the data model
XML, JSON, CSV are just syntaxes
xBRL-JSON is a JSON representation of XBRL based on OIM.
Example:
{
"documentType": "https://xbrl.org/2021/xbrl-json",
"facts": {
"us-gaap:Assets": {
"value": 250000000,
"decimals": -3,
"dimensions": {
"concept": "us-gaap:Assets",
"entity": "http://www.sec.gov/CIK/0001234567",
"period": "2024-12-31",
"unit": "USD"
}
},
"us-gaap:CashAndCashEquivalentsAtCarryingValue": {
"value": 5000000,
"decimals": -3,
"dimensions": {
"concept": "us-gaap:CashAndCashEquivalentsAtCarryingValue",
"entity": "http://www.sec.gov/CIK/0001234567",
"period": "2024-12-31",
"unit": "USD"
}
},
"us-gaap:Revenues": [
{
"value": 100000000,
"decimals": -3,
"dimensions": {
"concept": "us-gaap:Revenues",
"entity": "http://www.sec.gov/CIK/0001234567",
"period": "2024-01-01/2024-12-31",
"unit": "USD",
"us-gaap:StatementBusinessSegmentsAxis": "company:RetailSegmentMember"
}
},
{
"value": 150000000,
"decimals": -3,
"dimensions": {
"concept": "us-gaap:Revenues",
"entity": "http://www.sec.gov/CIK/0001234567",
"period": "2024-01-01/2024-12-31",
"unit": "USD",
"us-gaap:StatementBusinessSegmentsAxis": "company:CommercialSegmentMember"
}
}
]
}
}
Advantages:
xBRL-CSV is a CSV representation of XBRL, ideal for tabular data like COREP/FINREP.
Example - COREP Template C 01.00:
template,row,column,value,decimals,unit,entity,period
C_01_00,r010,c010,1500000000,-3,EUR,1234567890ABCDEFGHIJ,2024-12-31
C_01_00,r020,c010,1250000000,-3,EUR,1234567890ABCDEFGHIJ,2024-12-31
C_01_00,r030,c010,1000000000,-3,EUR,1234567890ABCDEFGHIJ,2024-12-31
C_01_00,r040,c010,250000000,-3,EUR,1234567890ABCDEFGHIJ,2024-12-31
C_01_00,r050,c010,250000000,-3,EUR,1234567890ABCDEFGHIJ,2024-12-31
Advantages:
JSON Viewers:
// Simple JavaScript viewer for xBRL-JSON
class XBRLJSONViewer {
renderFacts(xbrlJson, containerId) {
const container = document.getElementById(containerId);
const facts = xbrlJson.facts;
let html = '<table><tr><th>Concept</th><th>Value</th><th>Period</th></tr>';
for (const [concept, fact] of Object.entries(facts)) {
if (Array.isArray(fact)) {
// Multiple facts for same concept
fact.forEach(f => {
html += this.renderFactRow(concept, f);
});
} else {
html += this.renderFactRow(concept, fact);
}
}
html += '</table>';
container.innerHTML = html;
}
renderFactRow(concept, fact) {
const label = this.getLabel(concept);
const formattedValue = this.formatValue(fact.value, fact.decimals, fact.dimensions.unit);
const period = fact.dimensions.period;
return `<tr>
<td>${label}</td>
<td class="amount">${formattedValue}</td>
<td>${period}</td>
</tr>`;
}
}
CSV Viewers:
# Python script to render xBRL-CSV as HTML
import pandas as pd
def render_xbrl_csv(csv_file, template_id):
# Read CSV
df = pd.read_csv(csv_file)
# Filter for specific template
template_df = df[df['template'] == template_id]
# Pivot to table format
table = template_df.pivot(index='row', columns='column', values='value')
# Apply labels
table.index = table.index.map(get_row_label)
table.columns = table.columns.map(get_column_label)
# Render as HTML
html = table.to_html(classes=['xbrl-table'], float_format=lambda x: f'{x:,.0f}')
return html
DO:
DON'T:
Essential Features:
Nice-to-Have Features:
8. Comparison views (period-over-period)
9. Customizable templates
10. Annotation capabilities
11. Data export (Excel, JSON, CSV)
12. Collaborative features
Recommendations:
Netherlands Experiments (2008-2015):
Key Innovations:
Lessons Learned:
Global Consensus:
Inline XBRL = Standard Approach
├─ Human-readable HTML
├─ Machine-readable XBRL
├─ Single source of truth
└─ Browser-based viewing
Supporting Technologies:
Industry Practice:
public class XBRLToHTMLConverter {
public File convert(File xbrlFile, File taxonomyPackage) {
// Step 1: Load XBRL instance
XBRLInstance instance = XBRLParser.parse(xbrlFile);
// Step 2: Load taxonomy
Taxonomy taxonomy = TaxonomyLoader.load(taxonomyPackage);
instance.setTaxonomy(taxonomy);
// Step 3: Get presentation linkbase
PresentationLinkbase presentation =
taxonomy.getPresentationLinkbase();
// Step 4: Create HTML document
HTMLDocument html = new HTMLDocument();
html.setTitle(instance.getEntityName() + " - " +
instance.getDocumentType());
// Step 5: Add styles
html.addStylesheet(loadStyles());
// Step 6: Render each presentation network
for (Network network : presentation.getNetworks()) {
Section section = html.addSection();
section.setHeading(network.getRole().getDefinition());
// Render as table
Table table = renderNetwork(network, instance);
section.addTable(table);
}
// Step 7: Add footnotes
html.addFootnotes(instance.getFootnotes());
// Step 8: Save
File outputFile = new File("output.html");
html.saveTo(outputFile);
return outputFile;
}
private Table renderNetwork(Network network, XBRLInstance instance) {
Table table = new Table();
// Add columns
table.addColumn("Concept");
table.addColumn("Value", "right");
// Render recursively
renderConcepts(network.getRootConcepts(), instance, table, 0);
return table;
}
private void renderConcepts(List<Concept> concepts,
XBRLInstance instance,
Table table,
int level) {
for (Concept concept : concepts) {
Row row = table.addRow();
// Indented label
Cell labelCell = row.addCell();
labelCell.setIndent(level);
labelCell.setText(concept.getLabel());
// Value
Cell valueCell = row.addCell();
List<Fact> facts = instance.getFacts(concept);
if (!facts.isEmpty()) {
valueCell.setText(formatFact(facts.get(0)));
}
// Render children
if (concept.hasChildren()) {
renderConcepts(concept.getChildren(), instance, table, level + 1);
}
}
}
}
public class InlineXBRLGenerator {
public File generate(XBRLInstance instance, HTMLTemplate template) {
// Step 1: Load HTML template
Document doc = template.getDocument();
// Step 2: Add XBRL namespace declarations
Element html = doc.getDocumentElement();
html.setAttribute("xmlns:ix", "http://www.xbrl.org/2013/inlineXBRL");
html.setAttribute("xmlns:xbrli", "http://www.xbrl.org/2003/instance");
// ... add taxonomy namespaces
// Step 3: Add hidden header
Element body = (Element) doc.getElementsByTagName("body").item(0);
Element header = createHeader(instance);
body.insertBefore(header, body.getFirstChild());
// Step 4: Tag facts in HTML
tagFacts(doc, instance);
// Step 5: Add hidden contexts and units
Element hidden = createHiddenSection(instance);
body.appendChild(hidden);
// Step 6: Save
File output = new File("output.html");
saveDocument(doc, output);
return output;
}
private void tagFacts(Document doc, XBRLInstance instance) {
// Find text nodes containing fact values
NodeList textNodes = doc.getElementsByTagName("*");
for (int i = 0; i < textNodes.getLength(); i++) {
Element element = (Element) textNodes.item(i);
String text = element.getTextContent().trim();
// Try to match with facts
Fact fact = instance.findFactByValue(text);
if (fact != null) {
// Wrap with ix:nonFraction or ix:nonNumeric
Element ixElement = createInlineXBRLTag(fact);
element.getParentNode().replaceChild(ixElement, element);
}
}
}
}
Inline XBRL is the standard solution:
Viewers are mature:
Alternative formats available:
For Human Consumption:
For Development:
XBRL was designed for machines, not humans.
The solution is NOW standardized:
The Dutch experiments were prescient - they pioneered the approach that became the global standard.
For modern XBRL implementations:
XBRL is finally human-readable!
This document explains the human readability challenge with XBRL, the official solutions (Inline XBRL, OIM), and best practices for making XBRL accessible to humans while maintaining machine readability.