Generate an interactive supply chain dashboard for the company named in the user's request. If no ticker or company is provided, ask for one before proceeding.
Before starting, read ../data-access.md for data access methods and ../design-system.md for formatting conventions. Follow the data access detection logic and design system throughout this skill.
This skill maps the upstream (supplier) and downstream (customer) relationships for a target company, quantifying financial interdependencies in both directions. The output enables an analyst to understand: Who are the critical suppliers and customers? Where is concentration risk on both sides? Which suppliers depend heavily on this company for revenue? Which customers depend on this company's products as critical inputs? How does a shock propagate both upstream (demand shock to suppliers) and downstream (supply disruption to customers)?
Output Format
The final deliverable is a single self-contained HTML file with:
- Embedded CSS and JavaScript (no external dependencies)
- Tier-grouped Canvas network visualization — columns: Tier 3 → Tier 2 → Tier 1 → Target → Customers, with connection lines. Clickable nodes open detail overlays.
- Inventory Health Overview table — for all suppliers: RM%, WIP%, FG% of total inventory shown as stacked colored bars, plus latest total inventory value
- Supplier cards grouped by tier — Tier 1 (Critical/Sole-source), Tier 2 (Major Component), Tier 3 (Specialty) with click-to-expand detail overlays
- Detail overlays for each supplier containing:
- 10-quarter financial table (Revenue, Gross Profit, Net Income, Gross Margin %)
- 10-quarter inventory breakdown table (Raw Materials, WIP, Finished Goods, Total, RM%, WIP%, FG%)
- Canvas chart: stacked bar chart of inventory composition with Gross Margin % line overlay
- Business description and relationship to target company
- Customer cards grouped by category — Channel Partners, Enterprise/B2B, End-Market Exposure — with click-to-expand detail overlays matching supplier depth
- Detail overlays for each customer containing:
- 10-quarter financial table (Revenue, Gross Profit, Net Income, Gross Margin %)
- 10-quarter inventory breakdown table (Raw Materials, WIP, Finished Goods, Total, RM%, WIP%, FG%)
- Canvas chart: stacked bar chart of inventory composition with Gross Margin % line overlay
- Business description and relationship to target company
- Upstream Shock Analysis section — narrative analysis of how a demand/supply shock to the target company ripples upstream through the supplier chain, with an impact matrix table (Revenue Impact, Margin Impact, Overall Risk per supplier)
- Downstream Shock Analysis section — narrative analysis of how a supply disruption at the target company ripples downstream through the customer chain, with an impact matrix table (Input Criticality, Switching Cost, Revenue at Risk, Overall Disruption Risk per customer)
- All financial figures hyperlinked to Daloopa source citations
- A "Download as PDF" button (uses
window.print())
DOM Safety: All JavaScript MUST use createElement() + textContent + appendChild() for DOM construction. NEVER use innerHTML, outerHTML, or any HTML-string injection methods. Use helper functions like ce(tag), ca(el, attrs), cA(parent, children) to keep code compact.
Save to reports/{TICKER}_supply-chain.html and open it with open.
RESEARCH WORKFLOW
This is a multi-phase research process. Each phase builds on the previous one. Maximize parallelism across independent API calls.
Phase 1: Target Company Identification
- Use
discover_companies with the ticker symbol to get the company_id, latest_calendar_quarter, and latest_fiscal_quarter. Note the firm name for report attribution (default: "Daloopa") — see ../data-access.md Section 4.5.
- Pull key financials for the target company:
- Use
discover_company_series with keywords: ["revenue", "cost of goods", "gross profit", "operating income", "net income", "total cost"]
- Calculate 4 quarters backward from
latest_calendar_quarter. Use get_company_fundamentals for those periods to get TTM figures.
- Note the target company's total COGS / cost of revenue (TTM) — this is the denominator for supplier % calculations.
Phase 2: Supplier Identification
Run these concurrently to build a comprehensive supplier list:
2a. Daloopa Document Search:
- Search keywords: ["supplier", "vendor", "purchase", "procurement"] across last 2-4 quarters
- Search keywords: ["supply agreement", "supply chain", "manufacturing"] across last 2-4 quarters
- Search keywords: ["sole source", "single source", "key supplier"] across last 2-4 quarters
- Search keywords: ["concentration", "significant supplier"] across last 2-4 quarters
- Search the company's 10-K specifically for supplier disclosures
2b. Web Research:
"[TICKER] [company name] key suppliers list 2025 2026" — supplier identification
"[TICKER] supply chain analysis suppliers" — analyst/industry reports
"[TICKER] 10-K supplier disclosure" — SEC filing analysis
"[company name] supply chain map" — industry supply chain maps
"[company name] supplier concentration risk" — risk analysis
"[company name] who manufactures for [company]" — manufacturing partners
"[company name] component suppliers" — component-level supply chain
2c. Industry-Specific Supplier Research:
For each industry, search for the known critical supply chain relationships:
- Tech/Hardware: semiconductor foundries (TSMC, Samsung), display (Samsung, LG, BOE), memory (Samsung, SK Hynix, Micron), sensors/cameras (Sony), glass (Corning), connectors (Amphenol), batteries (CATL, LG Energy), PCB/assembly (Foxconn/Hon Hai, Pegatron, Luxshare)
- Automotive: battery (CATL, Panasonic, LG Energy), semiconductors (Infineon, NXP, ON Semi, TI), steel (Nippon, POSCO), tires (Michelin, Bridgestone), glass (AGC, Saint-Gobain)
- Pharma: CDMOs (Lonza, Samsung Biologics, Catalent), API suppliers, packaging, distribution
- Retail: brand suppliers, logistics (FedEx, UPS), packaging
- Energy: equipment (Baker Hughes, Schlumberger), pipe (Tenaris), chemicals
Phase 3: Supplier Financial Analysis
For each identified supplier (aim for 8-15 key suppliers):
- Discover the supplier using
discover_companies with their ticker
- Pull key financials from Daloopa:
discover_company_series with keywords: ["revenue", "net income", "gross margin", "operating margin"]
get_company_fundamentals for the same 4 calendar quarters as the target company
- Determine revenue concentration:
- Search Daloopa documents for the supplier: keywords ["[target company name]", "customer", "concentration"]
- Web search:
"[supplier name] [target company] revenue percentage customer"
- Web search:
"[supplier name] 10-K customer concentration"
- Many suppliers disclose their top customers in 10-K filings — look for "customers that accounted for 10% or more of revenue"
- Source quality (MANDATORY): these are factual claims — accept them only from primary sources (SEC filings, IR pages, press releases, transcripts) or Tier-1 financial press (Reuters, Bloomberg, WSJ, FT) per
../data-access.md Section 2.5. Never source concentration figures from Yahoo Finance editorial, Benzinga, Seeking Alpha, Motley Fool, Zacks, TipRanks, StockTwits, Reddit, or similar aggregators/blogs; if a figure only appears there, corroborate it or flag it as unverified.
- Determine COGS attribution (what % of target's costs is this supplier):
- This is often estimated. Use logic like:
- If Apple's COGS is ~$200B TTM and TSMC's revenue from Apple is ~$70B, then TSMC = ~35% of COGS
- Cite the source of each estimate (analyst report, 10-K disclosure, industry research)
- Flag when this is an estimate vs. a disclosed figure
- Business & product description: What does this supplier provide? Be specific (e.g., "5nm/3nm chip fabrication for A-series and M-series SoCs" not just "semiconductors")
Phase 3b: Inventory & 10-Quarter Financial Data
For the target company AND each identified supplier (8-15 companies), pull 10 quarters of data:
- Discover inventory series using
discover_company_series with keywords: ["raw material", "work in process", "finished good", "inventory", "inventories"]
- Look for separate RM, WIP, FG series, plus a total inventory series
- Some companies report "carrying amount" breakdowns — use those for RM/WIP/FG splits
- Discover financial series using
discover_company_series with keywords: ["revenue", "gross profit", "net income", "gross margin"]
- Pull 10 quarters using
get_company_fundamentals. Calculate 10 quarters backward from latest_calendar_quarter.
- Example: if latest is Q4'25, pull ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2", "2025Q3", "2025Q4"]
- Compute inventory composition: For each quarter, calculate RM%, WIP%, FG% of total inventory
- High WIP% can signal production bottlenecks
- Rising FG% can signal demand weakness
- Rising RM% can signal supply hoarding or procurement buildup
- Handle missing data gracefully: Some suppliers may not report full inventory breakdowns — show what's available and note gaps
- Multi-currency handling: Note the reporting currency for each company (USD, NTD, KRW, EUR, etc.) and display with appropriate units (e.g., "NTD B" for TSMC, "KRW T" for Samsung)
Run inventory and financial series pulls in parallel across all companies.
Phase 4: Customer / Downstream Identification
The downstream side requires the same research rigor as the upstream side. Run these concurrently to build a comprehensive customer list:
4a. Daloopa Document Search (target company filings):
- Search keywords: ["customer", "contract", "agreement", "channel"] across last 2-4 quarters
- Search keywords: ["customer concentration", "significant customer", "major customer"] across last 2-4 quarters — many companies disclose customers >10% of revenue
- Search keywords: ["distribution", "retail partner", "reseller", "licensee"] across last 2-4 quarters
- Search keywords: ["accounts receivable", "contract asset", "deferred revenue"] — concentration in A/R often reveals customer dependency even when not explicitly named
- Search the company's 10-K specifically for customer disclosures and segment end-market breakdowns
4b. Web Research:
"[TICKER] [company name] major customers list" — direct customer identification
"[TICKER] customer concentration revenue breakdown" — analyst/industry reports
"[TICKER] 10-K customer disclosure" — SEC filing analysis
"[company name] who buys from [company name]" — downstream identification
"[company name] channel partners distributors" — channel analysis
"[company name] end market exposure" — end-market breakdown
4c. Industry-Specific Customer Research:
For each industry, search for the known critical downstream relationships:
- Semiconductors: Which OEMs depend on these chips? (e.g., NVDA → hyperscalers MSFT/AMZN/GOOG, QCOM → smartphone OEMs AAPL/Samsung, AVGO → networking OEMs Cisco/Arista)
- Components/Materials: Which assemblers or product companies use these inputs? (e.g., Corning → AAPL/Samsung for glass, TSMC → fabless semis NVDA/AMD/AAPL)
- Software/Platform: Who builds on this platform? (e.g., MSFT Azure → ISVs, AAPL App Store → developers, Salesforce → SI partners)
- Consumer products: Channel partners (carriers, retailers, e-commerce) and enterprise customers
- Industrial/B2B: End-market verticals (auto, aerospace, medical, telecom)
- Pharma/Biotech: Distributors (McKesson, AmerisourceBergen), PBMs, hospital systems
4d. Customer Financial Analysis:
For each identified customer (aim for 6-10 key customers):
- Discover the customer using
discover_companies with their ticker
- Pull key financials from Daloopa:
discover_company_series with keywords: ["revenue", "net income", "gross margin", "cost of goods", "operating income"]
get_company_fundamentals for the same 4 calendar quarters as the target company
- Determine revenue attribution (what % of target's revenue comes from this customer):
- Search Daloopa documents for the target company: keywords ["[customer name]", "customer", "concentration", "accounts receivable"]
- Web search:
"[target company] [customer name] revenue percentage"
- Web search:
"[target company] 10-K customer concentration"
- Many companies disclose customers that account for >10% of revenue in their 10-K
- Source quality (MANDATORY): same rule as the supplier analysis — attribution figures only from primary sources or Tier-1 financial press per
../data-access.md Section 2.5; never from Yahoo Finance editorial, Benzinga, Seeking Alpha, Motley Fool, Zacks, TipRanks, StockTwits, Reddit, or similar aggregators/blogs. Corroborate or flag as unverified.
- Determine input criticality (what % of customer's COGS comes from target):
- This is the inverse of the supplier analysis: if the target sells $X to a customer with $Y in COGS, then input share = X/Y
- Search for:
"[customer name] [target company] supplier dependence" or "[customer name] key inputs components"
- Flag whether the target's product is a critical, hard-to-substitute input vs. a commodity with alternatives
- Assess switching costs: Can the customer easily replace the target company's product?
- High switching cost: Custom/proprietary integration, long qualification cycles, regulatory requirements (e.g., TSMC's process node — customers can't easily switch foundries mid-design)
- Medium switching cost: Some integration required but alternatives exist with 6-12 month transition
- Low switching cost: Commodity input, multiple qualified alternatives, short switching timeline
- Business & product description: What does the target supply to this customer? Be specific (e.g., "A17 Pro and M4 SoCs fabricated on TSMC's 3nm process" not just "chips")
Phase 4e: Customer Inventory & 10-Quarter Financial Data
Mirror Phase 3b for the customer side. For each identified customer (6-10 companies), pull 10 quarters of data:
- Discover inventory series using
discover_company_series with keywords: ["raw material", "work in process", "finished good", "inventory", "inventories"]
- Look for separate RM, WIP, FG series, plus a total inventory series
- Discover financial series using
discover_company_series with keywords: ["revenue", "gross profit", "net income", "gross margin"]
- Pull 10 quarters using
get_company_fundamentals with the same 10 calendar quarters as the target company and suppliers (calculated from latest_calendar_quarter)
- Compute inventory composition: RM%, WIP%, FG% of total inventory
- For customers, inventory signals have different meaning:
- Rising RM% at a customer → they're stocking up on target company's inputs (bullish for target's near-term revenue, but may mean future destocking)
- Falling RM% → customer is drawing down inventory, may signal reduced orders ahead
- Rising FG% at a customer → demand for the customer's end product is softening, which will flow back upstream to the target
- Handle missing data gracefully: Some customers may not report inventory breakdowns — show what's available
- Multi-currency handling: Same as suppliers — note reporting currency
Run customer inventory and financial series pulls in parallel, and in parallel with supplier pulls where possible.
Phase 5: Tier 2 Supplier Research
For the top 3-5 most important Tier 1 suppliers, repeat a lighter version of Phase 2-3:
- Identify their key suppliers (Tier 2 to the original target)
- Pull basic financials
- Determine what they supply and rough revenue/cost relationships
- This enables the "drill deeper" functionality in the dashboard
Phase 6: Data Assembly & Synthesis
Before writing HTML, organize all data into this structure:
TARGET COMPANY:
- Name, ticker, description
- TTM Revenue, COGS, Gross Profit, Net Income, Gross Margin, Op Margin
- Market cap, stock price (from web)
TIER 1 SUPPLIERS (sorted by estimated % of target COGS, descending):
For each:
- Name, ticker, description
- What they supply (specific products/components)
- Estimated % of target company COGS (with source/logic)
- % of supplier revenue from target company (with source)
- TTM Revenue, Net Income, Gross Margin
- Market cap
- Relationship summary (sole source? multi-source? critical?)
- Their key suppliers (Tier 2) if researched
- 10-quarter financials: Revenue, Gross Profit, Net Income, GM% (with Daloopa citation IDs)
- 10-quarter inventory: RM, WIP, FG, Total, RM%, WIP%, FG% (with Daloopa citation IDs)
- Reporting currency and unit (e.g., USD $M, NTD B, KRW T)
TIER 1 CUSTOMERS (sorted by estimated % of target revenue, descending):
For each:
- Name, ticker, description
- What target company supplies to them (specific products/services)
- Estimated % of target revenue from this customer (with source/logic)
- Estimated % of customer COGS from target (input criticality, with source)
- Switching cost assessment (High/Medium/Low with reasoning)
- TTM Revenue, COGS, Net Income, Gross Margin
- Market cap
- Relationship summary (exclusive? multi-source? long-term contract? spot?)
- 10-quarter financials: Revenue, Gross Profit, Net Income, GM% (with Daloopa citation IDs)
- 10-quarter inventory: RM, WIP, FG, Total, RM%, WIP%, FG% (with Daloopa citation IDs)
- Reporting currency and unit (e.g., USD $M, EUR M, JPY B)
TIER 2 CUSTOMERS (for top 3-5 Tier 1 customers — who do THEY sell to?):
For each Tier 1 customer, their key customers with basic data
This traces the value chain forward: Target → Customer → End Market
TIER 2 SUPPLIERS (for top 3-5 Tier 1 suppliers):
For each Tier 1 supplier, their key suppliers with basic data
Phase 6b: Upstream Shock Analysis (Demand Shock → Suppliers)
Prepare a narrative analysis of how a demand shock at the target company would ripple upstream through the supplier chain:
Classify each supplier by dependency level:
- High dependency: Target company is >20% of supplier's revenue → severe impact from demand shock
- Moderate dependency: Target is 10-20% of revenue → meaningful but manageable impact
- Low dependency: Target is <10% of revenue → diversified, minimal direct impact
Assess shock propagation for each supplier:
- Revenue Impact (High/Medium/Low): Based on % of revenue from target
- Margin Impact (High/Medium/Low): Based on operating leverage, fixed costs, ability to find replacement demand
- Inventory Risk: Suppliers with high FG% are more exposed to demand shocks; those with high RM% face supply-side risk
- Substitutability: Can the target switch to alternatives? Can the supplier find other customers?
Build an impact matrix table with columns: Supplier, Tier, Revenue Dependency, Revenue Impact, Margin Impact, Overall Risk
Write narrative sections:
- "Most Exposed Suppliers" — 2-3 paragraphs on suppliers facing highest risk
- "Resilient Suppliers" — suppliers with diversified revenue bases
- "Second-Order Effects" — how Tier 2 suppliers would be indirectly affected
- "Key Monitoring Metrics" — what an analyst should watch (inventory days, order backlog, etc.)
Phase 6c: Downstream Shock Analysis (Supply Disruption → Customers)
Prepare a narrative analysis of how a supply disruption at the target company (production halt, quality issue, capacity constraint, export ban) would ripple downstream through the customer chain:
Classify each customer by input criticality:
- Critical input: Target's product is a key component with no drop-in replacement; disruption halts customer production (e.g., TSMC to Apple — no alternative foundry for A-series chips)
- Important input: Target is a significant but not sole supplier; customer can partially substitute with 3-6 month lead time
- Supplementary input: Target provides a non-critical input; customer has multiple qualified alternatives
Assess downstream disruption for each customer:
- Input Criticality (High/Medium/Low): How essential is the target's product to the customer's operations?
- Switching Cost (High/Medium/Low): How long and expensive to qualify an alternative? Are there contractual lock-ins?
- Revenue at Risk: What portion of the customer's revenue depends on products that use the target's inputs?
- Inventory Buffer: Does the customer hold significant RM inventory of the target's product? How many weeks/months of supply?
- Alternative Sources: Who else could supply this? What's the capacity gap?
Build a downstream impact matrix table with columns: Customer, Category, Input Criticality, Switching Cost, Revenue at Risk, Inventory Buffer, Overall Disruption Risk
Write narrative sections:
- "Most Vulnerable Customers" — customers who would face production disruption or revenue loss
- "Customers with Alternatives" — those who can substitute away from the target
- "Pricing Power Implications" — if the target faces a supply constraint, which customers have the leverage to secure allocation vs. which get cut first?
- "Channel Inventory Signals" — what customer inventory levels (especially RM%) tell you about near-term order patterns for the target company
- "Second-Order Downstream Effects" — how end consumers or Tier 2 customers would be affected
HTML TEMPLATE & DESIGN SYSTEM
Start from the HTML Report Template in ../design-system.md (copy the full <style> block). Then add the following additional CSS for interactive dashboard components. Use the design system's color palette throughout.
Design Principles
- Follow
../design-system.md for color palette, typography, and table conventions
- Information density: Show data compactly but with clear hierarchy
- Interactive but not flashy: Smooth transitions, click-to-expand, no animations for animation's sake
Core CSS
Start with the full CSS from ../design-system.md, then append these dashboard-specific styles:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>[TICKER] Supply Chain Dashboard</title>
<style>
/* === PASTE FULL CSS FROM design-system.md HTML Report Template HERE === */
/* === DASHBOARD-SPECIFIC EXTENSIONS BELOW === */
@media print {
.no-print { display: none !important; }
.interactive { pointer-events: none; }
@page { margin: 0.5in; size: landscape; }
}
:root {
/* Extended palette for dashboard components — supplements design-system.md vars */
--bg: var(--light-gray);
--surface: #ffffff;
--border: var(--mid-gray);
--border-light: var(--light-gray);
--text-primary: var(--near-black);
--text-secondary: var(--dark-gray);
--text-tertiary: #8a8a85;
--accent: var(--steel-blue);
--green-bg: #f0f9f2;
--red-bg: #fef2f2;
--amber: #92600a;
--amber-bg: #fefce8;
--blue-bg: #eff6ff;
--node-supplier: var(--mid-gray);
--node-customer: #dde8f0;
--node-target: var(--navy);
--sans: "Segoe UI", -apple-system, BlinkMacSystemFont, Arial, sans-serif;
--mono: "SF Mono", "Fira Code", "Fira Mono", "Roboto Mono", monospace;
}
/* Layout */
.page-header {
background: var(--surface);
border-bottom: 3px solid var(--navy);
padding: 24px 40px 16px;
}
.page-header h1 {
font-size: 28px;
font-weight: 700;
color: var(--navy);
letter-spacing: -0.5px;
line-height: 1.2;
}
.page-header .subtitle {
font-size: 14px;
color: var(--text-secondary);
margin-top: 4px;
}
.page-header .dateline {
font-size: 12px;
color: var(--text-tertiary);
margin-top: 8px;
font-family: var(--mono);
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 24px 40px;
}
/* Section Headers */
h2 {
font-family: var(--sans);
font-size: 20px;
font-weight: 700;
margin: 32px 0 16px;
padding-bottom: 6px;
border-bottom: 1px solid var(--mid-gray);
letter-spacing: -0.3px;
color: var(--navy);
}
h3 {
font-family: var(--sans);
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.8px;
color: var(--steel-blue);
margin: 20px 0 10px;
}
/* KPI Bar */
.kpi-bar {
display: flex;
gap: 0;
border: 1px solid var(--border);
border-radius: 6px;
overflow: hidden;
background: var(--surface);
margin: 16px 0;
}
.kpi-item {
flex: 1;
padding: 12px 16px;
border-right: 1px solid var(--border-light);
text-align: center;
}
.kpi-item:last-child { border-right: none; }
.kpi-label {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-tertiary);
font-weight: 600;
}
.kpi-value {
font-size: 18px;
font-weight: 700;
margin-top: 2px;
font-variant-numeric: tabular-nums;
}
.kpi-sub {
font-size: 11px;
color: var(--text-tertiary);
margin-top: 1px;
}
/* Supply Chain Visualization */
.chain-view {
display: flex;
gap: 24px;
align-items: flex-start;
margin: 20px 0;
overflow-x: auto;
padding-bottom: 16px;
}
.chain-column {
min-width: 280px;
flex-shrink: 0;
}
.chain-column-header {
font-family: var(--sans);
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
color: var(--text-tertiary);
margin-bottom: 12px;
padding-bottom: 6px;
border-bottom: 1px solid var(--border);
text-align: center;
}
.chain-arrow {
display: flex;
align-items: center;
justify-content: center;
color: var(--text-tertiary);
font-size: 24px;
min-width: 40px;
padding-top: 40px;
flex-shrink: 0;
}
/* Company Cards */
.company-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 14px 16px;
margin-bottom: 10px;
cursor: pointer;
transition: border-color 0.15s, box-shadow 0.15s;
}
.company-card:hover {
border-color: var(--text-secondary);
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
}
.company-card.target-card {
background: var(--navy);
color: white;
border-color: var(--navy);
}
.company-card.target-card .card-ticker { color: rgba(255,255,255,0.7); }
.company-card.target-card .card-metric-label { color: rgba(255,255,255,0.5); }
.company-card.target-card .card-metric-value { color: white; }
.company-card.target-card .card-desc { color: rgba(255,255,255,0.7); }
.company-card.expanded { border-color: var(--steel-blue); box-shadow: 0 2px 12px rgba(74,111,165,0.15); }
.company-card.supplier-card { border-left: 3px solid var(--node-supplier); }
.company-card.customer-card { border-left: 3px solid var(--node-customer); }
.card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.card-name {
font-family: var(--sans);
font-size: 16px;
font-weight: 700;
line-height: 1.2;
}
.card-ticker {
font-family: var(--mono);
font-size: 11px;
color: var(--text-tertiary);
margin-top: 2px;
}
.card-badge {
font-size: 10px;
font-weight: 700;
padding: 2px 8px;
border-radius: 3px;
white-space: nowrap;
}
.badge-pct-high { background: var(--red-bg); color: var(--red); }
.badge-pct-med { background: var(--amber-bg); color: var(--amber); }
.badge-pct-low { background: var(--green-bg); color: var(--green); }
.card-supplies {
font-size: 12px;
color: var(--text-secondary);
margin-top: 6px;
line-height: 1.4;
}
.card-metrics {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 8px;
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid var(--border-light);
}
.card-metric-label {
font-size: 9px;
text-transform: uppercase;
letter-spacing: 0.3px;
color: var(--text-tertiary);
}
.card-metric-value {
font-size: 13px;
font-weight: 700;
font-variant-numeric: tabular-nums;
}
.card-desc {
font-size: 12px;
color: var(--text-secondary);
margin-top: 8px;
line-height: 1.45;
}
/* Expanded Detail Panel */
.detail-panel {
display: none;
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid var(--border-light);
}
.company-card.expanded .detail-panel { display: block; }
.detail-section {
margin-bottom: 14px;
}
.detail-section h4 {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-tertiary);
margin-bottom: 6px;
}
.relationship-bar {
height: 8px;
background: var(--border-light);
border-radius: 4px;
overflow: hidden;
margin: 4px 0;
}
.relationship-fill {
height: 100%;
border-radius: 4px;
transition: width 0.3s;
}
.fill-red { background: var(--red); }
.fill-amber { background: var(--amber); }
.fill-green { background: var(--green); }
.fill-blue { background: var(--accent); }
/* Drill-down button */
.drill-btn {
display: inline-block;
font-size: 11px;
font-weight: 600;
color: var(--accent);
cursor: pointer;
padding: 4px 0;
border: none;
background: none;
font-family: var(--sans);
}
.drill-btn:hover { text-decoration: underline; }
/* Concentration Table */
.conc-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
margin: 12px 0;
}
.conc-table th {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-tertiary);
font-weight: 600;
text-align: left;
padding: 6px 10px;
border-bottom: 2px solid var(--border);
background: var(--bg);
}
.conc-table th:not(:first-child) { text-align: right; }
.conc-table td {
padding: 8px 10px;
border-bottom: 1px solid var(--border-light);
font-variant-numeric: tabular-nums;
}
.conc-table td:not(:first-child) { text-align: right; }
.conc-table tr:hover { background: var(--blue-bg); }
.conc-table .row-total {
font-weight: 700;
border-top: 2px solid var(--border);
background: var(--bg);
}
/* Risk indicator */
.risk-tag {
display: inline-block;
font-size: 10px;
font-weight: 700;
padding: 1px 6px;
border-radius: 3px;
}
.risk-high { background: var(--red-bg); color: var(--red); }
.risk-med { background: var(--amber-bg); color: var(--amber); }
.risk-low { background: var(--green-bg); color: var(--green); }
/* Tabs for switching views */
.tab-bar {
display: flex;
gap: 0;
border-bottom: 2px solid var(--border);
margin-bottom: 20px;
}
.tab {
padding: 10px 20px;
font-size: 13px;
font-weight: 600;
color: var(--text-tertiary);
cursor: pointer;
border-bottom: 2px solid transparent;
margin-bottom: -2px;
transition: color 0.15s, border-color 0.15s;
font-family: var(--sans);
background: none;
border-top: none;
border-left: none;
border-right: none;
}
.tab:hover { color: var(--text-primary); }
.tab.active {
color: var(--text-primary);
border-bottom-color: var(--text-primary);
}
.tab-content { display: none; }
.tab-content.active { display: block; }
/* Methodology / Source Notes */
.methodology-box {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 6px;
padding: 16px 20px;
margin: 16px 0;
font-size: 12px;
color: var(--text-secondary);
line-height: 1.5;
}
.methodology-box h4 {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-tertiary);
margin-bottom: 8px;
}
/* Links & References */
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
.source-tag {
font-size: 9px;
color: var(--text-tertiary);
font-style: italic;
}
/* Footer */
.page-footer {
margin-top: 40px;
padding: 16px 0;
border-top: 3px solid var(--navy);
font-size: 11px;
color: var(--text-tertiary);
text-align: center;
}
/* Print button */
.dl-btn {
display: inline-block;
padding: 10px 24px;
background: var(--navy);
color: white;
border: none;
border-radius: 5px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
font-family: var(--sans);
}
.dl-btn:hover { background: var(--steel-blue); }
/* Two-column layout */
.two-col {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
@media (max-width: 800px) {
.two-col { grid-template-columns: 1fr; }
.chain-view { flex-direction: column; }
.chain-arrow { transform: rotate(90deg); padding-top: 0; }
}
</style>
</head>
Core JavaScript Pattern
The dashboard uses vanilla JavaScript for interactivity. Include these functions in a <script> tag at the end of the body:
<script>
// Tab switching
function switchTab(tabId) {
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
document.querySelector(`[data-tab="${tabId}"]`).classList.add('active');
document.getElementById(tabId).classList.add('active');
}
// Card expand/collapse
function toggleCard(cardId) {
const card = document.getElementById(cardId);
card.classList.toggle('expanded');
}
// Navigate to tier 2 view for a specific supplier
function drillDown(companyTicker) {
// Switch to the tier-2 tab and scroll to the relevant section
switchTab('tier2');
const section = document.getElementById('tier2-' + companyTicker);
if (section) {
section.scrollIntoView({ behavior: 'smooth', block: 'start' });
section.style.outline = '2px solid var(--accent)';
setTimeout(() => { section.style.outline = 'none'; }, 2000);
}
}
// Initialize
document.addEventListener('DOMContentLoaded', () => {
// Set first tab active
const firstTab = document.querySelector('.tab');
if (firstTab) firstTab.click();
});
</script>
DOCUMENT STRUCTURE
The HTML document has these sections. Every section is mandatory.
Section 1: Print Button Bar
<div class="no-print" style="text-align:center; padding:16px; background:var(--surface); border-bottom:1px solid var(--border);">
<button class="dl-btn" as PDF</button>
<span style="font-size:12px; color:var(--text-tertiary); margin-left:12px;">or Cmd+P → Save as PDF</span>
</div>
Section 2: Page Header
<div class="page-header">
<h1>[TICKER] — Supply Chain Map</h1>
<div class="subtitle">[Full Company Name] · Interactive Supply Chain Analysis</div>
<div class="dateline">Prepared [Date] · Data sourced from <a href="https://daloopa.com">Daloopa</a> · TTM through [Latest Quarter]</div>
</div>
Section 3: Target Company KPI Bar
Show 6 KPIs for the target company:
<div class="container">
<div class="kpi-bar">
<div class="kpi-item"><div class="kpi-label">TTM Revenue</div><div class="kpi-value">$XXB</div></div>
<div class="kpi-item"><div class="kpi-label">TTM COGS</div><div class="kpi-value">$XXB</div></div>
<div class="kpi-item"><div class="kpi-label">Gross Margin</div><div class="kpi-value">XX.X%</div></div>
<div class="kpi-item"><div class="kpi-label">Suppliers Mapped</div><div class="kpi-value">XX</div></div>
<div class="kpi-item"><div class="kpi-label">Top 5 = % of COGS</div><div class="kpi-value">~XX%</div></div>
<div class="kpi-item"><div class="kpi-label">Key Customers</div><div class="kpi-value">XX</div></div>
</div>
Section 4: Page Layout
The dashboard uses a single scrollable page (no tabs) with the following vertical order:
- KPI bar (target company overview)
- Canvas network visualization (full chain: Tier 3 → Tier 2 → Tier 1 → Target → Customers → Tier 2 Customers)
- Inventory Health Overview table (suppliers AND customers)
- Supplier cards grouped by tier
- Customer cards grouped by category
- Upstream Shock Analysis (demand shock → suppliers, narrative + impact matrix)
- Downstream Shock Analysis (supply disruption → customers, narrative + impact matrix)
- Concentration Analysis summary (both upstream and downstream)
- Footer
Each supplier and customer card is clickable — opening a full-screen detail overlay with 10-quarter financials, inventory tables, and Canvas charts. The overlay is dismissed with × or backdrop click.
Section 5: Canvas Network Visualization
Replace the HTML card-based chain view with a Canvas-based tier-grouped network:
- Use a
<canvas> element spanning the full container width, ~420px height
- Column layout: Tier 3 (left) → Tier 2 → Tier 1 → Target (center) → Customers (right)
- Draw each company as a rounded rectangle node with ticker label
- Draw connection lines (bezier curves or straight lines) between related nodes
- Color-code by tier: Target = navy (#1B2A4A), Tier 1 = steel blue (#4A6FA5), Tier 2 = gold (#C5A55A), Tier 3 = dark gray (#6C757D), Customers = mid gray (#E9ECEF)
- Clickable nodes: Track click coordinates with a
click event listener on the canvas, determine which node was clicked via hit-testing, then open the detail overlay for that company
- Column headers ("TIER 1", "TIER 2", "TARGET", etc.) drawn as text above each column
- Responsive: redraw on
window.resize
// Example network drawing function pattern:
function drawNetwork() {
const cv = document.getElementById('networkCanvas');
const ctx = cv.getContext('2d');
cv.width = cv.parentElement.clientWidth;
cv.height = 420;
ctx.clearRect(0, 0, cv.width, cv.height);
// Define columns: x positions for each tier
const cols = {
tier3: cv.width * 0.08,
tier2: cv.width * 0.28,
tier1: cv.width * 0.48,
target: cv.width * 0.68,
customers: cv.width * 0.88
};
// Draw column headers, nodes, and connection lines
// Store node positions for hit-testing on click
}
Section 5b: Inventory Health Overview
Below the network, add an Inventory Health Overview table showing all suppliers AND customers:
| Company | Ticker | Role | Total Inventory | RM% | WIP% | FG% | Composition Bar |
- The "Role" column shows "Supplier T1", "Supplier T2", "Customer", or "Target"
- The "Composition Bar" column renders a stacked horizontal bar (RM = blue, WIP = amber, FG = green) using inline CSS
background: linear-gradient(...)
- Sort by total inventory descending or by FG% descending (highest FG% = most demand-shock exposure)
- Include the target company at the top of the table, then suppliers, then customers
- Each inventory value must link to its Daloopa citation
- Analytical note: For suppliers, rising FG% signals demand weakness from the target. For customers, rising RM% signals stockpiling of the target's inputs (bullish near-term, potential destocking risk later). Falling RM% at customers signals reduced orders ahead.
Section 5c: Supplier Cards by Tier
Below the inventory overview, render supplier cards grouped under tier headings:
── TIER 1 · Critical / Sole-Source ──────
[Card: TSMC] [Card: Samsung] [Card: Broadcom] ...
── TIER 2 · Major Component ─────────────
[Card: Qualcomm] [Card: Skyworks] [Card: TXN] ...
── TI
…(truncated)
1---2name: supply-chain3description: Interactive supply chain dashboard mapping suppliers, customers, and financial interdependencies4---56Generate an interactive supply chain dashboard for the company named in the user's request. If no ticker or company is provided, ask for one before proceeding.78**Before starting, read `../data-access.md` for data access methods and `../design-system.md` for formatting conventions.** Follow the data access detection logic and design system throughout this skill.910This skill maps the upstream (supplier) and downstream (customer) relationships for a target company, quantifying financial interdependencies in both directions. The output enables an analyst to understand: Who are the critical suppliers and customers? Where is concentration risk on both sides? Which suppliers depend heavily on this company for revenue? Which customers depend on this company's products as critical inputs? How does a shock propagate both upstream (demand shock to suppliers) and downstream (supply disruption to customers)?1112## Output Format1314The final deliverable is a **single self-contained HTML file** with:15- Embedded CSS and JavaScript (no external dependencies)16- **Tier-grouped Canvas network visualization** — columns: Tier 3 → Tier 2 → Tier 1 → Target → Customers, with connection lines. Clickable nodes open detail overlays.17- **Inventory Health Overview table** — for all suppliers: RM%, WIP%, FG% of total inventory shown as stacked colored bars, plus latest total inventory value18- **Supplier cards grouped by tier** — Tier 1 (Critical/Sole-source), Tier 2 (Major Component), Tier 3 (Specialty) with click-to-expand detail overlays19- **Detail overlays** for each supplier containing:20 - 10-quarter financial table (Revenue, Gross Profit, Net Income, Gross Margin %)21 - 10-quarter inventory breakdown table (Raw Materials, WIP, Finished Goods, Total, RM%, WIP%, FG%)22 - Canvas chart: stacked bar chart of inventory composition with Gross Margin % line overlay23 - Business description and relationship to target company24- **Customer cards grouped by category** — Channel Partners, Enterprise/B2B, End-Market Exposure — with click-to-expand detail overlays matching supplier depth25- **Detail overlays** for each customer containing:26 - 10-quarter financial table (Revenue, Gross Profit, Net Income, Gross Margin %)27 - 10-quarter inventory breakdown table (Raw Materials, WIP, Finished Goods, Total, RM%, WIP%, FG%)28 - Canvas chart: stacked bar chart of inventory composition with Gross Margin % line overlay29 - Business description and relationship to target company30- **Upstream Shock Analysis** section — narrative analysis of how a demand/supply shock to the target company ripples upstream through the supplier chain, with an impact matrix table (Revenue Impact, Margin Impact, Overall Risk per supplier)31- **Downstream Shock Analysis** section — narrative analysis of how a supply disruption at the target company ripples downstream through the customer chain, with an impact matrix table (Input Criticality, Switching Cost, Revenue at Risk, Overall Disruption Risk per customer)32- All financial figures hyperlinked to Daloopa source citations33- A "Download as PDF" button (uses `window.print()`)3435**DOM Safety**: All JavaScript MUST use `createElement()` + `textContent` + `appendChild()` for DOM construction. NEVER use `innerHTML`, `outerHTML`, or any HTML-string injection methods. Use helper functions like `ce(tag)`, `ca(el, attrs)`, `cA(parent, children)` to keep code compact.3637Save to `reports/{TICKER}_supply-chain.html` and open it with `open`.3839---4041## RESEARCH WORKFLOW4243This is a multi-phase research process. Each phase builds on the previous one. Maximize parallelism across independent API calls.4445### Phase 1: Target Company Identification46471. Use `discover_companies` with the ticker symbol to get the `company_id`, `latest_calendar_quarter`, and `latest_fiscal_quarter`. Note the firm name for report attribution (default: "Daloopa") — see `../data-access.md` Section 4.5.482. Pull key financials for the target company:49 - Use `discover_company_series` with keywords: ["revenue", "cost of goods", "gross profit", "operating income", "net income", "total cost"]50 - Calculate 4 quarters backward from `latest_calendar_quarter`. Use `get_company_fundamentals` for those periods to get TTM figures.513. Note the target company's total COGS / cost of revenue (TTM) — this is the denominator for supplier % calculations.5253### Phase 2: Supplier Identification5455Run these concurrently to build a comprehensive supplier list:5657**2a. Daloopa Document Search:**58- Search keywords: ["supplier", "vendor", "purchase", "procurement"] across last 2-4 quarters59- Search keywords: ["supply agreement", "supply chain", "manufacturing"] across last 2-4 quarters60- Search keywords: ["sole source", "single source", "key supplier"] across last 2-4 quarters61- Search keywords: ["concentration", "significant supplier"] across last 2-4 quarters62- Search the company's 10-K specifically for supplier disclosures6364**2b. Web Research:**65- `"[TICKER] [company name] key suppliers list 2025 2026"` — supplier identification66- `"[TICKER] supply chain analysis suppliers"` — analyst/industry reports67- `"[TICKER] 10-K supplier disclosure"` — SEC filing analysis68- `"[company name] supply chain map"` — industry supply chain maps69- `"[company name] supplier concentration risk"` — risk analysis70- `"[company name] who manufactures for [company]"` — manufacturing partners71- `"[company name] component suppliers"` — component-level supply chain7273**2c. Industry-Specific Supplier Research:**74For each industry, search for the known critical supply chain relationships:75- **Tech/Hardware**: semiconductor foundries (TSMC, Samsung), display (Samsung, LG, BOE), memory (Samsung, SK Hynix, Micron), sensors/cameras (Sony), glass (Corning), connectors (Amphenol), batteries (CATL, LG Energy), PCB/assembly (Foxconn/Hon Hai, Pegatron, Luxshare)76- **Automotive**: battery (CATL, Panasonic, LG Energy), semiconductors (Infineon, NXP, ON Semi, TI), steel (Nippon, POSCO), tires (Michelin, Bridgestone), glass (AGC, Saint-Gobain)77- **Pharma**: CDMOs (Lonza, Samsung Biologics, Catalent), API suppliers, packaging, distribution78- **Retail**: brand suppliers, logistics (FedEx, UPS), packaging79- **Energy**: equipment (Baker Hughes, Schlumberger), pipe (Tenaris), chemicals8081### Phase 3: Supplier Financial Analysis8283For each identified supplier (aim for 8-15 key suppliers):84851. **Discover the supplier** using `discover_companies` with their ticker862. **Pull key financials** from Daloopa:87 - `discover_company_series` with keywords: ["revenue", "net income", "gross margin", "operating margin"]88 - `get_company_fundamentals` for the same 4 calendar quarters as the target company893. **Determine revenue concentration**:90 - Search Daloopa documents for the supplier: keywords ["[target company name]", "customer", "concentration"]91 - Web search: `"[supplier name] [target company] revenue percentage customer"`92 - Web search: `"[supplier name] 10-K customer concentration"`93 - Many suppliers disclose their top customers in 10-K filings — look for "customers that accounted for 10% or more of revenue"94 - **Source quality (MANDATORY):** these are factual claims — accept them only from primary sources (SEC filings, IR pages, press releases, transcripts) or Tier-1 financial press (Reuters, Bloomberg, WSJ, FT) per `../data-access.md` Section 2.5. Never source concentration figures from Yahoo Finance editorial, Benzinga, Seeking Alpha, Motley Fool, Zacks, TipRanks, StockTwits, Reddit, or similar aggregators/blogs; if a figure only appears there, corroborate it or flag it as unverified.954. **Determine COGS attribution** (what % of target's costs is this supplier):96 - This is often estimated. Use logic like:97 - If Apple's COGS is ~$200B TTM and TSMC's revenue from Apple is ~$70B, then TSMC = ~35% of COGS98 - Cite the source of each estimate (analyst report, 10-K disclosure, industry research)99 - Flag when this is an estimate vs. a disclosed figure1005. **Business & product description**: What does this supplier provide? Be specific (e.g., "5nm/3nm chip fabrication for A-series and M-series SoCs" not just "semiconductors")101102### Phase 3b: Inventory & 10-Quarter Financial Data103104For the target company AND each identified supplier (8-15 companies), pull **10 quarters** of data:1051061. **Discover inventory series** using `discover_company_series` with keywords: ["raw material", "work in process", "finished good", "inventory", "inventories"]107 - Look for separate RM, WIP, FG series, plus a total inventory series108 - Some companies report "carrying amount" breakdowns — use those for RM/WIP/FG splits1092. **Discover financial series** using `discover_company_series` with keywords: ["revenue", "gross profit", "net income", "gross margin"]1103. **Pull 10 quarters** using `get_company_fundamentals`. Calculate 10 quarters backward from `latest_calendar_quarter`.111 - Example: if latest is Q4'25, pull ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2", "2025Q3", "2025Q4"]1124. **Compute inventory composition**: For each quarter, calculate RM%, WIP%, FG% of total inventory113 - High WIP% can signal production bottlenecks114 - Rising FG% can signal demand weakness115 - Rising RM% can signal supply hoarding or procurement buildup1165. **Handle missing data gracefully**: Some suppliers may not report full inventory breakdowns — show what's available and note gaps1176. **Multi-currency handling**: Note the reporting currency for each company (USD, NTD, KRW, EUR, etc.) and display with appropriate units (e.g., "NTD B" for TSMC, "KRW T" for Samsung)118119Run inventory and financial series pulls in parallel across all companies.120121### Phase 4: Customer / Downstream Identification122123The downstream side requires the same research rigor as the upstream side. Run these concurrently to build a comprehensive customer list:124125**4a. Daloopa Document Search (target company filings):**126- Search keywords: ["customer", "contract", "agreement", "channel"] across last 2-4 quarters127- Search keywords: ["customer concentration", "significant customer", "major customer"] across last 2-4 quarters — many companies disclose customers >10% of revenue128- Search keywords: ["distribution", "retail partner", "reseller", "licensee"] across last 2-4 quarters129- Search keywords: ["accounts receivable", "contract asset", "deferred revenue"] — concentration in A/R often reveals customer dependency even when not explicitly named130- Search the company's 10-K specifically for customer disclosures and segment end-market breakdowns131132**4b. Web Research:**133- `"[TICKER] [company name] major customers list"` — direct customer identification134- `"[TICKER] customer concentration revenue breakdown"` — analyst/industry reports135- `"[TICKER] 10-K customer disclosure"` — SEC filing analysis136- `"[company name] who buys from [company name]"` — downstream identification137- `"[company name] channel partners distributors"` — channel analysis138- `"[company name] end market exposure"` — end-market breakdown139140**4c. Industry-Specific Customer Research:**141For each industry, search for the known critical downstream relationships:142- **Semiconductors**: Which OEMs depend on these chips? (e.g., NVDA → hyperscalers MSFT/AMZN/GOOG, QCOM → smartphone OEMs AAPL/Samsung, AVGO → networking OEMs Cisco/Arista)143- **Components/Materials**: Which assemblers or product companies use these inputs? (e.g., Corning → AAPL/Samsung for glass, TSMC → fabless semis NVDA/AMD/AAPL)144- **Software/Platform**: Who builds on this platform? (e.g., MSFT Azure → ISVs, AAPL App Store → developers, Salesforce → SI partners)145- **Consumer products**: Channel partners (carriers, retailers, e-commerce) and enterprise customers146- **Industrial/B2B**: End-market verticals (auto, aerospace, medical, telecom)147- **Pharma/Biotech**: Distributors (McKesson, AmerisourceBergen), PBMs, hospital systems148149**4d. Customer Financial Analysis:**150151For each identified customer (aim for 6-10 key customers):1521531. **Discover the customer** using `discover_companies` with their ticker1542. **Pull key financials** from Daloopa:155 - `discover_company_series` with keywords: ["revenue", "net income", "gross margin", "cost of goods", "operating income"]156 - `get_company_fundamentals` for the same 4 calendar quarters as the target company1573. **Determine revenue attribution** (what % of target's revenue comes from this customer):158 - Search Daloopa documents for the target company: keywords ["[customer name]", "customer", "concentration", "accounts receivable"]159 - Web search: `"[target company] [customer name] revenue percentage"`160 - Web search: `"[target company] 10-K customer concentration"`161 - Many companies disclose customers that account for >10% of revenue in their 10-K162 - **Source quality (MANDATORY):** same rule as the supplier analysis — attribution figures only from primary sources or Tier-1 financial press per `../data-access.md` Section 2.5; never from Yahoo Finance editorial, Benzinga, Seeking Alpha, Motley Fool, Zacks, TipRanks, StockTwits, Reddit, or similar aggregators/blogs. Corroborate or flag as unverified.1634. **Determine input criticality** (what % of customer's COGS comes from target):164 - This is the inverse of the supplier analysis: if the target sells $X to a customer with $Y in COGS, then input share = X/Y165 - Search for: `"[customer name] [target company] supplier dependence"` or `"[customer name] key inputs components"`166 - Flag whether the target's product is a critical, hard-to-substitute input vs. a commodity with alternatives1675. **Assess switching costs**: Can the customer easily replace the target company's product?168 - **High switching cost**: Custom/proprietary integration, long qualification cycles, regulatory requirements (e.g., TSMC's process node — customers can't easily switch foundries mid-design)169 - **Medium switching cost**: Some integration required but alternatives exist with 6-12 month transition170 - **Low switching cost**: Commodity input, multiple qualified alternatives, short switching timeline1716. **Business & product description**: What does the target supply to this customer? Be specific (e.g., "A17 Pro and M4 SoCs fabricated on TSMC's 3nm process" not just "chips")172173### Phase 4e: Customer Inventory & 10-Quarter Financial Data174175Mirror Phase 3b for the customer side. For each identified customer (6-10 companies), pull **10 quarters** of data:1761771. **Discover inventory series** using `discover_company_series` with keywords: ["raw material", "work in process", "finished good", "inventory", "inventories"]178 - Look for separate RM, WIP, FG series, plus a total inventory series1792. **Discover financial series** using `discover_company_series` with keywords: ["revenue", "gross profit", "net income", "gross margin"]1803. **Pull 10 quarters** using `get_company_fundamentals` with the same 10 calendar quarters as the target company and suppliers (calculated from `latest_calendar_quarter`)1814. **Compute inventory composition**: RM%, WIP%, FG% of total inventory182 - For customers, inventory signals have different meaning:183 - Rising RM% at a customer → they're stocking up on target company's inputs (bullish for target's near-term revenue, but may mean future destocking)184 - Falling RM% → customer is drawing down inventory, may signal reduced orders ahead185 - Rising FG% at a customer → demand for the customer's end product is softening, which will flow back upstream to the target1865. **Handle missing data gracefully**: Some customers may not report inventory breakdowns — show what's available1876. **Multi-currency handling**: Same as suppliers — note reporting currency188189Run customer inventory and financial series pulls in parallel, and in parallel with supplier pulls where possible.190191### Phase 5: Tier 2 Supplier Research192193For the top 3-5 most important Tier 1 suppliers, repeat a lighter version of Phase 2-3:1941951. Identify their key suppliers (Tier 2 to the original target)1962. Pull basic financials1973. Determine what they supply and rough revenue/cost relationships1984. This enables the "drill deeper" functionality in the dashboard199200### Phase 6: Data Assembly & Synthesis201202Before writing HTML, organize all data into this structure:203204```205TARGET COMPANY:206 - Name, ticker, description207 - TTM Revenue, COGS, Gross Profit, Net Income, Gross Margin, Op Margin208 - Market cap, stock price (from web)209210TIER 1 SUPPLIERS (sorted by estimated % of target COGS, descending):211 For each:212 - Name, ticker, description213 - What they supply (specific products/components)214 - Estimated % of target company COGS (with source/logic)215 - % of supplier revenue from target company (with source)216 - TTM Revenue, Net Income, Gross Margin217 - Market cap218 - Relationship summary (sole source? multi-source? critical?)219 - Their key suppliers (Tier 2) if researched220 - 10-quarter financials: Revenue, Gross Profit, Net Income, GM% (with Daloopa citation IDs)221 - 10-quarter inventory: RM, WIP, FG, Total, RM%, WIP%, FG% (with Daloopa citation IDs)222 - Reporting currency and unit (e.g., USD $M, NTD B, KRW T)223224TIER 1 CUSTOMERS (sorted by estimated % of target revenue, descending):225 For each:226 - Name, ticker, description227 - What target company supplies to them (specific products/services)228 - Estimated % of target revenue from this customer (with source/logic)229 - Estimated % of customer COGS from target (input criticality, with source)230 - Switching cost assessment (High/Medium/Low with reasoning)231 - TTM Revenue, COGS, Net Income, Gross Margin232 - Market cap233 - Relationship summary (exclusive? multi-source? long-term contract? spot?)234 - 10-quarter financials: Revenue, Gross Profit, Net Income, GM% (with Daloopa citation IDs)235 - 10-quarter inventory: RM, WIP, FG, Total, RM%, WIP%, FG% (with Daloopa citation IDs)236 - Reporting currency and unit (e.g., USD $M, EUR M, JPY B)237238TIER 2 CUSTOMERS (for top 3-5 Tier 1 customers — who do THEY sell to?):239 For each Tier 1 customer, their key customers with basic data240 This traces the value chain forward: Target → Customer → End Market241242TIER 2 SUPPLIERS (for top 3-5 Tier 1 suppliers):243 For each Tier 1 supplier, their key suppliers with basic data244```245246### Phase 6b: Upstream Shock Analysis (Demand Shock → Suppliers)247248Prepare a narrative analysis of how a demand shock at the target company would ripple upstream through the supplier chain:2492501. **Classify each supplier by dependency level**:251 - **High dependency**: Target company is >20% of supplier's revenue → severe impact from demand shock252 - **Moderate dependency**: Target is 10-20% of revenue → meaningful but manageable impact253 - **Low dependency**: Target is <10% of revenue → diversified, minimal direct impact2542552. **Assess shock propagation for each supplier**:256 - **Revenue Impact** (High/Medium/Low): Based on % of revenue from target257 - **Margin Impact** (High/Medium/Low): Based on operating leverage, fixed costs, ability to find replacement demand258 - **Inventory Risk**: Suppliers with high FG% are more exposed to demand shocks; those with high RM% face supply-side risk259 - **Substitutability**: Can the target switch to alternatives? Can the supplier find other customers?2602613. **Build an impact matrix table** with columns: Supplier, Tier, Revenue Dependency, Revenue Impact, Margin Impact, Overall Risk2622634. **Write narrative sections**:264 - "Most Exposed Suppliers" — 2-3 paragraphs on suppliers facing highest risk265 - "Resilient Suppliers" — suppliers with diversified revenue bases266 - "Second-Order Effects" — how Tier 2 suppliers would be indirectly affected267 - "Key Monitoring Metrics" — what an analyst should watch (inventory days, order backlog, etc.)268269### Phase 6c: Downstream Shock Analysis (Supply Disruption → Customers)270271Prepare a narrative analysis of how a supply disruption at the target company (production halt, quality issue, capacity constraint, export ban) would ripple downstream through the customer chain:2722731. **Classify each customer by input criticality**:274 - **Critical input**: Target's product is a key component with no drop-in replacement; disruption halts customer production (e.g., TSMC to Apple — no alternative foundry for A-series chips)275 - **Important input**: Target is a significant but not sole supplier; customer can partially substitute with 3-6 month lead time276 - **Supplementary input**: Target provides a non-critical input; customer has multiple qualified alternatives2772782. **Assess downstream disruption for each customer**:279 - **Input Criticality** (High/Medium/Low): How essential is the target's product to the customer's operations?280 - **Switching Cost** (High/Medium/Low): How long and expensive to qualify an alternative? Are there contractual lock-ins?281 - **Revenue at Risk**: What portion of the customer's revenue depends on products that use the target's inputs?282 - **Inventory Buffer**: Does the customer hold significant RM inventory of the target's product? How many weeks/months of supply?283 - **Alternative Sources**: Who else could supply this? What's the capacity gap?2842853. **Build a downstream impact matrix table** with columns: Customer, Category, Input Criticality, Switching Cost, Revenue at Risk, Inventory Buffer, Overall Disruption Risk2862874. **Write narrative sections**:288 - "Most Vulnerable Customers" — customers who would face production disruption or revenue loss289 - "Customers with Alternatives" — those who can substitute away from the target290 - "Pricing Power Implications" — if the target faces a supply constraint, which customers have the leverage to secure allocation vs. which get cut first?291 - "Channel Inventory Signals" — what customer inventory levels (especially RM%) tell you about near-term order patterns for the target company292 - "Second-Order Downstream Effects" — how end consumers or Tier 2 customers would be affected293294---295296## HTML TEMPLATE & DESIGN SYSTEM297298Start from the HTML Report Template in `../design-system.md` (copy the full `<style>` block). Then add the following **additional CSS** for interactive dashboard components. Use the design system's color palette throughout.299300### Design Principles301- Follow `../design-system.md` for color palette, typography, and table conventions302- **Information density**: Show data compactly but with clear hierarchy303- **Interactive but not flashy**: Smooth transitions, click-to-expand, no animations for animation's sake304305### Core CSS306307Start with the full CSS from `../design-system.md`, then append these dashboard-specific styles:308309```html310<!DOCTYPE html>311<html lang="en">312<head>313<meta charset="UTF-8">314<meta name="viewport" content="width=device-width, initial-scale=1.0">315<title>[TICKER] Supply Chain Dashboard</title>316<style>317 /* === PASTE FULL CSS FROM design-system.md HTML Report Template HERE === */318319 /* === DASHBOARD-SPECIFIC EXTENSIONS BELOW === */320321 @media print {322 .no-print { display: none !important; }323 .interactive { pointer-events: none; }324 @page { margin: 0.5in; size: landscape; }325 }326327 :root {328 /* Extended palette for dashboard components — supplements design-system.md vars */329 --bg: var(--light-gray);330 --surface: #ffffff;331 --border: var(--mid-gray);332 --border-light: var(--light-gray);333 --text-primary: var(--near-black);334 --text-secondary: var(--dark-gray);335 --text-tertiary: #8a8a85;336 --accent: var(--steel-blue);337 --green-bg: #f0f9f2;338 --red-bg: #fef2f2;339 --amber: #92600a;340 --amber-bg: #fefce8;341 --blue-bg: #eff6ff;342 --node-supplier: var(--mid-gray);343 --node-customer: #dde8f0;344 --node-target: var(--navy);345 --sans: "Segoe UI", -apple-system, BlinkMacSystemFont, Arial, sans-serif;346 --mono: "SF Mono", "Fira Code", "Fira Mono", "Roboto Mono", monospace;347 }348349 /* Layout */350 .page-header {351 background: var(--surface);352 border-bottom: 3px solid var(--navy);353 padding: 24px 40px 16px;354 }355 .page-header h1 {356 font-size: 28px;357 font-weight: 700;358 color: var(--navy);359 letter-spacing: -0.5px;360 line-height: 1.2;361 }362 .page-header .subtitle {363 font-size: 14px;364 color: var(--text-secondary);365 margin-top: 4px;366 }367 .page-header .dateline {368 font-size: 12px;369 color: var(--text-tertiary);370 margin-top: 8px;371 font-family: var(--mono);372 }373374 .container {375 max-width: 1400px;376 margin: 0 auto;377 padding: 24px 40px;378 }379380 /* Section Headers */381 h2 {382 font-family: var(--sans);383 font-size: 20px;384 font-weight: 700;385 margin: 32px 0 16px;386 padding-bottom: 6px;387 border-bottom: 1px solid var(--mid-gray);388 letter-spacing: -0.3px;389 color: var(--navy);390 }391 h3 {392 font-family: var(--sans);393 font-size: 13px;394 font-weight: 700;395 text-transform: uppercase;396 letter-spacing: 0.8px;397 color: var(--steel-blue);398 margin: 20px 0 10px;399 }400401 /* KPI Bar */402 .kpi-bar {403 display: flex;404 gap: 0;405 border: 1px solid var(--border);406 border-radius: 6px;407 overflow: hidden;408 background: var(--surface);409 margin: 16px 0;410 }411 .kpi-item {412 flex: 1;413 padding: 12px 16px;414 border-right: 1px solid var(--border-light);415 text-align: center;416 }417 .kpi-item:last-child { border-right: none; }418 .kpi-label {419 font-size: 10px;420 text-transform: uppercase;421 letter-spacing: 0.5px;422 color: var(--text-tertiary);423 font-weight: 600;424 }425 .kpi-value {426 font-size: 18px;427 font-weight: 700;428 margin-top: 2px;429 font-variant-numeric: tabular-nums;430 }431 .kpi-sub {432 font-size: 11px;433 color: var(--text-tertiary);434 margin-top: 1px;435 }436437 /* Supply Chain Visualization */438 .chain-view {439 display: flex;440 gap: 24px;441 align-items: flex-start;442 margin: 20px 0;443 overflow-x: auto;444 padding-bottom: 16px;445 }446 .chain-column {447 min-width: 280px;448 flex-shrink: 0;449 }450 .chain-column-header {451 font-family: var(--sans);452 font-size: 11px;453 font-weight: 700;454 text-transform: uppercase;455 letter-spacing: 1px;456 color: var(--text-tertiary);457 margin-bottom: 12px;458 padding-bottom: 6px;459 border-bottom: 1px solid var(--border);460 text-align: center;461 }462 .chain-arrow {463 display: flex;464 align-items: center;465 justify-content: center;466 color: var(--text-tertiary);467 font-size: 24px;468 min-width: 40px;469 padding-top: 40px;470 flex-shrink: 0;471 }472473 /* Company Cards */474 .company-card {475 background: var(--surface);476 border: 1px solid var(--border);477 border-radius: 6px;478 padding: 14px 16px;479 margin-bottom: 10px;480 cursor: pointer;481 transition: border-color 0.15s, box-shadow 0.15s;482 }483 .company-card:hover {484 border-color: var(--text-secondary);485 box-shadow: 0 2px 8px rgba(0,0,0,0.06);486 }487 .company-card.target-card {488 background: var(--navy);489 color: white;490 border-color: var(--navy);491 }492 .company-card.target-card .card-ticker { color: rgba(255,255,255,0.7); }493 .company-card.target-card .card-metric-label { color: rgba(255,255,255,0.5); }494 .company-card.target-card .card-metric-value { color: white; }495 .company-card.target-card .card-desc { color: rgba(255,255,255,0.7); }496 .company-card.expanded { border-color: var(--steel-blue); box-shadow: 0 2px 12px rgba(74,111,165,0.15); }497 .company-card.supplier-card { border-left: 3px solid var(--node-supplier); }498 .company-card.customer-card { border-left: 3px solid var(--node-customer); }499500 .card-header {501 display: flex;502 justify-content: space-between;503 align-items: flex-start;504 }505 .card-name {506 font-family: var(--sans);507 font-size: 16px;508 font-weight: 700;509 line-height: 1.2;510 }511 .card-ticker {512 font-family: var(--mono);513 font-size: 11px;514 color: var(--text-tertiary);515 margin-top: 2px;516 }517 .card-badge {518 font-size: 10px;519 font-weight: 700;520 padding: 2px 8px;521 border-radius: 3px;522 white-space: nowrap;523 }524 .badge-pct-high { background: var(--red-bg); color: var(--red); }525 .badge-pct-med { background: var(--amber-bg); color: var(--amber); }526 .badge-pct-low { background: var(--green-bg); color: var(--green); }527528 .card-supplies {529 font-size: 12px;530 color: var(--text-secondary);531 margin-top: 6px;532 line-height: 1.4;533 }534535 .card-metrics {536 display: grid;537 grid-template-columns: repeat(3, 1fr);538 gap: 8px;539 margin-top: 10px;540 padding-top: 10px;541 border-top: 1px solid var(--border-light);542 }543 .card-metric-label {544 font-size: 9px;545 text-transform: uppercase;546 letter-spacing: 0.3px;547 color: var(--text-tertiary);548 }549 .card-metric-value {550 font-size: 13px;551 font-weight: 700;552 font-variant-numeric: tabular-nums;553 }554555 .card-desc {556 font-size: 12px;557 color: var(--text-secondary);558 margin-top: 8px;559 line-height: 1.45;560 }561562 /* Expanded Detail Panel */563 .detail-panel {564 display: none;565 margin-top: 12px;566 padding-top: 12px;567 border-top: 1px solid var(--border-light);568 }569 .company-card.expanded .detail-panel { display: block; }570571 .detail-section {572 margin-bottom: 14px;573 }574 .detail-section h4 {575 font-size: 11px;576 font-weight: 700;577 text-transform: uppercase;578 letter-spacing: 0.5px;579 color: var(--text-tertiary);580 margin-bottom: 6px;581 }582583 .relationship-bar {584 height: 8px;585 background: var(--border-light);586 border-radius: 4px;587 overflow: hidden;588 margin: 4px 0;589 }590 .relationship-fill {591 height: 100%;592 border-radius: 4px;593 transition: width 0.3s;594 }595 .fill-red { background: var(--red); }596 .fill-amber { background: var(--amber); }597 .fill-green { background: var(--green); }598 .fill-blue { background: var(--accent); }599600 /* Drill-down button */601 .drill-btn {602 display: inline-block;603 font-size: 11px;604 font-weight: 600;605 color: var(--accent);606 cursor: pointer;607 padding: 4px 0;608 border: none;609 background: none;610 font-family: var(--sans);611 }612 .drill-btn:hover { text-decoration: underline; }613614 /* Concentration Table */615 .conc-table {616 width: 100%;617 border-collapse: collapse;618 font-size: 13px;619 margin: 12px 0;620 }621 .conc-table th {622 font-size: 10px;623 text-transform: uppercase;624 letter-spacing: 0.5px;625 color: var(--text-tertiary);626 font-weight: 600;627 text-align: left;628 padding: 6px 10px;629 border-bottom: 2px solid var(--border);630 background: var(--bg);631 }632 .conc-table th:not(:first-child) { text-align: right; }633 .conc-table td {634 padding: 8px 10px;635 border-bottom: 1px solid var(--border-light);636 font-variant-numeric: tabular-nums;637 }638 .conc-table td:not(:first-child) { text-align: right; }639 .conc-table tr:hover { background: var(--blue-bg); }640 .conc-table .row-total {641 font-weight: 700;642 border-top: 2px solid var(--border);643 background: var(--bg);644 }645646 /* Risk indicator */647 .risk-tag {648 display: inline-block;649 font-size: 10px;650 font-weight: 700;651 padding: 1px 6px;652 border-radius: 3px;653 }654 .risk-high { background: var(--red-bg); color: var(--red); }655 .risk-med { background: var(--amber-bg); color: var(--amber); }656 .risk-low { background: var(--green-bg); color: var(--green); }657658 /* Tabs for switching views */659 .tab-bar {660 display: flex;661 gap: 0;662 border-bottom: 2px solid var(--border);663 margin-bottom: 20px;664 }665 .tab {666 padding: 10px 20px;667 font-size: 13px;668 font-weight: 600;669 color: var(--text-tertiary);670 cursor: pointer;671 border-bottom: 2px solid transparent;672 margin-bottom: -2px;673 transition: color 0.15s, border-color 0.15s;674 font-family: var(--sans);675 background: none;676 border-top: none;677 border-left: none;678 border-right: none;679 }680 .tab:hover { color: var(--text-primary); }681 .tab.active {682 color: var(--text-primary);683 border-bottom-color: var(--text-primary);684 }685 .tab-content { display: none; }686 .tab-content.active { display: block; }687688 /* Methodology / Source Notes */689 .methodology-box {690 background: var(--bg);691 border: 1px solid var(--border);692 border-radius: 6px;693 padding: 16px 20px;694 margin: 16px 0;695 font-size: 12px;696 color: var(--text-secondary);697 line-height: 1.5;698 }699 .methodology-box h4 {700 font-size: 11px;701 font-weight: 700;702 text-transform: uppercase;703 letter-spacing: 0.5px;704 color: var(--text-tertiary);705 margin-bottom: 8px;706 }707708 /* Links & References */709 a { color: var(--accent); text-decoration: none; }710 a:hover { text-decoration: underline; }711712 .source-tag {713 font-size: 9px;714 color: var(--text-tertiary);715 font-style: italic;716 }717718 /* Footer */719 .page-footer {720 margin-top: 40px;721 padding: 16px 0;722 border-top: 3px solid var(--navy);723 font-size: 11px;724 color: var(--text-tertiary);725 text-align: center;726 }727728 /* Print button */729 .dl-btn {730 display: inline-block;731 padding: 10px 24px;732 background: var(--navy);733 color: white;734 border: none;735 border-radius: 5px;736 font-size: 13px;737 font-weight: 600;738 cursor: pointer;739 font-family: var(--sans);740 }741 .dl-btn:hover { background: var(--steel-blue); }742743 /* Two-column layout */744 .two-col {745 display: grid;746 grid-template-columns: 1fr 1fr;747 gap: 20px;748 }749 @media (max-width: 800px) {750 .two-col { grid-template-columns: 1fr; }751 .chain-view { flex-direction: column; }752 .chain-arrow { transform: rotate(90deg); padding-top: 0; }753 }754</style>755</head>756```757758### Core JavaScript Pattern759760The dashboard uses vanilla JavaScript for interactivity. Include these functions in a `<script>` tag at the end of the body:761762```javascript763<script>764// Tab switching765function switchTab(tabId) {766 document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));767 document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));768 document.querySelector(`[data-tab="${tabId}"]`).classList.add('active');769 document.getElementById(tabId).classList.add('active');770}771772// Card expand/collapse773function toggleCard(cardId) {774 const card = document.getElementById(cardId);775 card.classList.toggle('expanded');776}777778// Navigate to tier 2 view for a specific supplier779function drillDown(companyTicker) {780 // Switch to the tier-2 tab and scroll to the relevant section781 switchTab('tier2');782 const section = document.getElementById('tier2-' + companyTicker);783 if (section) {784 section.scrollIntoView({ behavior: 'smooth', block: 'start' });785 section.style.outline = '2px solid var(--accent)';786 setTimeout(() => { section.style.outline = 'none'; }, 2000);787 }788}789790// Initialize791document.addEventListener('DOMContentLoaded', () => {792 // Set first tab active793 const firstTab = document.querySelector('.tab');794 if (firstTab) firstTab.click();795});796</script>797```798799---800801## DOCUMENT STRUCTURE802803The HTML document has these sections. Every section is mandatory.804805### Section 1: Print Button Bar806```html807<div class="no-print" style="text-align:center; padding:16px; background:var(--surface); border-bottom:1px solid var(--border);">808 <button class="dl-btn" onclick="window.print()">Download as PDF</button>809 <span style="font-size:12px; color:var(--text-tertiary); margin-left:12px;">or Cmd+P → Save as PDF</span>810</div>811```812813### Section 2: Page Header814```html815<div class="page-header">816 <h1>[TICKER] — Supply Chain Map</h1>817 <div class="subtitle">[Full Company Name] · Interactive Supply Chain Analysis</div>818 <div class="dateline">Prepared [Date] · Data sourced from <a href="https://daloopa.com">Daloopa</a> · TTM through [Latest Quarter]</div>819</div>820```821822### Section 3: Target Company KPI Bar823Show 6 KPIs for the target company:824```html825<div class="container">826 <div class="kpi-bar">827 <div class="kpi-item"><div class="kpi-label">TTM Revenue</div><div class="kpi-value">$XXB</div></div>828 <div class="kpi-item"><div class="kpi-label">TTM COGS</div><div class="kpi-value">$XXB</div></div>829 <div class="kpi-item"><div class="kpi-label">Gross Margin</div><div class="kpi-value">XX.X%</div></div>830 <div class="kpi-item"><div class="kpi-label">Suppliers Mapped</div><div class="kpi-value">XX</div></div>831 <div class="kpi-item"><div class="kpi-label">Top 5 = % of COGS</div><div class="kpi-value">~XX%</div></div>832 <div class="kpi-item"><div class="kpi-label">Key Customers</div><div class="kpi-value">XX</div></div>833 </div>834```835836### Section 4: Page Layout837838The dashboard uses a **single scrollable page** (no tabs) with the following vertical order:8391. KPI bar (target company overview)8402. Canvas network visualization (full chain: Tier 3 → Tier 2 → Tier 1 → Target → Customers → Tier 2 Customers)8413. Inventory Health Overview table (suppliers AND customers)8424. Supplier cards grouped by tier8435. Customer cards grouped by category8446. Upstream Shock Analysis (demand shock → suppliers, narrative + impact matrix)8457. Downstream Shock Analysis (supply disruption → customers, narrative + impact matrix)8468. Concentration Analysis summary (both upstream and downstream)8479. Footer848849Each supplier and customer card is clickable — opening a **full-screen detail overlay** with 10-quarter financials, inventory tables, and Canvas charts. The overlay is dismissed with × or backdrop click.850851### Section 5: Canvas Network Visualization852853Replace the HTML card-based chain view with a **Canvas-based tier-grouped network**:854855- Use a `<canvas>` element spanning the full container width, ~420px height856- **Column layout**: Tier 3 (left) → Tier 2 → Tier 1 → Target (center) → Customers (right)857- Draw each company as a rounded rectangle node with ticker label858- Draw connection lines (bezier curves or straight lines) between related nodes859- Color-code by tier: Target = navy (#1B2A4A), Tier 1 = steel blue (#4A6FA5), Tier 2 = gold (#C5A55A), Tier 3 = dark gray (#6C757D), Customers = mid gray (#E9ECEF)860- **Clickable nodes**: Track click coordinates with a `click` event listener on the canvas, determine which node was clicked via hit-testing, then open the detail overlay for that company861- Column headers ("TIER 1", "TIER 2", "TARGET", etc.) drawn as text above each column862- Responsive: redraw on `window.resize`863864```javascript865// Example network drawing function pattern:866function drawNetwork() {867 const cv = document.getElementById('networkCanvas');868 const ctx = cv.getContext('2d');869 cv.width = cv.parentElement.clientWidth;870 cv.height = 420;871 ctx.clearRect(0, 0, cv.width, cv.height);872873 // Define columns: x positions for each tier874 const cols = {875 tier3: cv.width * 0.08,876 tier2: cv.width * 0.28,877 tier1: cv.width * 0.48,878 target: cv.width * 0.68,879 customers: cv.width * 0.88880 };881882 // Draw column headers, nodes, and connection lines883 // Store node positions for hit-testing on click884}885```886887### Section 5b: Inventory Health Overview888889Below the network, add an **Inventory Health Overview** table showing all suppliers AND customers:890891```892| Company | Ticker | Role | Total Inventory | RM% | WIP% | FG% | Composition Bar |893```894895- The "Role" column shows "Supplier T1", "Supplier T2", "Customer", or "Target"896- The "Composition Bar" column renders a stacked horizontal bar (RM = blue, WIP = amber, FG = green) using inline CSS `background: linear-gradient(...)`897- Sort by total inventory descending or by FG% descending (highest FG% = most demand-shock exposure)898- Include the target company at the top of the table, then suppliers, then customers899- Each inventory value must link to its Daloopa citation900- **Analytical note**: For suppliers, rising FG% signals demand weakness from the target. For customers, rising RM% signals stockpiling of the target's inputs (bullish near-term, potential destocking risk later). Falling RM% at customers signals reduced orders ahead.901902### Section 5c: Supplier Cards by Tier903904Below the inventory overview, render supplier cards grouped under tier headings:905906```907── TIER 1 · Critical / Sole-Source ──────908[Card: TSMC] [Card: Samsung] [Card: Broadcom] ...909910── TIER 2 · Major Component ─────────────911[Card: Qualcomm] [Card: Skyworks] [Card: TXN] ...912913── TI914915…(truncated)