
{"id":725,"date":"2026-04-28T06:19:51","date_gmt":"2026-04-28T06:19:51","guid":{"rendered":"https:\/\/obexanalytica.com\/ar\/?p=725"},"modified":"2026-05-02T22:22:16","modified_gmt":"2026-05-02T22:22:16","slug":"irans-oil-infrastructure-under-blokade-production-decline-and-recovery-constraints","status":"publish","type":"post","link":"https:\/\/obexanalytica.com\/ar\/blog\/2026\/04\/28\/irans-oil-infrastructure-under-blokade-production-decline-and-recovery-constraints\/","title":{"rendered":"\u062f\u064a\u0646\u0627\u0645\u064a\u0643\u064a\u0627\u062a \u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0628\u0646\u064a\u0629 \u0627\u0644\u062a\u062d\u062a\u064a\u0629 \u0627\u0644\u0646\u0641\u0637\u064a\u0629 \u0627\u0644\u0625\u064a\u0631\u0627\u0646\u064a\u0629 \u0641\u064a \u0638\u0644 \u0627\u0644\u062d\u0635\u0627\u0631: \u0627\u0646\u062e\u0641\u0627\u0636 \u0627\u0644\u0625\u0646\u062a\u0627\u062c \u0648\u0645\u0639\u0648\u0642\u0627\u062a \u0627\u0644\u062a\u0639\u0627\u0641\u064a"},"content":{"rendered":"\n<div id=\"obex-article-iran-oil-infrastructure-hormuz-closure\" class=\"obex-article\" lang=\"en\" dir=\"ltr\">\n  <style>\n    @import url('https:\/\/fonts.googleapis.com\/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Sans+Arabic:wght@400;500;600;700&display=swap');\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure,\n    #obex-article-iran-oil-infrastructure-hormuz-closure * {\n      box-sizing: border-box;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure {\n      --obex-primary: #0F1C5C;\n      --obex-accent: #E60000;\n      --obex-white: #FFFFFF;\n      --obex-soft-bg: #F7F8FC;\n      --obex-grid: rgba(15, 28, 92, 0.14);\n      --obex-border: rgba(15, 28, 92, 0.24);\n      --obex-muted: rgba(15, 28, 92, 0.68);\n      --obex-shadow: 0 18px 40px rgba(15, 28, 92, 0.08);\n      --obex-radius: 18px;\n      width: 100%;\n      color: var(--obex-primary);\n      font-family: 'IBM Plex Sans', 'IBM Plex Sans Arabic', Arial, sans-serif;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-article-shell {\n      width: 100%;\n      max-width: 1100px;\n      margin: 0 auto;\n      padding: 36px 0;\n      color: var(--obex-primary);\n      font-family: inherit;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure[dir=\"rtl\"] .obex-article-shell {\n      direction: rtl;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure[dir=\"ltr\"] .obex-article-shell {\n      direction: ltr;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-summary {\n      margin: 0 0 40px;\n      padding: 28px 34px;\n      background: var(--obex-primary);\n      color: var(--obex-white) !important;\n      border-left: 8px solid var(--obex-accent);\n      border-radius: var(--obex-radius);\n      box-shadow: var(--obex-shadow);\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-summary,\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-summary * {\n      color: var(--obex-white) !important;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-summary p {\n      margin: 0;\n      font-size: clamp(1rem, 1.6vw, 1.18rem);\n      line-height: 1.9;\n      font-weight: 500;\n      text-align: justify;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-text {\n      margin: 0 0 26px;\n      color: var(--obex-primary);\n      font-family: inherit;\n      font-size: clamp(1rem, 1.45vw, 1.18rem);\n      line-height: 1.95;\n      font-weight: 400;\n      text-align: justify;\n      overflow-wrap: break-word;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-heading {\n      display: inline-block;\n      margin: 50px 0 24px;\n      padding-bottom: 10px;\n      color: var(--obex-primary);\n      border-bottom: 3px solid var(--obex-accent);\n      font-family: inherit;\n      font-size: clamp(1.35rem, 2.6vw, 1.75rem);\n      line-height: 1.45;\n      font-weight: 700;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-card {\n      margin: 44px 0;\n      padding: 30px 34px;\n      background: var(--obex-white);\n      border: 2px solid var(--obex-primary);\n      border-radius: var(--obex-radius);\n      box-shadow: var(--obex-shadow);\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-title {\n      margin: 0 0 22px;\n      text-align: center;\n      color: var(--obex-accent);\n      font-size: clamp(1.12rem, 2.1vw, 1.45rem);\n      line-height: 1.45;\n      font-weight: 700;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-wrapper {\n      position: relative;\n      width: 100%;\n      min-height: 380px;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-wrapper.is-timeline {\n      min-height: 430px;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-source,\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-note {\n      margin: 16px 0 0;\n      color: var(--obex-muted);\n      font-size: 0.84rem;\n      line-height: 1.6;\n      text-align: center;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-note {\n      max-width: 860px;\n      margin-left: auto;\n      margin-right: auto;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure canvas {\n      display: block;\n      width: 100% !important;\n      height: 100% !important;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-diagram-wrap {\n      width: 100%;\n      overflow-x: auto;\n      padding: 4px 0;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-diagram-svg {\n      display: block;\n      width: 100%;\n      min-width: 760px;\n      height: auto;\n      background: var(--obex-soft-bg);\n      border: 1px solid var(--obex-grid);\n      border-radius: 14px;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-diagram-svg text {\n      font-family: 'IBM Plex Sans', 'IBM Plex Sans Arabic', Arial, sans-serif;\n      fill: var(--obex-primary);\n      font-weight: 600;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-diagram-svg text.obex-diagram-red {\n      fill: var(--obex-accent);\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-diagram-svg text.obex-diagram-muted {\n      fill: var(--obex-muted);\n      font-weight: 500;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-table-wrap {\n      width: 100%;\n      overflow-x: auto;\n      margin: 42px 0 10px;\n      border: 2px solid var(--obex-primary);\n      border-radius: var(--obex-radius);\n      background: var(--obex-white);\n      box-shadow: var(--obex-shadow);\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-data-table {\n      width: 100%;\n      min-width: 900px;\n      border-collapse: collapse;\n      color: var(--obex-primary);\n      font-size: 0.98rem;\n      line-height: 1.65;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-data-table caption {\n      caption-side: top;\n      padding: 18px;\n      color: var(--obex-accent);\n      font-weight: 700;\n      font-size: 1.22rem;\n      line-height: 1.45;\n      text-align: center;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-data-table th,\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-data-table td {\n      padding: 14px 16px;\n      border-bottom: 1px solid var(--obex-grid);\n      vertical-align: top;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-data-table thead th {\n      background: var(--obex-primary);\n      color: var(--obex-white);\n      font-weight: 700;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-data-table tbody tr:last-child td {\n      border-bottom: 0;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure .obex-copyright {\n      margin: 42px 0 0;\n      padding-top: 22px;\n      border-top: 1px solid var(--obex-border);\n      color: var(--obex-muted);\n      font-size: 0.92rem;\n      line-height: 1.7;\n      text-align: center;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure a {\n      color: var(--obex-accent);\n      text-decoration: none;\n      overflow-wrap: anywhere;\n    }\n\n    #obex-article-iran-oil-infrastructure-hormuz-closure a:hover {\n      color: var(--obex-primary);\n      text-decoration: none;\n    }\n\n    @media (max-width: 768px) {\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-article-shell {\n        padding: 28px 0;\n      }\n\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-summary,\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-card {\n        padding: 22px 16px;\n        border-radius: 14px;\n      }\n\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-summary {\n        margin-bottom: 32px;\n      }\n\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-text {\n        font-size: 1rem;\n        line-height: 1.9;\n        margin-bottom: 22px;\n      }\n\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-heading {\n        display: block;\n        width: fit-content;\n        margin-top: 40px;\n        font-size: 1.28rem;\n      }\n\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-wrapper {\n        min-height: 340px;\n      }\n\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-wrapper.is-timeline {\n        min-height: 420px;\n      }\n\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-chart-title {\n        font-size: 1.08rem;\n      }\n\n      #obex-article-iran-oil-infrastructure-hormuz-closure .obex-data-table {\n        min-width: 860px;\n        font-size: 0.9rem;\n      }\n    }\n  <\/style>\n\n  <article class=\"obex-article-shell\">\n    <section class=\"obex-summary\" aria-label=\"Introductory assessment\">\n      <p>Iran entered the 2026 crisis with crude production of approximately 3.3 to 3.5 million barrels per day (mb\/d), of which 1.5 to 1.6 mb\/d reached international buyers through an export network almost entirely dependent on the Strait of Hormuz. The Strait handles approximately 20 mb\/d of hydrocarbons \u2014 roughly 20 percent of global petroleum liquids consumption \u2014 and Iran alone contributed 2.41 mb\/d of that flow in 2025 when crude, condensate, and refined products are combined. Iran&#8217;s domestic refining capacity of roughly 2.4 mb\/d provides a partial demand floor, but usable working storage at the onset of the crisis stood at only 35 to 42 million barrels against a theoretical maximum of 86 million barrels, with the pre-crisis inventory already occupying approximately 47 million barrels.<\/p>\n    <\/section>\n\n    <p class=\"obex-text\">Within 48 hours of initial strikes in late February 2026, war risk premiums for vessels transiting the Strait surged fivefold \u2014 rising from 0.125 percent to between 0.2 and 0.4 percent of ship insurance value per transit \u2014 adding hundreds of thousands of dollars to the cost of a single VLCC voyage. The Lloyd&#8217;s Market Association formally redesignated the entire Arabian Gulf as a conflict zone, and tanker traffic collapsed by more than 80 percent before a naval blockade was formally declared. Crude exports fell from a pre-crisis baseline of 1.5 to 1.6 mb\/d to an estimated 200,000 to 400,000 barrels per day. The resulting economic losses have already exceeded an estimated $144 billion, approximately 40 percent of Iran&#8217;s pre-war GDP in under two months of conflict.<\/p>\n\n    <h2 class=\"obex-heading\">Iran&#8217;s Export Infrastructure: A Single Point Of Failure<\/h2>\n\n    <p class=\"obex-text\">The structure of Iran&#8217;s export network concentrates approximately 90 percent of crude shipments through a single facility: Kharg Island. Crude from the giant southwestern onshore fields \u2014 Ahvaz, Gachsaran, and Marun \u2014 travels a fixed corridor through the Ghurreh booster station and the Ganaveh manifold before entering 30-inch, 42-inch, and 52-inch subsea lines to the island, where 78-inch transfer lines feed berths capable of loading up to nine tankers simultaneously. This linear dependency means that disabling a single pumping station or manifold severs the entire mainland production base from the sea.<\/p>\n\n    <figure class=\"obex-chart-card\">\n      <figcaption class=\"obex-chart-title\">Export Infrastructure Concentration And Bypass Limits<\/figcaption>\n      <div class=\"obex-chart-wrapper\">\n        <canvas id=\"obex-chart-export-terminals\" role=\"img\" aria-label=\"Horizontal bar chart comparing text-stated export terminal scale across Kharg Island, Jask, Lavan, and Sirri.\"><\/canvas>\n      <\/div>\n      <p class=\"obex-chart-note\">Data use text-stated or text-derived values: Kharg&#8217;s baseline role is calculated from the 90 percent share of the 1.55 mb\/d midpoint of pre-crisis crude exports; Jask shows 1.0 mb\/d design capacity but zero sustained commercial utilization at the crisis start.<\/p>\n      <p class=\"obex-chart-source\">OBEX Analytica assessment<\/p>\n    <\/figure>\n\n    <p class=\"obex-text\">The theoretical bypass at Jask on the Gulf of Oman \u2014 designed for 1 mb\/d via the Goreh-Jask pipeline with 20 million barrels of planned storage \u2014 remained effectively non-operational at the start of the crisis. A single test cargo moved in late 2024, but no sustained commercial volumes had utilized the route. Smaller terminals at Lavan and Sirri handle roughly 105,000 and 100,000 barrels per day respectively and cannot absorb mainland volumes at scale. Strikes on South Pars Phase 14 have additionally removed an estimated 100,000 to 120,000 barrels per day of condensate capacity for the medium term, further narrowing the export slate.<\/p>\n\n    <h2 class=\"obex-heading\">The Storage Threshold And The Forced Shut-In<\/h2>\n\n    <p class=\"obex-text\">Once the export pathway is blocked, the logic of the shut-in becomes purely mathematical. With a daily net surplus of approximately 1.5 mb\/d accumulating against a working buffer of only 35 to 42 million barrels, operators face a storage ceiling in 13 to 22 days under normal extraction rates. Shadow fleet tankers moored in the Strait contribute an estimated 8 million barrels of floating capacity, extending that threshold to roughly 24 to 26 days.<\/p>\n\n    <figure class=\"obex-chart-card\">\n      <figcaption class=\"obex-chart-title\">Storage Accumulation And Shut-In Trigger Over A 30-Day Export Blackout<\/figcaption>\n      <div class=\"obex-chart-wrapper is-timeline\">\n        <canvas id=\"obex-chart-storage-timeline\" role=\"img\" aria-label=\"Line chart showing daily storage accumulation, a Day 16 shut-in trigger, and an indicative production decline path over thirty days.\"><\/canvas>\n      <\/div>\n      <p class=\"obex-chart-note\">Storage accumulation is calculated at the stated 1.5 mb\/d net surplus. The production path is indicative, anchored to the stated 3.4 mb\/d production midpoint and 2.4 mb\/d domestic refining floor.<\/p>\n      <p class=\"obex-chart-source\">OBEX Analytica assessment<\/p>\n    <\/figure>\n\n    <p class=\"obex-text\">Production curtailments do not wait for storage to hit absolute zero. Field-level coordination requires upstream operators to initiate well shut-ins approximately 16 days into a comprehensive export blackout. The National Iranian Oil Company cannot apply uniform reductions: shared fields with neighboring states \u2014 Azadegan, Yadavaran, Foroozan, and Salman \u2014 must remain active to prevent subterranean fluid migration and the permanent loss of reserves to competing jurisdictions. The shut-in burden therefore falls disproportionately onto the most commercially mature and pressure-sensitive onshore fields already operating at advanced stages of natural decline.<\/p>\n\n    <h2 class=\"obex-heading\">Subsurface Deterioration In Mature Carbonate Reservoirs<\/h2>\n\n    <p class=\"obex-text\">Iran&#8217;s production base is dominated by the Asmari and Bangestan carbonate formations. The Asmari \u2014 historically accounting for roughly 43 percent of Iran&#8217;s initial oil in place \u2014 produces through matrix permeability and supplies the Iran Light blend at 33\u00b0 API and 1.5 percent sulfur. The Bangestan system, with porosity ranges of only 4 to 15 percent, depends overwhelmingly on natural fracture networks for flow and feeds the heavier Iran Heavy blend at 29.5\u00b0 API and 1.8 percent sulfur. These are not passive storage structures; they are dynamic pressure systems maintained in equilibrium by continuous extraction, artificial lift, and injected gas.<\/p>\n\n    <figure class=\"obex-chart-card obex-diagram-card\">\n      <figcaption class=\"obex-chart-title\">Asmari\u2013Bangestan Shut-In Dynamics: Water Coning And Fracture-Pathway Risk<\/figcaption>\n      <div class=\"obex-diagram-wrap\">\n        <svg class=\"obex-diagram-svg\" viewBox=\"0 0 900 520\" role=\"img\" aria-labelledby=\"obex-diagram-title obex-diagram-desc\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\n          <title id=\"obex-diagram-title\">Conceptual cross-section of Asmari and Bangestan reservoir deterioration during shut-in conditions<\/title>\n          <desc id=\"obex-diagram-desc\">The diagram shows a vertical well crossing Asmari and Bangestan carbonate layers, upward aquifer water coning, fracture-network flow paths, wax deposition in tubing, and weakened gas reinjection pressure support.<\/desc>\n\n          <defs>\n            <marker id=\"obex-hormuz-arrow-navy\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"6\" orient=\"auto\">\n              <path d=\"M 0 0 L 12 6 L 0 12 z\" fill=\"#0F1C5C\"><\/path>\n            <\/marker>\n            <marker id=\"obex-hormuz-arrow-red\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"6\" orient=\"auto\">\n              <path d=\"M 0 0 L 12 6 L 0 12 z\" fill=\"#E60000\"><\/path>\n            <\/marker>\n            <linearGradient id=\"obex-hormuz-water-cone\" x1=\"0\" x2=\"0\" y1=\"1\" y2=\"0\">\n              <stop offset=\"0%\" stop-color=\"#E60000\" stop-opacity=\"0.45\"><\/stop>\n              <stop offset=\"100%\" stop-color=\"#E60000\" stop-opacity=\"0.12\"><\/stop>\n            <\/linearGradient>\n          <\/defs>\n\n          <rect x=\"30\" y=\"24\" width=\"840\" height=\"456\" rx=\"16\" fill=\"#FFFFFF\" stroke=\"rgba(15, 28, 92, 0.24)\" stroke-width=\"2\"><\/rect>\n\n          <rect x=\"70\" y=\"70\" width=\"760\" height=\"54\" rx=\"8\" fill=\"rgba(15, 28, 92, 0.14)\"><\/rect>\n          <text x=\"90\" y=\"103\" font-size=\"18\">Surface facilities \/ compressor and lift systems<\/text>\n\n          <path d=\"M70 150 C180 130, 280 170, 390 150 C520 128, 630 168, 830 146 L830 248 L70 248 Z\" fill=\"rgba(15, 28, 92, 0.25)\" stroke=\"#0F1C5C\" stroke-width=\"2\"><\/path>\n          <text x=\"92\" y=\"190\" font-size=\"22\">Asmari Formation<\/text>\n          <text class=\"obex-diagram-muted\" x=\"92\" y=\"218\" font-size=\"14\">Matrix permeability | Iran Light blend | pressure-sensitive near-wellbore flow<\/text>\n\n          <path d=\"M70 264 C180 244, 270 286, 380 266 C520 240, 640 286, 830 262 L830 410 L70 410 Z\" fill=\"rgba(230, 0, 0, 0.14)\" stroke=\"#E60000\" stroke-width=\"2\"><\/path>\n          <text x=\"92\" y=\"315\" font-size=\"22\">Bangestan Formation<\/text>\n          <text class=\"obex-diagram-muted\" x=\"92\" y=\"344\" font-size=\"14\">Fracture-dominated carbonate flow | Iran Heavy blend | higher restart uncertainty<\/text>\n\n          <rect x=\"70\" y=\"420\" width=\"760\" height=\"44\" rx=\"8\" fill=\"rgba(230, 0, 0, 0.25)\" stroke=\"rgba(230, 0, 0, 0.72)\" stroke-width=\"2\"><\/rect>\n          <text x=\"92\" y=\"448\" font-size=\"17\">Aquifer pressure source<\/text>\n\n          <line x1=\"455\" y1=\"96\" x2=\"455\" y2=\"390\" stroke=\"#0F1C5C\" stroke-width=\"10\" stroke-linecap=\"round\"><\/line>\n          <line x1=\"455\" y1=\"96\" x2=\"455\" y2=\"390\" stroke=\"#FFFFFF\" stroke-width=\"4\" stroke-linecap=\"round\"><\/line>\n          <text x=\"475\" y=\"118\" font-size=\"15\">Production well<\/text>\n\n          <path d=\"M405 420 C420 376, 435 338, 455 304 C480 342, 500 376, 517 420 Z\" fill=\"url(#obex-hormuz-water-cone)\" stroke=\"#E60000\" stroke-width=\"3\"><\/path>\n          <path d=\"M455 420 C455 382, 455 344, 455 304\" stroke=\"#E60000\" stroke-width=\"3\" stroke-dasharray=\"8 8\" marker-end=\"url(#obex-hormuz-arrow-red)\"><\/path>\n          <text class=\"obex-diagram-red\" x=\"535\" y=\"383\" font-size=\"15\">Water coning toward wellbore<\/text>\n\n          <path d=\"M300 302 C350 286, 405 302, 455 286 C510 268, 570 286, 632 270\" fill=\"none\" stroke=\"#0F1C5C\" stroke-width=\"4\" stroke-linecap=\"round\"><\/path>\n          <path d=\"M320 348 C370 330, 418 354, 455 332 C515 300, 592 326, 676 292\" fill=\"none\" stroke=\"rgba(15, 28, 92, 0.72)\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-dasharray=\"12 9\"><\/path>\n          <path d=\"M374 226 C418 210, 455 232, 508 210\" fill=\"none\" stroke=\"rgba(15, 28, 92, 0.72)\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"10 8\"><\/path>\n          <text x=\"620\" y=\"245\" font-size=\"15\">Fracture-network pathways<\/text>\n\n          <path d=\"M455 148 C430 162, 430 178, 455 192 C482 208, 480 224, 455 238\" fill=\"none\" stroke=\"#E60000\" stroke-width=\"4\" stroke-linecap=\"round\"><\/path>\n          <text class=\"obex-diagram-red\" x=\"500\" y=\"205\" font-size=\"15\">Wax \/ paraffin deposition risk<\/text>\n\n          <path d=\"M650 96 L650 170 L585 232\" fill=\"none\" stroke=\"#0F1C5C\" stroke-width=\"4\" stroke-dasharray=\"9 7\" marker-end=\"url(#obex-hormuz-arrow-navy)\"><\/path>\n          <text x=\"666\" y=\"130\" font-size=\"15\">Gas reinjection pressure support<\/text>\n          <text class=\"obex-diagram-muted\" x=\"666\" y=\"151\" font-size=\"13\">weakened when compressors idle<\/text>\n\n          <path d=\"M150 464 C230 440, 335 440, 455 464 C560 486, 686 484, 805 462\" fill=\"none\" stroke=\"rgba(230, 0, 0, 0.72)\" stroke-width=\"3\" stroke-dasharray=\"8 7\"><\/path>\n        <\/svg>\n      <\/div>\n      <p class=\"obex-chart-note\">Conceptual diagram only; not to scale. It visualizes the reservoir mechanisms described in the assessment rather than measured subsurface geometry.<\/p>\n      <p class=\"obex-chart-source\">OBEX Analytica assessment<\/p>\n    <\/figure>\n\n    <p class=\"obex-text\">Forcing these wells into extended shut-ins triggers a sequential chain of physical failures. Gravity-driven phase segregation drives aquifer water upward through high-permeability fracture networks \u2014 a process known as water coning \u2014 permanently altering near-wellbore relative permeability and rock wettability in ways that resist reversal. Simultaneously, cooling oil crosses its Wax Appearance Temperature, causing high-molecular-weight paraffins to crystallize inside production tubing and pore throats; wax content ranges from 3 to 44 percent of crude volume depending on field chemistry, and if cooling proceeds past gelation the flowline becomes mechanically blocked.<\/p>\n\n    <p class=\"obex-text\">A compounding failure stems from the disruption of gas reinjection programs that have historically routed approximately 4.8 billion cubic feet per day back into producing fields to sustain sweep efficiency and maintain miscibility. When compressor stations are idled and associated gas output drops due to oil shut-ins, reservoir pressure falls below minimum miscibility pressure \u2014 the threshold at which injected gas efficiently displaces crude through porous rock. Below this threshold, oil is trapped in pore spaces and entire reservoir zones become permanently inaccessible. The concurrent strikes on South Pars, which holds an estimated 1,800 trillion cubic feet of usable gas, have additionally severed the gas processing capacity that feeds this reinjection loop.<\/p>\n\n    <h2 class=\"obex-heading\">Recovery: Infrastructure Constraints And Capacity Scarring<\/h2>\n\n    <p class=\"obex-text\">Physical restoration of Kharg Island&#8217;s berths, manifolds, loading arms, and firewater systems ranges from weeks for isolated component damage to nine months or longer for severe structural failure. Subsea spool replacement and single-point mooring reconstruction can extend repair windows to four months or beyond. Mine clearance of terminal approach channels \u2014 which in historical analogues consistently outlasts steel repair as the binding recovery variable \u2014 requires countermeasure vessels, hydrographic surveys, naval escort, and insurer acceptance before tanker traffic can resume.<\/p>\n\n    <div class=\"obex-table-wrap\">\n      <table class=\"obex-data-table\">\n        <caption>Recovery Scenario Matrix: Restoration Milestones And Capacity Scarring Risk<\/caption>\n        <thead>\n          <tr>\n            <th scope=\"col\">Scenario<\/th>\n            <th scope=\"col\">Path To 70% Restoration<\/th>\n            <th scope=\"col\">Path To 88% Restoration<\/th>\n            <th scope=\"col\">Path To Full Production Restoration<\/th>\n            <th scope=\"col\">Binding Constraint<\/th>\n            <th scope=\"col\">Capacity Scarring Risk<\/th>\n          <\/tr>\n        <\/thead>\n        <tbody>\n          <tr>\n            <td>Best-case \/ isolated component damage<\/td>\n            <td>Weeks, where damage is limited to isolated terminal components.<\/td>\n            <td>Dependent on terminal approach clearance, naval escort, and insurer acceptance before tanker traffic can normalize.<\/td>\n            <td>Minimum of six months to return crude exports to pre-war levels under an optimal scenario.<\/td>\n            <td>Mine clearance and acceptance by insurers after physical repair.<\/td>\n            <td>Lower for surface assets, but permanent risk remains for the most pressure-depleted Bangestan wells.<\/td>\n          <\/tr>\n          <tr>\n            <td>Moderate damage \/ subsea and SPM bottlenecks<\/td>\n            <td>Repair window can extend to four months or beyond where subsea spool replacement or single-point mooring reconstruction is required.<\/td>\n            <td>Likely delayed by workover scarcity, sanctions-constrained parts access, and post-clearance tanker acceptance.<\/td>\n            <td>Six months or longer, depending on channel clearance and the pace of upstream workovers.<\/td>\n            <td>Subsea reconstruction, single-point mooring repair, OEM parts, and workover capacity.<\/td>\n            <td>Medium to high: ESP restart failures, wax-laden columns, sand ingress, and cross-flow may scar output.<\/td>\n          <\/tr>\n          <tr>\n            <td>Severe structural failure \/ sustained blockade aftermath<\/td>\n            <td>Nine months or longer where berths, manifolds, loading arms, or firewater systems suffer severe structural failure.<\/td>\n            <td>Not separately quantified in the assessment; restoration remains subordinate to severe terminal repair plus mine-clearance acceptance.<\/td>\n            <td>Full restoration is not guaranteed for the most pressure-depleted Bangestan wells because damage to ultimate recovery factors is likely permanent.<\/td>\n            <td>Severe terminal reconstruction, mine clearance, sanctions, finance, and upstream well intervention bottlenecks.<\/td>\n            <td>High to permanent across mature carbonate reservoirs and pressure-sensitive onshore fields.<\/td>\n          <\/tr>\n        <\/tbody>\n      <\/table>\n    <\/div>\n    <p class=\"obex-chart-source\">OBEX Analytica assessment<\/p>\n\n    <p class=\"obex-text\">Upstream restart is equally treacherous. Electric Submersible Pumps subjected to extended cold shutdowns frequently fail on restart, burning out motors or fracturing shafts under the torque required to move static, wax-laden fluid columns; each failure requires a full rig intervention to retrieve the completion string \u2014 a procedure severely bottlenecked by the scarcity of workover capacity under active sanctions. Sand ingress from backflow surges during restart can fill hundreds of feet of production tubing and demands coiled tubing cleanouts. Cross-flow between stacked reservoirs at differing pressure gradients further reduces the predictability of post-restart output and can permanently trap hydrocarbons in multi-layered Bangestan carbonates.<\/p>\n\n    <p class=\"obex-text\">The sanctions environment magnifies every repair timeline. Years of restricted access to OEM spare parts, advanced corrosion inhibitors, and operational technology have left Iran&#8217;s infrastructure with a far lower baseline resilience than during the Iran-Iraq War of the 1980s. With the rial having depreciated to approximately 1.4 to 1.5 million per U.S. dollar and inflation pressures projected to reach 180 percent under the blockade, the financial capacity required to execute complex well interventions and terminal reconstructions is severely diminished. Even under an optimal scenario \u2014 immediate cessation of hostilities, prompt diplomatic resolution, and rapid channel clearance \u2014 analysts estimate a minimum of six months to return crude exports to pre-war levels. For the most pressure-depleted Bangestan wells, the damage to ultimate recovery factors is likely permanent.<\/p>\n\n    <p class=\"obex-text\">All scenarios and analysis outcomes presented in this assessment are accessible through the interactive dashboard attached at the end of this page. The dashboard provides parametric modelling across low-, medium-, and high-intensity blockade scenarios, asset-level recovery timelines, and reservoir damage projections for each major Iranian production zone.<\/p>\n\n    <p class=\"obex-copyright\">\u00a9 2026 Obex Analytica. All rights reserved.<\/p>\n  <\/article>\n\n  <script>\n    (function () {\n      function loadChartJs(callback) {\n        if (window.Chart) {\n          callback();\n          return;\n        }\n\n        var existingScript = document.querySelector('script[src*=\"chart.js\"]');\n        if (existingScript) {\n          existingScript.addEventListener('load', callback);\n          return;\n        }\n\n        var script = document.createElement('script');\n        script.src = 'https:\/\/cdn.jsdelivr.net\/npm\/chart.js@4.4.7\/dist\/chart.umd.min.js';\n        script.onload = callback;\n        document.head.appendChild(script);\n      }\n\n      loadChartJs(function () {\n        var article = document.getElementById('obex-article-iran-oil-infrastructure-hormuz-closure');\n        if (!article || !window.Chart) return;\n\n        var isArabic = article.getAttribute('dir') === 'rtl';\n        var locale = isArabic ? 'ar-EG' : 'en-US';\n        var textDirection = isArabic ? 'rtl' : 'ltr';\n\n        var OBEX_COLORS = {\n          primary: '#0F1C5C',\n          accent: '#E60000',\n          white: '#FFFFFF',\n          primary72: 'rgba(15, 28, 92, 0.72)',\n          accent72: 'rgba(230, 0, 0, 0.72)',\n          primary45: 'rgba(15, 28, 92, 0.45)',\n          accent45: 'rgba(230, 0, 0, 0.45)',\n          primary25: 'rgba(15, 28, 92, 0.25)',\n          accent25: 'rgba(230, 0, 0, 0.25)',\n          grid: 'rgba(15, 28, 92, 0.14)',\n          muted: 'rgba(15, 28, 92, 0.68)'\n        };\n\n        Chart.defaults.font.family = isArabic\n          ? \"'IBM Plex Sans Arabic', 'IBM Plex Sans', Arial, sans-serif\"\n          : \"'IBM Plex Sans', 'IBM Plex Sans Arabic', Arial, sans-serif\";\n\n        Chart.defaults.color = OBEX_COLORS.primary;\n\n        function formatValue(value, unit) {\n          if (value === null || typeof value === 'undefined' || Number.isNaN(value)) {\n            return 'Not specified';\n          }\n\n          var number = new Intl.NumberFormat(locale, {\n            maximumFractionDigits: 2\n          }).format(value);\n\n          if (!unit) return number;\n          if (unit === '%') return number + '%';\n          if (unit === '$') return '$' + number;\n          if (unit === 'USD\/bbl') return '$' + number + '\/bbl';\n          return number + ' ' + unit;\n        }\n\n        function tooltipOptions(defaultUnit) {\n          return {\n            enabled: true,\n            rtl: isArabic,\n            textDirection: textDirection,\n            backgroundColor: OBEX_COLORS.primary,\n            titleColor: OBEX_COLORS.white,\n            bodyColor: OBEX_COLORS.white,\n            borderColor: OBEX_COLORS.accent,\n            borderWidth: 1,\n            padding: 12,\n            titleFont: { weight: '700' },\n            bodyFont: { weight: '500' },\n            callbacks: {\n              label: function (context) {\n                var label = context.dataset && context.dataset.label ? context.dataset.label + ': ' : '';\n                var unit = context.dataset && context.dataset.unit ? context.dataset.unit : defaultUnit;\n                var value;\n\n                if (context.parsed && typeof context.parsed.y !== 'undefined') {\n                  value = context.parsed.y;\n                } else if (context.parsed && typeof context.parsed.x !== 'undefined') {\n                  value = context.parsed.x;\n                } else {\n                  value = context.raw;\n                }\n\n                if (context.chart && context.chart.config && context.chart.config.type === 'bar' && context.chart.options.indexAxis === 'y') {\n                  value = context.parsed.x;\n                }\n\n                return label + formatValue(value, unit);\n              }\n            }\n          };\n        }\n\n        function legendOptions() {\n          return {\n            position: 'bottom',\n            rtl: isArabic,\n            textDirection: textDirection,\n            labels: {\n              color: OBEX_COLORS.primary,\n              font: {\n                weight: '600',\n                size: window.innerWidth < 768 ? 11 : 13\n              },\n              boxWidth: 14,\n              boxHeight: 14,\n              padding: 16\n            }\n          };\n        }\n\n        function axisTicks() {\n          return {\n            color: OBEX_COLORS.primary,\n            font: {\n              weight: '600',\n              size: window.innerWidth < 768 ? 10 : 12\n            }\n          };\n        }\n\n        var exportTerminalData = {\n          labels: ['Kharg Island', 'Jask', 'Lavan', 'Sirri'],\n          unit: 'mb\/d',\n          baselineScale: [1.4, 1.0, 0.105, 0.1],\n          sustainedUtilizationNoted: [1.4, 0, 0.105, 0.1]\n        };\n\n        var exportTerminalCanvas = document.getElementById('obex-chart-export-terminals');\n        if (exportTerminalCanvas) {\n          new Chart(exportTerminalCanvas, {\n            type: 'bar',\n            data: {\n              labels: exportTerminalData.labels,\n              datasets: [\n                {\n                  label: 'Baseline role \/ design or handling limit',\n                  unit: exportTerminalData.unit,\n                  data: exportTerminalData.baselineScale,\n                  backgroundColor: [\n                    OBEX_COLORS.accent72,\n                    OBEX_COLORS.primary45,\n                    OBEX_COLORS.primary45,\n                    OBEX_COLORS.primary45\n                  ],\n                  borderColor: [\n                    OBEX_COLORS.accent,\n                    OBEX_COLORS.primary,\n                    OBEX_COLORS.primary,\n                    OBEX_COLORS.primary\n                  ],\n                  borderWidth: 1,\n                  borderRadius: 0,\n                  borderSkipped: false,\n                  maxBarThickness: 46\n                },\n                {\n                  label: 'Sustained commercial utilization noted in text',\n                  unit: exportTerminalData.unit,\n                  data: exportTerminalData.sustainedUtilizationNoted,\n                  backgroundColor: [\n                    OBEX_COLORS.primary72,\n                    OBEX_COLORS.accent45,\n                    OBEX_COLORS.primary25,\n                    OBEX_COLORS.primary25\n                  ],\n                  borderColor: [\n                    OBEX_COLORS.primary,\n                    OBEX_COLORS.accent,\n                    OBEX_COLORS.primary,\n                    OBEX_COLORS.primary\n                  ],\n                  borderWidth: 1,\n                  borderRadius: 0,\n                  borderSkipped: false,\n                  maxBarThickness: 46\n                }\n              ]\n            },\n            options: {\n              indexAxis: 'y',\n              responsive: true,\n              maintainAspectRatio: false,\n              plugins: {\n                legend: legendOptions(),\n                tooltip: tooltipOptions(exportTerminalData.unit)\n              },\n              scales: {\n                x: {\n                  beginAtZero: true,\n                  max: 1.6,\n                  grid: { color: OBEX_COLORS.grid },\n                  ticks: axisTicks(),\n                  title: {\n                    display: true,\n                    text: 'Million barrels per day',\n                    color: OBEX_COLORS.primary,\n                    font: { weight: '700' }\n                  }\n                },\n                y: {\n                  grid: { color: OBEX_COLORS.grid },\n                  ticks: axisTicks()\n                }\n              }\n            }\n          });\n        }\n\n        var storageTimelineData = {\n          storageUnit: 'million barrels',\n          productionUnit: 'mb\/d',\n          storageAccumulation: [\n            { x: 0, y: 0 },\n            { x: 5, y: 7.5 },\n            { x: 10, y: 15 },\n            { x: 13, y: 19.5 },\n            { x: 16, y: 24 },\n            { x: 20, y: 30 },\n            { x: 22, y: 33 },\n            { x: 24, y: 36 },\n            { x: 26, y: 39 },\n            { x: 30, y: 45 }\n          ],\n          indicativeProduction: [\n            { x: 0, y: 3.4 },\n            { x: 5, y: 3.4 },\n            { x: 10, y: 3.4 },\n            { x: 13, y: 3.4 },\n            { x: 16, y: 3.25 },\n            { x: 20, y: 3.0 },\n            { x: 22, y: 2.8 },\n            { x: 24, y: 2.65 },\n            { x: 26, y: 2.55 },\n            { x: 30, y: 2.4 }\n          ],\n          triggerPoint: [{ x: 16, y: 24 }]\n        };\n\n        var timelineMarkerPlugin = {\n          id: 'obexTimelineMarkers',\n          afterDatasetsDraw: function (chart, args, pluginOptions) {\n            var options = pluginOptions || {};\n            var markers = options.markers || [];\n            var ctx = chart.ctx;\n            var chartArea = chart.chartArea;\n            var xScale = chart.scales.x;\n\n            if (!ctx || !chartArea || !xScale) return;\n\n            ctx.save();\n            markers.forEach(function (marker) {\n              var xPosition = xScale.getPixelForValue(marker.day);\n              if (xPosition < chartArea.left || xPosition > chartArea.right) return;\n\n              ctx.beginPath();\n              ctx.moveTo(xPosition, chartArea.top);\n              ctx.lineTo(xPosition, chartArea.bottom);\n              ctx.lineWidth = marker.lineWidth || 2;\n              ctx.setLineDash(marker.dash || [8, 6]);\n              ctx.strokeStyle = marker.color || OBEX_COLORS.accent;\n              ctx.stroke();\n\n              ctx.setLineDash([]);\n              ctx.fillStyle = marker.color || OBEX_COLORS.accent;\n              ctx.font = '700 12px IBM Plex Sans, Arial, sans-serif';\n              ctx.textAlign = marker.align || 'center';\n              ctx.textBaseline = 'top';\n              ctx.fillText(marker.label, xPosition + (marker.offsetX || 0), chartArea.top + (marker.offsetY || 6));\n            });\n            ctx.restore();\n          }\n        };\n\n        var storageTimelineCanvas = document.getElementById('obex-chart-storage-timeline');\n        if (storageTimelineCanvas) {\n          new Chart(storageTimelineCanvas, {\n            type: 'line',\n            data: {\n              datasets: [\n                {\n                  label: 'Storage accumulation',\n                  unit: storageTimelineData.storageUnit,\n                  data: storageTimelineData.storageAccumulation,\n                  yAxisID: 'y',\n                  borderColor: OBEX_COLORS.accent,\n                  backgroundColor: OBEX_COLORS.accent25,\n                  borderWidth: 3,\n                  pointRadius: 4,\n                  pointHoverRadius: 6,\n                  tension: 0.18,\n                  fill: false\n                },\n                {\n                  label: 'Indicative production trajectory',\n                  unit: storageTimelineData.productionUnit,\n                  data: storageTimelineData.indicativeProduction,\n                  yAxisID: 'y1',\n                  borderColor: OBEX_COLORS.primary,\n                  backgroundColor: OBEX_COLORS.primary25,\n                  borderWidth: 3,\n                  pointRadius: 4,\n                  pointHoverRadius: 6,\n                  tension: 0.18,\n                  fill: false\n                },\n                {\n                  label: 'Approximate shut-in trigger',\n                  unit: storageTimelineData.storageUnit,\n                  data: storageTimelineData.triggerPoint,\n                  yAxisID: 'y',\n                  showLine: false,\n                  borderColor: OBEX_COLORS.accent,\n                  backgroundColor: OBEX_COLORS.accent,\n                  pointRadius: 7,\n                  pointHoverRadius: 9\n                }\n              ]\n            },\n            options: {\n              responsive: true,\n              maintainAspectRatio: false,\n              parsing: false,\n              interaction: {\n                mode: 'nearest',\n                intersect: false\n              },\n              plugins: {\n                legend: legendOptions(),\n                tooltip: tooltipOptions(storageTimelineData.storageUnit),\n                obexTimelineMarkers: {\n                  markers: [\n                    {\n                      day: 16,\n                      label: 'Day 16 trigger',\n                      color: OBEX_COLORS.accent,\n                      offsetY: 8,\n                      dash: [7, 5]\n                    },\n                    {\n                      day: 24,\n                      label: 'Day 24\u201326 floating threshold',\n                      color: OBEX_COLORS.primary72,\n                      offsetX: 12,\n                      offsetY: 28,\n                      align: 'left',\n                      dash: [4, 5]\n                    },\n                    {\n                      day: 26,\n                      label: '',\n                      color: OBEX_COLORS.primary72,\n                      dash: [4, 5]\n                    }\n                  ]\n                }\n              },\n              scales: {\n                x: {\n                  type: 'linear',\n                  min: 0,\n                  max: 30,\n                  grid: { color: OBEX_COLORS.grid },\n                  ticks: {\n                    color: OBEX_COLORS.primary,\n                    stepSize: 5,\n                    font: {\n                      weight: '600',\n                      size: window.innerWidth < 768 ? 10 : 12\n                    },\n                    callback: function (value) {\n                      return 'Day ' + value;\n                    }\n                  },\n                  title: {\n                    display: true,\n                    text: 'Days since comprehensive export blackout',\n                    color: OBEX_COLORS.primary,\n                    font: { weight: '700' }\n                  }\n                },\n                y: {\n                  beginAtZero: true,\n                  position: 'left',\n                  grid: { color: OBEX_COLORS.grid },\n                  ticks: axisTicks(),\n                  title: {\n                    display: true,\n                    text: 'Accumulated surplus storage (million barrels)',\n                    color: OBEX_COLORS.accent,\n                    font: { weight: '700' }\n                  }\n                },\n                y1: {\n                  beginAtZero: true,\n                  position: 'right',\n                  min: 0,\n                  max: 4,\n                  grid: { drawOnChartArea: false },\n                  ticks: axisTicks(),\n                  title: {\n                    display: true,\n                    text: 'Production trajectory (mb\/d)',\n                    color: OBEX_COLORS.primary,\n                    font: { weight: '700' }\n                  }\n                }\n              }\n            },\n            plugins: [timelineMarkerPlugin]\n          });\n        }\n      });\n    })();\n  <\/script>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<!doctype html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \/>\n  <title>OBEX Dashboard | Iran Oil Blockade Scenario Matrix<\/title>\n<\/head>\n<body>\n  <obex-linked-dashboard><\/obex-linked-dashboard>\n\n  <script>\n  (() => {\n    const tagName = \"obex-linked-dashboard\";\n    if (customElements.get(tagName)) return;\n\n    const dashboardData = {\"meta\":{\"title\":\"Iran Oil Blockade: Production Shock Cockpit\",\"subtitle\":\"Scenario model for key export\/chokepoint inputs. Edit Assumptions to refresh formulas.\",\"eyebrow\":\"OBEX | Scenario Matrix\",\"primaryMetric\":\"Export loss\",\"secondaryMetric\":\"Production impact\",\"defaultScenario\":\"s2\",\"defaultEntity\":\"ahvaz\",\"defaultFocus\":\"storage\",\"baselineProduction\":3.4,\"baselineExports\":1.69,\"totalOilExports\":2.41},\"scenarioOrder\":[\"s0\",\"s1\",\"s2\",\"s3\",\"s4\"],\"entityOrder\":[\"ahvaz\",\"gachsaran\",\"marun\",\"aghajari\",\"karanj-parsi\"],\"focusOrder\":[\"marine\",\"terminal\",\"storage\",\"field\",\"recovery\"],\"scenarios\":{\"s0\":{\"id\":\"S0\",\"label\":\"Baseline \/ No blockade\",\"shortLabel\":\"Baseline\",\"description\":\"Exports remain open; no material marine access denial.\",\"firstAssets\":\"Normal export chain\",\"exportLoss\":[0.0,0.0,0.0],\"residualExports\":1.69,\"dailySurplus\":0.0,\"directPhysicalLoss\":0.0,\"storageFullDays\":null,\"curtailmentStart\":null,\"prodLoss\":{\"30\":0.0,\"60\":0.0,\"90\":0.0},\"remainingProd\":{\"30\":3.4,\"60\":3.4,\"90\":3.4},\"recoveryWindow\":\"Normal operations\",\"restoration\":{\"3m\":100.0,\"6m\":100.0},\"scarring\":[0.0,0.0],\"longTermCapacity\":3.4,\"riskLevel\":\"None\",\"keyDrivers\":\"None\",\"sourceNotes\":\"Model baseline\",\"stress\":8.0,\"prodPath\":[{\"day\":0,\"value\":3.4},{\"day\":7,\"value\":3.4},{\"day\":14,\"value\":3.4},{\"day\":16,\"value\":3.4},{\"day\":21,\"value\":3.4},{\"day\":30,\"value\":3.4},{\"day\":45,\"value\":3.4},{\"day\":60,\"value\":3.4}],\"storagePath\":[{\"day\":0,\"value\":0},{\"day\":7,\"value\":0},{\"day\":14,\"value\":0},{\"day\":16,\"value\":0},{\"day\":21,\"value\":0},{\"day\":30,\"value\":0},{\"day\":45,\"value\":0},{\"day\":60,\"value\":0},{\"day\":90,\"value\":0}]},\"s1\":{\"id\":\"S1\",\"label\":\"Low-intensity blockade\",\"shortLabel\":\"Low\",\"description\":\"Intermittent interdiction, insurer\/charterer withdrawal, partial cyber disruption, temporary local closures; no sustained terminal strikes.\",\"firstAssets\":\"Tanker liftings, scheduling, pilotage, floating storage management\",\"exportLoss\":[0.3,0.55,0.8],\"residualExports\":1.14,\"dailySurplus\":0.36,\"directPhysicalLoss\":0.05,\"storageFullDays\":129.2,\"curtailmentStart\":129.2,\"prodLoss\":{\"30\":0.05,\"60\":0.05,\"90\":0.05},\"remainingProd\":{\"30\":3.35,\"60\":3.35,\"90\":3.35},\"recoveryWindow\":\"Days to several weeks\",\"restoration\":{\"3m\":95.0,\"6m\":100.0},\"scarring\":[0.0,2.0],\"longTermCapacity\":3.366,\"riskLevel\":\"Low\",\"keyDrivers\":\"Diplomatic reopening, tanker availability, dispatch restoration, storage management.\",\"sourceNotes\":\"First document low-intensity range 0.3\u20130.8 mb\/d export loss.\",\"stress\":30.0,\"prodPath\":[{\"day\":0,\"value\":3.35},{\"day\":7,\"value\":3.35},{\"day\":14,\"value\":3.35},{\"day\":16,\"value\":3.35},{\"day\":21,\"value\":3.35},{\"day\":30,\"value\":3.35},{\"day\":45,\"value\":3.35},{\"day\":60,\"value\":3.35}],\"storagePath\":[{\"day\":0,\"value\":0.0},{\"day\":7,\"value\":5.4},{\"day\":14,\"value\":10.8},{\"day\":16,\"value\":12.4},{\"day\":21,\"value\":16.3},{\"day\":30,\"value\":23.2},{\"day\":45,\"value\":34.8},{\"day\":60,\"value\":46.5},{\"day\":90,\"value\":69.7}]},\"s2\":{\"id\":\"S2\",\"label\":\"Medium-intensity blockade\",\"shortLabel\":\"Medium\",\"description\":\"Repeated interdiction plus selective mining and one-off strikes on berth, manifold, loading arm, SPM, pump, power\/firewater or OT\/IT.\",\"firstAssets\":\"Kharg berth systems, Lavan SBM, Sirri jetty, feeder lines, metering, firewater\",\"exportLoss\":[1.0,1.4,1.8],\"residualExports\":0.29,\"dailySurplus\":1.21,\"directPhysicalLoss\":0.35,\"storageFullDays\":38.4,\"curtailmentStart\":16.0,\"prodLoss\":{\"30\":1.21,\"60\":1.21,\"90\":1.21},\"remainingProd\":{\"30\":2.19,\"60\":2.19,\"90\":2.19},\"recoveryWindow\":\"1\u20136 months\",\"restoration\":{\"3m\":70.0,\"6m\":88.0},\"scarring\":[3.0,8.0],\"longTermCapacity\":3.213,\"riskLevel\":\"Medium\",\"keyDrivers\":\"Mine-clearance access, localized steel\/controls replacement, partial restarts.\",\"sourceNotes\":\"First document medium-intensity range 1.0\u20131.8 mb\/d export loss; second document storage\/shut-in dynamics.\",\"stress\":58.0,\"prodPath\":[{\"day\":0,\"value\":3.05},{\"day\":7,\"value\":3.05},{\"day\":14,\"value\":3.05},{\"day\":16,\"value\":2.19},{\"day\":21,\"value\":2.19},{\"day\":30,\"value\":2.19},{\"day\":45,\"value\":2.19},{\"day\":60,\"value\":2.19}],\"storagePath\":[{\"day\":0,\"value\":0.0},{\"day\":7,\"value\":18.2},{\"day\":14,\"value\":36.4},{\"day\":16,\"value\":41.6},{\"day\":21,\"value\":54.6},{\"day\":30,\"value\":78.1},{\"day\":45,\"value\":100.0},{\"day\":60,\"value\":100.0},{\"day\":90,\"value\":100.0}]},\"s3\":{\"id\":\"S3\",\"label\":\"High-intensity \/ Kharg disabled\",\"shortLabel\":\"High\",\"description\":\"Sustained blockade with repeated strikes on Kharg, storage, metering, firewater, subsea feeders and marine approaches.\",\"firstAssets\":\"Kharg tank farm and berths, subsea feeders, mainland feeders, offshore platform manifolds, storage\",\"exportLoss\":[1.7,2.05,2.4],\"residualExports\":0.0,\"dailySurplus\":1.5,\"directPhysicalLoss\":0.75,\"storageFullDays\":31.0,\"curtailmentStart\":16.0,\"prodLoss\":{\"30\":1.5,\"60\":1.5,\"90\":1.5},\"remainingProd\":{\"30\":1.9,\"60\":1.9,\"90\":1.9},\"recoveryWindow\":\"3\u201312 months\",\"restoration\":{\"3m\":55.0,\"6m\":75.0},\"scarring\":[8.0,18.0],\"longTermCapacity\":2.958,\"riskLevel\":\"High\",\"keyDrivers\":\"Mine clearance, repeated repairs under threat, sanctions-related spares shortage, marine spread availability.\",\"sourceNotes\":\"First document high-intensity range 1.7\u20132.4 mb\/d crude\/products export loss; Kharg concentration from both docs.\",\"stress\":78.0,\"prodPath\":[{\"day\":0,\"value\":2.65},{\"day\":7,\"value\":2.65},{\"day\":14,\"value\":2.65},{\"day\":16,\"value\":1.9},{\"day\":21,\"value\":1.9},{\"day\":30,\"value\":1.9},{\"day\":45,\"value\":1.9},{\"day\":60,\"value\":1.9}],\"storagePath\":[{\"day\":0,\"value\":0.0},{\"day\":7,\"value\":22.6},{\"day\":14,\"value\":45.2},{\"day\":16,\"value\":51.6},{\"day\":21,\"value\":67.7},{\"day\":30,\"value\":96.8},{\"day\":45,\"value\":100.0},{\"day\":60,\"value\":100.0},{\"day\":90,\"value\":100.0}]},\"s4\":{\"id\":\"S4\",\"label\":\"Extreme \/ Systemic shut-in\",\"shortLabel\":\"Extreme\",\"description\":\"Full or near-full export shutdown plus direct damage to terminal, pressure-maintenance, tankage, subsea feeders and mature-field restart systems.\",\"firstAssets\":\"Kharg, Ganaveh\/Ghurreh nodes, mature onshore fields, gas-reinjection\/compression, tankage, OT\/IT\",\"exportLoss\":[1.9,2.2,2.41],\"residualExports\":0.0,\"dailySurplus\":1.5,\"directPhysicalLoss\":2.0,\"storageFullDays\":31.0,\"curtailmentStart\":16.0,\"prodLoss\":{\"30\":2.0,\"60\":2.0,\"90\":2.0},\"remainingProd\":{\"30\":1.4,\"60\":1.4,\"90\":1.4},\"recoveryWindow\":\"6\u201324+ months\",\"restoration\":{\"3m\":35.0,\"6m\":60.0},\"scarring\":[15.0,35.0],\"longTermCapacity\":2.55,\"riskLevel\":\"Extreme\",\"keyDrivers\":\"Mass shut-ins, water coning, wax\/asphaltene, ESP failures, pressure-support disruption, corrosion.\",\"sourceNotes\":\"Second document recovery table and storage crisis; first document severe terminal and well-control timelines.\",\"stress\":94.0,\"prodPath\":[{\"day\":0,\"value\":1.4},{\"day\":7,\"value\":1.4},{\"day\":14,\"value\":1.4},{\"day\":16,\"value\":1.4},{\"day\":21,\"value\":1.4},{\"day\":30,\"value\":1.4},{\"day\":45,\"value\":1.4},{\"day\":60,\"value\":1.4}],\"storagePath\":[{\"day\":0,\"value\":0.0},{\"day\":7,\"value\":22.6},{\"day\":14,\"value\":45.2},{\"day\":16,\"value\":51.6},{\"day\":21,\"value\":67.7},{\"day\":30,\"value\":96.8},{\"day\":45,\"value\":100.0},{\"day\":60,\"value\":100.0},{\"day\":90,\"value\":100.0}]}},\"entities\":{\"ahvaz\":{\"label\":\"Ahvaz\",\"rank\":1,\"type\":\"Asmari & Bangestan\",\"beta\":\"Highest field beta\",\"productionMbd\":0.7,\"estimatedKbpd\":700.0,\"share\":20.6,\"shareRaw\":0.2059,\"characteristics\":\"Highly mature, massive carbonate structure; central southwest production pillar.\",\"vulnerability\":\"Water coning, pressure redistribution, wax\/asphaltene restart risk under prolonged shut-in.\",\"mitigation\":\"Prioritize pressure monitoring, staged restart, chemical treatment, workover capacity.\",\"sourceNotes\":\"Second document Table 3.\",\"weights\":{\"marine\":0.79,\"terminal\":0.84,\"storage\":0.89,\"field\":0.98,\"recovery\":0.98},\"bufferScore\":14,\"producerSensitivity\":0.98},\"gachsaran\":{\"label\":\"Gachsaran\",\"rank\":2,\"type\":\"Asmari & Bangestan\",\"beta\":\"High field beta\",\"productionMbd\":0.56,\"estimatedKbpd\":560.0,\"share\":16.5,\"shareRaw\":0.1647,\"characteristics\":\"Pressure-support dependent mature field.\",\"vulnerability\":\"Pressure-maintenance interruption can reduce sweep efficiency and restart performance.\",\"mitigation\":\"Gas reinjection integrity, conservative drawdown, well-by-well triage.\",\"sourceNotes\":\"Second document Table 3.\",\"weights\":{\"marine\":0.73,\"terminal\":0.79,\"storage\":0.84,\"field\":0.93,\"recovery\":0.98},\"bufferScore\":14,\"producerSensitivity\":0.93},\"marun\":{\"label\":\"Marun\",\"rank\":3,\"type\":\"Asmari\",\"beta\":\"High field beta\",\"productionMbd\":0.52,\"estimatedKbpd\":520.0,\"share\":15.3,\"shareRaw\":0.1529,\"characteristics\":\"Mature supergiant with H2S risks from Bangestan source rocks.\",\"vulnerability\":\"Sour-service corrosion and ESP restart stress if fluids stagnate.\",\"mitigation\":\"Corrosion inhibitors, ESP inspection\/replacement, staged flowback.\",\"sourceNotes\":\"Second document Table 3.\",\"weights\":{\"marine\":0.71,\"terminal\":0.77,\"storage\":0.82,\"field\":0.98,\"recovery\":0.98},\"bufferScore\":14,\"producerSensitivity\":0.98},\"aghajari\":{\"label\":\"Aghajari\",\"rank\":4,\"type\":\"Asmari & Bangestan\",\"beta\":\"Selective restart beta\",\"productionMbd\":0.2,\"estimatedKbpd\":200.0,\"share\":5.9,\"shareRaw\":0.0588,\"characteristics\":\"Mature field with rapid natural decline requiring reinjection.\",\"vulnerability\":\"Long shut-ins raise risk of production not returning to prior plateau.\",\"mitigation\":\"Pressure support, stimulation\/workover, restart chemistry.\",\"sourceNotes\":\"Second document Table 3.\",\"weights\":{\"marine\":0.57,\"terminal\":0.65,\"storage\":0.71,\"field\":0.8,\"recovery\":0.92},\"bufferScore\":23.2,\"producerSensitivity\":0.8},\"karanj-parsi\":{\"label\":\"Karanj-Parsi\",\"rank\":5,\"type\":\"Asmari & Bangestan\",\"beta\":\"Selective restart beta\",\"productionMbd\":0.2,\"estimatedKbpd\":200.0,\"share\":5.9,\"shareRaw\":0.0588,\"characteristics\":\"Fractured carbonate network.\",\"vulnerability\":\"Fracture-driven water encroachment and crossflow risk.\",\"mitigation\":\"Water shutoff treatments, controlled drawdown, workover allocation.\",\"sourceNotes\":\"Second document Table 3.\",\"weights\":{\"marine\":0.57,\"terminal\":0.65,\"storage\":0.71,\"field\":0.79,\"recovery\":0.91},\"bufferScore\":23.7,\"producerSensitivity\":0.79}},\"channels\":{\"marine\":{\"label\":\"Marine access\",\"layer\":\"Export gate\",\"body\":\"Access denial begins at the export gate: tanker liftings, insurance or charterer withdrawal, pilotage constraints, local closures and mined approaches can reduce crude liftings before reservoir damage appears.\",\"layerCopy\":\"Residual export capacity is the first variable that determines whether surplus barrels accumulate.\",\"timing\":\"Immediate\",\"timingCopy\":\"The workbook models export loss as the first shock, with storage and field curtailments following as the system runs out of outlets.\",\"weightCopy\":\"Field exposure is indirect: large fields feel the shock through national export capacity and storage back-pressure.\",\"intensity\":{\"s0\":0,\"s1\":22.8,\"s2\":58.1,\"s3\":85.1,\"s4\":91.3}},\"terminal\":{\"label\":\"Terminal assets\",\"layer\":\"Physical bottleneck\",\"body\":\"Terminal assets convert a marine blockade into harder production constraints when berth systems, SBM\/SPM equipment, metering, firewater, OT\/IT, subsea feeders or tank farms are damaged.\",\"layerCopy\":\"These nodes are high-leverage: export capacity can fall even while wells and reservoirs remain physically intact.\",\"timing\":\"Days to months\",\"timingCopy\":\"Repair ranges in the workbook span days for light components and several months for severe berth, tank farm, subsea or approach-clearing cases.\",\"weightCopy\":\"Field exposure rises with production share and dependency on export-chain continuity.\",\"intensity\":{\"s0\":1.4,\"s1\":7.6,\"s2\":26.2,\"s3\":47.8,\"s4\":100}},\"storage\":{\"label\":\"Storage pressure\",\"layer\":\"Curtailment trigger\",\"body\":\"Storage pressure is the bridge between export denial and forced shut-in. Surplus crude accumulates when production exceeds domestic absorption plus residual exports.\",\"layerCopy\":\"The central model uses effective storage headroom and daily surplus to estimate days to tank-top or earlier operational curtailment.\",\"timing\":\"Day-16 signal in severe cases\",\"timingCopy\":\"Medium, high and extreme cases show an operational curtailment signal around day 16 in the scenario matrix.\",\"weightCopy\":\"Field exposure is higher for large barrels that become difficult to route when storage space disappears.\",\"intensity\":{\"s0\":0,\"s1\":21.3,\"s2\":86.9,\"s3\":100,\"s4\":100}},\"field\":{\"label\":\"Field shut-in\",\"layer\":\"Reservoir \/ restart layer\",\"body\":\"Field shut-in risk concentrates in mature carbonate systems where pressure support, water coning, wax or asphaltene deposition, ESP stress, sour-service corrosion and crossflow can slow restart.\",\"layerCopy\":\"The field panel applies the selected field\u2019s production share and vulnerability text to the total scenario loss.\",\"timing\":\"After curtailment\",\"timingCopy\":\"Direct physical loss and storage-driven curtailment determine the modeled production loss at days 30, 60 and 90.\",\"weightCopy\":\"The selected field weight is driven by production share plus the qualitative restart vulnerabilities listed in the workbook.\",\"intensity\":{\"s0\":0,\"s1\":2.4,\"s2\":45.8,\"s3\":61.2,\"s4\":95.6}},\"recovery\":{\"label\":\"Recovery \/ scarring\",\"layer\":\"Restoration layer\",\"body\":\"Recovery capacity determines how much lost output returns after reopening. Severe cases introduce capacity scarring through damaged infrastructure, mature-field restart problems and constrained critical resources.\",\"layerCopy\":\"The scenario matrix provides recovery windows, 3M and 6M restoration rates, scarring bands and long-term sustainable capacity.\",\"timing\":\"Months to 24+ months\",\"timingCopy\":\"Recovery windows range from normal operations to 6\u201324+ months in the extreme systemic shut-in case.\",\"weightCopy\":\"Field exposure is tied to vulnerability and the ability to sequence safe, high-return restarts.\",\"intensity\":{\"s0\":0,\"s1\":6.2,\"s2\":28.1,\"s3\":55.4,\"s4\":99.8}}},\"assumptions\":{\"crude-production-operational-output\":{\"category\":\"Baseline\",\"label\":\"Crude production \/ operational output\",\"central\":3.4,\"low\":3.1,\"high\":3.5,\"unit\":\"mb\/d\",\"used\":\"Yes\",\"notes\":\"Mid-3 mb\/d production backbone used as baseline for curtailment model.\",\"source\":\"User docs; EIA background\"},\"crude-condensate-exports\":{\"category\":\"Baseline\",\"label\":\"Crude & condensate exports\",\"central\":1.69,\"low\":1.483,\"high\":1.7,\"unit\":\"mb\/d\",\"used\":\"Yes\",\"notes\":\"2025 Hormuz crude\/condensate export estimate with 2024 EIA lower bound.\",\"source\":\"IEA; EIA\"},\"oil-product-exports-via-hormuz\":{\"category\":\"Baseline\",\"label\":\"Oil product exports via Hormuz\",\"central\":0.72,\"low\":0.7,\"high\":0.75,\"unit\":\"mb\/d\",\"used\":\"Context\",\"notes\":\"Product exports add to total oil-flow loss, but crude production balance uses crude exports.\",\"source\":\"IEA; user docs\"},\"total-iran-crude-product-exports-via-hormuz\":{\"category\":\"Baseline\",\"label\":\"Total Iran crude\/product exports via Hormuz\",\"central\":2.41,\"low\":2.183,\"high\":2.45,\"unit\":\"mb\/d\",\"used\":\"Context\",\"notes\":\"Crude\/condensate plus oil products.\",\"source\":\"IEA; user docs\"},\"domestic-refining-internal-crude-absorption\":{\"category\":\"Domestic absorption\",\"label\":\"Domestic refining \/ internal crude absorption\",\"central\":1.9,\"low\":1.8,\"high\":2.4,\"unit\":\"mb\/d\",\"used\":\"Yes\",\"notes\":\"Central value bridges two document estimates: domestic floor around 1.8 mb\/d and refining capacity\/process capacity near 2.0\u20132.4 mb\/d.\",\"source\":\"User docs\"},\"onshore-working-storage-headroom\":{\"category\":\"Storage\",\"label\":\"Onshore working storage headroom\",\"central\":38.5,\"low\":35.0,\"high\":42.0,\"unit\":\"million bbl\",\"used\":\"Yes\",\"notes\":\"Available working capacity after tanks already partly full.\",\"source\":\"User docs\"},\"floating-storage-relief\":{\"category\":\"Storage\",\"label\":\"Floating storage relief\",\"central\":8.0,\"low\":0.0,\"high\":8.0,\"unit\":\"million bbl\",\"used\":\"Yes\",\"notes\":\"Iran-linked VLCCs inside Hormuz can provide temporary floating storage relief.\",\"source\":\"User docs\"},\"effective-storage-headroom\":{\"category\":\"Storage\",\"label\":\"Effective storage headroom\",\"central\":46.5,\"low\":35.0,\"high\":50.0,\"unit\":\"million bbl\",\"used\":\"Yes\",\"notes\":\"Onshore plus floating storage; central drives days-to-curtailment formulas.\",\"source\":\"Model formula\"},\"kharg-share-of-crude-exports\":{\"category\":\"Export concentration\",\"label\":\"Kharg share of crude exports\",\"central\":0.9,\"low\":0.9,\"high\":0.94,\"unit\":\"share\",\"used\":\"Context\",\"notes\":\"Kharg is the dominant export node; Kpler-based reporting places recent share above 90%.\",\"source\":\"Reuters; Kpler; user docs\"},\"jask-usable-relief-capacity\":{\"category\":\"Bypass\",\"label\":\"Jask usable relief capacity\",\"central\":0.05,\"low\":0.0,\"high\":0.1,\"unit\":\"mb\/d\",\"used\":\"Context\",\"notes\":\"Designed capacity is much higher, but both documents treat Jask as effectively non-operational for wartime diversion.\",\"source\":\"IEA; user docs\"},\"severe-outage-early-curtailment-trigger\":{\"category\":\"Timing\",\"label\":\"Severe-outage early curtailment trigger\",\"central\":16.0,\"low\":13.0,\"high\":22.0,\"unit\":\"days\",\"used\":\"Yes\",\"notes\":\"For severe export disruption, curtailments begin before absolute storage capacity is exhausted.\",\"source\":\"User docs\"},\"residual-exports-under-enforced-blockade\":{\"category\":\"Residual exports\",\"label\":\"Residual exports under enforced blockade\",\"central\":0.3,\"low\":0.2,\"high\":0.4,\"unit\":\"mb\/d\",\"used\":\"Context\",\"notes\":\"Second document cites export collapse to roughly 200\u2013400 kb\/d under enforced blockade.\",\"source\":\"User docs\"},\"day-30-horizon\":{\"category\":\"Model horizon\",\"label\":\"Day 30 horizon\",\"central\":30.0,\"low\":30.0,\"high\":30.0,\"unit\":\"days\",\"used\":\"Yes\",\"notes\":\"Near-term production impact checkpoint.\",\"source\":\"Model setting\"},\"day-60-horizon\":{\"category\":\"Model horizon\",\"label\":\"Day 60 horizon\",\"central\":60.0,\"low\":60.0,\"high\":60.0,\"unit\":\"days\",\"used\":\"Yes\",\"notes\":\"Medium-term production impact checkpoint.\",\"source\":\"Model setting\"},\"day-90-horizon\":{\"category\":\"Model horizon\",\"label\":\"Day 90 horizon\",\"central\":90.0,\"low\":90.0,\"high\":90.0,\"unit\":\"days\",\"used\":\"Yes\",\"notes\":\"Three-month production impact checkpoint.\",\"source\":\"Model setting\"}},\"assetRows\":[{\"asset\":\"Individual onshore wellhead \/ tree \/ manifold\",\"package\":\"Isolate well; replace valves\/tree\/spools; pressure test; cautious restart\",\"bestLow\":3,\"bestHigh\":14,\"severeLow\":14,\"severeHigh\":56,\"constraints\":\"Workover rig, pressure-control package, valves\/seals, welders, HSE, restart chemistry\",\"implication\":\"Usually localized. Capacity loss remains small unless many wells are affected simultaneously.\",\"sourceNotes\":\"First document repair table.\"},{\"asset\":\"Offshore platform well or well cluster\",\"package\":\"Stabilize platform; suppress fire; replace topside controls; verify integrity\",\"bestLow\":7,\"bestHigh\":28,\"severeLow\":30,\"severeHigh\":90,\"constraints\":\"Crane support, offshore construction crews, E&I technicians, firefighting, power, marine\/helicopter access\",\"implication\":\"Can isolate field clusters and disrupt offshore blends such as Aboozar\/Foroozan\/Dorood.\",\"sourceNotes\":\"First document repair table.\"},{\"asset\":\"Well blowout or mass well fires\",\"package\":\"Cap\/extinguish; debris removal; cleanup; possible relief well; rebuild surface equipment\",\"bestLow\":14,\"bestHigh\":56,\"severeLow\":60,\"severeHigh\":365,\"constraints\":\"Specialist well-control teams, capping stacks, relief-well rigs, water\/foam, exclusion zones\",\"implication\":\"Creates the longest direct production-capacity impairment and potential capacity scarring.\",\"sourceNotes\":\"First document with Kuwait analogue.\"},{\"asset\":\"Onshore gathering \/ trunk pipeline rupture\",\"package\":\"Isolate; cut out damaged section; weld replacement spool; hydrotest; recommission\",\"bestLow\":5,\"bestHigh\":21,\"severeLow\":30,\"severeHigh\":90,\"constraints\":\"Large-diameter pipe, NDT, valves, pigs, hydrotest pumps, ROW security, power\/telecom\",\"implication\":\"Can back up southwest onshore fields even if wells remain intact.\",\"sourceNotes\":\"First document repair table.\"},{\"asset\":\"Subsea flowline \/ jumper \/ feeder\",\"package\":\"Clamp or spool repair; isolate\/cut\/replace; test and restart\",\"bestLow\":7,\"bestHigh\":28,\"severeLow\":30,\"severeHigh\":180,\"constraints\":\"ROV\/divers, support vessel, lifting frames, clamps\/spools, weather window, mine-free access\",\"implication\":\"Can isolate offshore production and reduce exportable crude before terminal repairs are complete.\",\"sourceNotes\":\"First document repair table.\"},{\"asset\":\"Fixed jetty \/ loading arms \/ berth systems\",\"package\":\"Temporary steelwork and hose\/arm replacement; later permanent civil\/piping repair\",\"bestLow\":7,\"bestHigh\":21,\"severeLow\":30,\"severeHigh\":270,\"constraints\":\"Loading arms, hydraulics, manifolds, metering, fire pumps, civil contractors, recommissioning\",\"implication\":\"High leverage: can halt exports without damaging reservoirs.\",\"sourceNotes\":\"First document repair table and Kharg precedent.\"},{\"asset\":\"SBM\/SPM buoy \/ hose \/ hawser \/ swivel\",\"package\":\"Replace hoses\/hawsers\/swivel or buoy\/anchoring package\",\"bestLow\":3,\"bestHigh\":21,\"severeLow\":30,\"severeHigh\":120,\"constraints\":\"Specialized marine contractors, buoy parts, chain\/anchor gear, tug support, calibration\",\"implication\":\"A single-point failure can temporarily remove Lavan\/Sirri\/Jask-style export capacity.\",\"sourceNotes\":\"First document repair table; CPC analogue.\"},{\"asset\":\"Tank farm and storage\",\"package\":\"Roof\/rim-seal repair; shell\/floor\/piping\/instrumentation repair; sludge removal\",\"bestLow\":1,\"bestHigh\":14,\"severeLow\":30,\"severeHigh\":180,\"constraints\":\"Foam\/fire teams, floating-roof parts, shell plates, civil works, gas-freeing\",\"implication\":\"Lost storage accelerates forced shut-ins and constrains restarts.\",\"sourceNotes\":\"First document repair table; second document storage stress.\"},{\"asset\":\"Terminal OT\/IT systems\",\"package\":\"Restore dispatch, metering, safety logic, backups, communications; validate field devices\",\"bestLow\":3,\"bestHigh\":10,\"severeLow\":14,\"severeHigh\":84,\"constraints\":\"OT engineers, backups, firmware, controllers, instrument techs, vendor support, forensics\",\"implication\":\"Can halt loading even with intact steel; recovery depends on trustworthy control boundaries.\",\"sourceNotes\":\"First document repair table; cyber precedents.\"},{\"asset\":\"Mined or obstructed approaches\",\"package\":\"Survey, sweep, clear, verify channel, reopen under naval control\",\"bestLow\":7,\"bestHigh\":42,\"severeLow\":60,\"severeHigh\":180,\"constraints\":\"Mine-countermeasure vessels, hydrography, naval cover, legal reopening, insurer acceptance\",\"implication\":\"Often the binding constraint even after physical repairs are complete.\",\"sourceNotes\":\"First document repair table.\"}],\"sourceNotes\":[{\"type\":\"Uploaded file\",\"name\":\"How a Blockade Could Disrupt Iran\u2019s Oil Export Infrastructure.docx\",\"usedFor\":\"Scenario export-loss bands; asset repair timelines; Kharg\/Jask\/Lavan\/Sirri system mapping\",\"values\":\"Low 0.3\u20130.8 mb\/d; Medium 1.0\u20131.8 mb\/d; High 1.7\u20132.4 mb\/d; repair ranges by asset\",\"reliability\":\"Primary input. Analytical estimates, not forecasts.\",\"lastChecked\":\"2026-04-27\",\"treatment\":\"Directly used in Scenario_Matrix and Asset_Recovery.\"},{\"type\":\"Uploaded file\",\"name\":\"Iran Oil Infrastructure Blockade Impact.docx\",\"usedFor\":\"Storage math, field exposure, recovery percentages, petrophysical shut-in risks\",\"values\":\"Storage 35\u201342 Mbbl + 8 Mbbl floating; curtailment around 16 days; field production table; 70%\/88% restoration references\",\"reliability\":\"Primary input. Some event claims should be treated as scenario assumptions unless independently verified.\",\"lastChecked\":\"2026-04-27\",\"treatment\":\"Used in Assumptions, ShutIn_Model, Field_Exposure.\"},{\"type\":\"Public source\",\"name\":\"IEA Strait of Hormuz factsheet\",\"usedFor\":\"Baseline Hormuz flows and Iran crude\/product exports context\",\"values\":\"Iran 2025 crude\/condensate and product flows via Hormuz; nearly 20 mb\/d regional chokepoint context\",\"reliability\":\"Official energy agency source.\",\"lastChecked\":\"2026-04-27\",\"treatment\":\"Sanity check for baseline and source notes.\"},{\"type\":\"Public source\",\"name\":\"EIA Report on Iranian Petroleum and Petroleum Products Exports\",\"usedFor\":\"2024 crude\/condensate export lower bound\",\"values\":\"2024 crude & condensate exports: 1.483 mb\/d; exports to China 1.444 mb\/d\",\"reliability\":\"Official U.S. government source; 2025 report for 2024 exports.\",\"lastChecked\":\"2026-04-27\",\"treatment\":\"Low-end export benchmark in Assumptions.\"},{\"type\":\"Public source\",\"name\":\"Reuters: Kharg Island, struck by US, is key hub for Iran oil exports\",\"usedFor\":\"Kharg concentration sanity check\",\"values\":\"Kharg handles around 90% of Iranian oil shipments in cited reporting.\",\"reliability\":\"Reputable news source; used for high-level concentration only.\",\"lastChecked\":\"2026-04-27\",\"treatment\":\"Supports Kharg-share assumption.\"},{\"type\":\"Public source\",\"name\":\"Kpler: Kharg Island backbone\/vulnerability\",\"usedFor\":\"Kharg share and storage context\",\"values\":\"Kpler cited 94% of recent crude exports from Kharg and 31 Mbbl storage.\",\"reliability\":\"Commercial analytics source; useful but not independently auditable in full.\",\"lastChecked\":\"2026-04-27\",\"treatment\":\"Supports range around Kharg concentration.\"},{\"type\":\"Public source\",\"name\":\"SPE\/JPT: Managing risk and reducing damage from well shut-ins\",\"usedFor\":\"General shut-in mechanisms and restart risk\",\"values\":\"Wells can suffer restart impairment; damage depends on duration and reservoir\/mechanical conditions.\",\"reliability\":\"Technical trade source.\",\"lastChecked\":\"2026-04-27\",\"treatment\":\"Used qualitatively for field-risk notes.\"},{\"type\":\"Public source\",\"name\":\"ABS Subsea Inspection, Maintenance, and Repair Advisory\",\"usedFor\":\"Subsea repair logic\",\"values\":\"Clamp vs. replacement categories; inspection and repair constraints.\",\"reliability\":\"Technical guidance source.\",\"lastChecked\":\"2026-04-27\",\"treatment\":\"Used qualitatively in Asset_Recovery.\"},{\"type\":\"Public source\",\"name\":\"Penspen Emergency Pipeline Repair Systems paper\",\"usedFor\":\"Pipeline emergency repair preparedness\",\"values\":\"Preparedness and pre-stocked repair systems reduce downtime.\",\"reliability\":\"Technical paper.\",\"lastChecked\":\"2026-04-27\",\"treatment\":\"Used qualitatively in Asset_Recovery.\"}],\"caveats\":[\"Model caveats\",\"The matrix quantifies impact on production capability using export-denial, storage, direct physical damage, and recovery\/scarring assumptions. It is an analytical scenario model, not a prediction.\",\"Export-loss numbers are drawn from the uploaded documents and capped against crude exports when modeling crude production balance; product-export losses are retained as market\/context exposure.\",\"Days-to-curtailment is sensitive to storage headroom and domestic absorption. Adjust Assumptions!C9:C12 to test alternative storage\/refinery cases.\",\"The model intentionally separates 'exports halted' from 'wells destroyed' because blockade pressure typically cuts exports before it damages reservoirs.\"],\"monitorDefs\":[{\"key\":\"export\",\"label\":\"Export denial\",\"desc\":\"Central export loss versus total crude\/product exports via Hormuz.\",\"good\":false},{\"key\":\"storage\",\"label\":\"Storage pressure\",\"desc\":\"Modeled uncurtailed storage fill at day 30 and curtailment urgency.\",\"good\":false},{\"key\":\"terminal\",\"label\":\"Terminal repair stress\",\"desc\":\"Direct physical loss and repair complexity across loading, tankage and OT\/IT nodes.\",\"good\":false},{\"key\":\"field\",\"label\":\"Field restart risk\",\"desc\":\"Selected field exposure weighted by mature-field vulnerability.\",\"good\":false},{\"key\":\"recovery\",\"label\":\"Scarring risk\",\"desc\":\"Long-term capacity scarring and lower three-month restoration.\",\"good\":false},{\"key\":\"buffers\",\"label\":\"Operational buffer\",\"desc\":\"Residual exports, domestic absorption and selected field resilience.\",\"good\":true}],\"focusLinkMap\":{\"marine\":[\"shock-marine\",\"marine-residual\",\"marine-storage\",\"marine-terminal\"],\"terminal\":[\"shock-marine\",\"marine-terminal\",\"terminal-storage\",\"terminal-production\"],\"storage\":[\"marine-storage\",\"terminal-storage\",\"storage-production\",\"storage-field\"],\"field\":[\"storage-field\",\"field-production\",\"field-recovery\"],\"recovery\":[\"field-recovery\",\"production-recovery\",\"recovery-capacity\"]}};\n\n    const template = document.createElement(\"template\");\n    template.innerHTML = `\n      <style>\n        @font-face {\n          font-family: \"OBEX Plex\";\n          src:\n            local(\"IBM Plex Sans\"),\n            url(\".\/obex-fonts\/IBMPlexSans-VariableFont_wdth,wght.woff2\") format(\"woff2\"),\n            url(\".\/IBMPlexSans-VariableFont_wdth,wght.woff2\") format(\"woff2\");\n          font-weight: 100 700;\n          font-style: normal;\n          font-display: swap;\n          unicode-range: U+0000-00FF, U+0100-024F, U+1E00-1EFF, U+2000-206F, U+20A0-20CF, U+2100-214F, U+2190-21FF, U+2200-22FF, U+25A0-25FF, U+FB00-FB06;\n        }\n\n        @font-face {\n          font-family: \"OBEX Plex\";\n          src:\n            local(\"IBM Plex Sans Arabic\"),\n            url(\".\/obex-fonts\/IBMPlexSansArabic-Regular.woff2\") format(\"woff2\"),\n            url(\".\/IBMPlexSansArabic-Regular.woff2\") format(\"woff2\");\n          font-weight: 100 700;\n          font-style: normal;\n          font-display: swap;\n          unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+FB50-FDFF, U+FE70-FEFF;\n        }\n\n        :host {\n          --obex-navy: #0F1C5C;\n          --obex-red: #E60000;\n          --obex-white: #FFFFFF;\n          --obex-soft: #F4F6FB;\n          --obex-soft-2: #EEF1F8;\n          --obex-ink: #141B40;\n          --obex-muted: #58607F;\n          --obex-line: rgba(15, 28, 92, 0.16);\n          --obex-line-strong: rgba(15, 28, 92, 0.24);\n          --obex-red-soft: rgba(230, 0, 0, 0.08);\n          --obex-navy-soft: rgba(15, 28, 92, 0.06);\n          display: block;\n          width: 100%;\n          container-type: inline-size;\n          font-family: \"OBEX Plex\", \"IBM Plex Sans\", \"IBM Plex Sans Arabic\", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Tahoma, Arial, sans-serif;\n          color: var(--obex-ink);\n        }\n\n        * { box-sizing: border-box; }\n        button, input, select, textarea { font: inherit; }\n        button { -webkit-tap-highlight-color: transparent; }\n        .shell {\n          width: 100%;\n          max-width: min(1100px, 100%);\n          margin: 0 auto;\n          padding: clamp(12px, 2cqi, 18px);\n          border: 2px solid var(--obex-navy);\n          border-radius: 28px;\n          background:\n            radial-gradient(circle at 88% 8%, rgba(230,0,0,0.10), transparent 25%),\n            radial-gradient(circle at 100% 100%, rgba(15,28,92,0.05), transparent 22%),\n            linear-gradient(180deg, var(--obex-white), #F8FAFF 58%, #F3F6FD 100%);\n          box-shadow: 0 14px 34px rgba(15, 28, 92, 0.09);\n          overflow: hidden;\n        }\n\n        .command {\n          padding: clamp(8px, 1.4cqi, 14px) clamp(8px, 1.6cqi, 14px) 8px;\n        }\n\n        .topline {\n          display: flex;\n          align-items: center;\n          justify-content: space-between;\n          gap: 10px;\n          flex-wrap: wrap;\n          margin-bottom: 8px;\n        }\n\n        .eyebrow {\n          display: inline-flex;\n          align-items: center;\n          gap: 7px;\n          padding: 6px 10px;\n          border: 1px solid var(--obex-line-strong);\n          border-radius: 999px;\n          background: rgba(255,255,255,0.82);\n          color: var(--obex-navy);\n          font-size: 0.72rem;\n          line-height: 1;\n          font-weight: 700;\n          letter-spacing: 0.06em;\n          text-transform: uppercase;\n        }\n\n        .eyebrow .dot {\n          width: 8px;\n          height: 8px;\n          border-radius: 999px;\n          background: var(--obex-red);\n          box-shadow: 0 0 0 5px var(--obex-red-soft);\n        }\n\n        .state-badge {\n          max-width: 100%;\n          display: inline-flex;\n          align-items: center;\n          gap: 7px;\n          padding: 6px 10px;\n          border-radius: 999px;\n          background: var(--obex-navy);\n          color: var(--obex-white);\n          font-size: 0.74rem;\n          line-height: 1.2;\n          font-weight: 650;\n          box-shadow: 0 8px 18px rgba(15, 28, 92, 0.14);\n        }\n\n        .state-badge b {\n          color: var(--obex-white);\n          font-weight: 700;\n        }\n\n        h1 {\n          margin: 0;\n          color: var(--obex-navy);\n          font-weight: 700;\n          letter-spacing: -0.055em;\n          line-height: 0.95;\n          font-size: clamp(1.9rem, 4.5cqi, 3.05rem);\n        }\n\n        .subtitle {\n          max-width: 880px;\n          margin: 8px 0 0;\n          color: var(--obex-muted);\n          font-size: clamp(0.82rem, 1.2cqi, 0.96rem);\n          line-height: 1.45;\n        }\n\n        .briefing {\n          margin: 12px 0 0;\n          padding: 12px 14px;\n          border: 1px solid var(--obex-line);\n          border-radius: 18px;\n          background: rgba(255,255,255,0.72);\n          color: var(--obex-ink);\n          font-size: 0.9rem;\n          line-height: 1.45;\n        }\n\n        .control-rail {\n          display: grid;\n          grid-template-columns: minmax(0, 1.06fr) minmax(0, 1.06fr) minmax(0, 0.92fr);\n          gap: 10px;\n          margin: 10px 0 12px;\n        }\n\n        .control-card {\n          min-width: 0;\n          padding: 11px;\n          border: 1px solid var(--obex-line);\n          border-radius: 20px;\n          background: rgba(255,255,255,0.86);\n        }\n\n        .control-head {\n          display: flex;\n          align-items: baseline;\n          justify-content: space-between;\n          gap: 8px;\n          margin-bottom: 8px;\n        }\n\n        .control-head span {\n          color: var(--obex-navy);\n          font-size: 0.77rem;\n          font-weight: 700;\n          letter-spacing: 0.04em;\n          text-transform: uppercase;\n        }\n\n        .control-head small {\n          color: var(--obex-muted);\n          font-size: 0.7rem;\n          white-space: nowrap;\n        }\n\n        .button-group {\n          display: flex;\n          flex-wrap: wrap;\n          gap: 6px;\n        }\n\n        .chip {\n          appearance: none;\n          border: 1px solid var(--obex-line-strong);\n          background: #fff;\n          color: var(--obex-navy);\n          border-radius: 999px;\n          padding: 7px 9px;\n          min-height: 31px;\n          display: inline-flex;\n          align-items: center;\n          gap: 6px;\n          cursor: pointer;\n          font-size: 0.77rem;\n          font-weight: 650;\n          line-height: 1;\n          transition: background .18s ease, color .18s ease, border-color .18s ease, transform .18s ease;\n        }\n\n        .chip small {\n          color: inherit;\n          opacity: .72;\n          font-size: 0.68rem;\n          font-weight: 600;\n        }\n\n        .chip:hover { transform: translateY(-1px); }\n        .chip.is-active {\n          color: #fff;\n          background: var(--obex-navy);\n          border-color: var(--obex-navy);\n          box-shadow: 0 8px 18px rgba(15,28,92,.16);\n        }\n        .chip.focus-chip.is-active {\n          background: var(--obex-red);\n          border-color: var(--obex-red);\n          box-shadow: 0 8px 18px rgba(230,0,0,.13);\n        }\n\n        .kpi-strip {\n          display: grid;\n          grid-template-columns: repeat(4, minmax(0, 1fr));\n          gap: 10px;\n          margin-bottom: 12px;\n        }\n\n        .kpi {\n          min-width: 0;\n          padding: 12px;\n          border: 1.5px solid var(--obex-line-strong);\n          border-radius: 20px;\n          background: rgba(255,255,255,0.90);\n          position: relative;\n          overflow: hidden;\n        }\n\n        .kpi::after {\n          content: \"\";\n          position: absolute;\n          inset: auto -18px -22px auto;\n          width: 78px;\n          height: 78px;\n          border-radius: 999px;\n          background: var(--obex-navy-soft);\n        }\n\n        .kpi .label {\n          color: var(--obex-muted);\n          font-size: 0.70rem;\n          font-weight: 700;\n          letter-spacing: 0.055em;\n          text-transform: uppercase;\n        }\n\n        .kpi .value {\n          margin-top: 5px;\n          color: var(--obex-navy);\n          font-size: clamp(1.23rem, 2.2cqi, 1.78rem);\n          line-height: 1.02;\n          font-weight: 700;\n          letter-spacing: -0.035em;\n          overflow-wrap: anywhere;\n        }\n\n        .kpi .note {\n          margin-top: 6px;\n          color: var(--obex-muted);\n          font-size: 0.75rem;\n          line-height: 1.3;\n        }\n\n        .meter, .mini-meter {\n          width: 100%;\n          height: 6px;\n          border-radius: 999px;\n          background: var(--obex-soft-2);\n          overflow: hidden;\n          margin-top: 8px;\n        }\n\n        .meter i, .mini-meter i {\n          display: block;\n          height: 100%;\n          width: 0%;\n          border-radius: inherit;\n          background: linear-gradient(90deg, var(--obex-navy), var(--obex-red));\n          transition: width .24s ease;\n        }\n\n        .grid {\n          display: grid;\n          grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.95fr);\n          grid-template-areas:\n            \"network focus\"\n            \"entities market\"\n            \"playbook playbook\"\n            \"monitor monitor\";\n          gap: 12px;\n        }\n\n        .card {\n          min-width: 0;\n          padding: 14px;\n          border: 1.5px solid var(--obex-line-strong);\n          border-radius: 22px;\n          background: rgba(255,255,255,0.92);\n        }\n\n        .card-head {\n          display: flex;\n          align-items: flex-start;\n          justify-content: space-between;\n          gap: 10px;\n          margin-bottom: 10px;\n        }\n\n        .card-head h2 {\n          margin: 0;\n          color: var(--obex-navy);\n          font-size: clamp(1.02rem, 1.55cqi, 1.32rem);\n          line-height: 1.1;\n          letter-spacing: -0.03em;\n        }\n\n        .card-head p {\n          margin: 4px 0 0;\n          color: var(--obex-muted);\n          font-size: 0.78rem;\n          line-height: 1.35;\n        }\n\n        .pill {\n          display: inline-flex;\n          align-items: center;\n          gap: 5px;\n          padding: 5px 8px;\n          border-radius: 999px;\n          background: var(--obex-navy-soft);\n          color: var(--obex-navy);\n          font-size: 0.70rem;\n          font-weight: 700;\n          white-space: nowrap;\n        }\n\n        .network-card { grid-area: network; }\n        .focus-card { grid-area: focus; }\n        .entities-card { grid-area: entities; }\n        .market-card { grid-area: market; }\n        .playbook-card { grid-area: playbook; }\n        .monitor-card { grid-area: monitor; }\n\n        .network-wrap {\n          width: 100%;\n          min-height: 350px;\n          border-radius: 20px;\n          background:\n            radial-gradient(circle at 22% 30%, rgba(230,0,0,0.08), transparent 20%),\n            linear-gradient(180deg, #fff, #F7F9FE);\n          border: 1px solid var(--obex-line);\n          overflow: hidden;\n        }\n\n        svg.network {\n          width: 100%;\n          height: auto;\n          min-height: 350px;\n          display: block;\n        }\n\n        .link {\n          fill: none;\n          stroke: rgba(15, 28, 92, 0.22);\n          stroke-linecap: round;\n          stroke-width: 2.1;\n          opacity: 0.46;\n          transition: opacity .22s ease, stroke .22s ease, stroke-width .22s ease;\n        }\n\n        .link.hot {\n          stroke: var(--obex-red);\n          opacity: 0.92;\n          stroke-width: var(--hot-width, 4);\n        }\n\n        .link.dim { opacity: 0.16; }\n\n        .node .ring {\n          fill: rgba(255,255,255,0.94);\n          stroke: rgba(15, 28, 92, 0.45);\n          stroke-width: 2;\n          transition: stroke .22s ease, stroke-width .22s ease;\n        }\n\n        .node .core {\n          fill: rgba(15, 28, 92, 0.16);\n          transition: r .22s ease, fill .22s ease, opacity .22s ease;\n        }\n\n        .node .node-label {\n          fill: var(--obex-navy);\n          font-size: 13px;\n          font-weight: 700;\n          letter-spacing: -0.02em;\n          pointer-events: none;\n        }\n\n        .node .score-label {\n          fill: var(--obex-muted);\n          font-size: 10.5px;\n          font-weight: 700;\n          pointer-events: none;\n        }\n\n        .node.focus-node {\n          cursor: pointer;\n          outline: none;\n        }\n\n        .node.focus-node:hover .ring,\n        .node.focus-node:focus .ring {\n          stroke: var(--obex-red);\n          stroke-width: 3;\n        }\n\n        .node.active .ring {\n          stroke: var(--obex-red);\n          stroke-width: 3.5;\n        }\n\n        .node.active .core {\n          fill: rgba(230, 0, 0, 0.34);\n        }\n\n        .node.hot:not(.active) .core {\n          fill: rgba(15, 28, 92, 0.22);\n        }\n\n        .node.dim {\n          opacity: 0.58;\n        }\n\n        .detail-title {\n          margin: 0;\n          color: var(--obex-navy);\n          font-size: clamp(1.22rem, 2.2cqi, 1.68rem);\n          line-height: 1.06;\n          letter-spacing: -0.04em;\n        }\n\n        .detail-body {\n          margin: 9px 0 0;\n          color: var(--obex-muted);\n          font-size: 0.86rem;\n          line-height: 1.45;\n        }\n\n        .detail-grid {\n          display: grid;\n          grid-template-columns: repeat(2, minmax(0, 1fr));\n          gap: 8px;\n          margin-top: 12px;\n        }\n\n        .mini-tile {\n          min-width: 0;\n          padding: 10px;\n          border-radius: 16px;\n          background: var(--obex-soft);\n          border: 1px solid var(--obex-line);\n        }\n\n        .mini-tile span {\n          display: block;\n          color: var(--obex-muted);\n          font-size: 0.68rem;\n          font-weight: 700;\n          letter-spacing: .05em;\n          text-transform: uppercase;\n          margin-bottom: 4px;\n        }\n\n        .mini-tile b {\n          display: block;\n          color: var(--obex-navy);\n          font-size: 0.88rem;\n          line-height: 1.25;\n        }\n\n        .mini-tile p {\n          margin: 4px 0 0;\n          color: var(--obex-muted);\n          font-size: 0.72rem;\n          line-height: 1.35;\n        }\n\n        .path-bars {\n          margin-top: 12px;\n          padding-top: 12px;\n          border-top: 1px solid var(--obex-line);\n        }\n\n        .path-bars h3 {\n          margin: 0 0 8px;\n          color: var(--obex-navy);\n          font-size: 0.82rem;\n          letter-spacing: .03em;\n          text-transform: uppercase;\n        }\n\n        .path-row {\n          display: grid;\n          grid-template-columns: 42px minmax(0, 1fr) 58px;\n          gap: 8px;\n          align-items: center;\n          margin: 7px 0;\n          color: var(--obex-muted);\n          font-size: 0.75rem;\n        }\n\n        .path-row b {\n          color: var(--obex-navy);\n          font-weight: 700;\n        }\n\n        .path-row .track {\n          height: 7px;\n          border-radius: 999px;\n          background: var(--obex-soft-2);\n          overflow: hidden;\n        }\n\n        .path-row .track i {\n          display: block;\n          height: 100%;\n          border-radius: inherit;\n          background: linear-gradient(90deg, var(--obex-navy), var(--obex-red));\n        }\n\n        .entity-list {\n          display: grid;\n          gap: 7px;\n        }\n\n        .entity-row {\n          appearance: none;\n          width: 100%;\n          border: 1px solid var(--obex-line);\n          border-radius: 16px;\n          padding: 9px 10px;\n          background: #fff;\n          text-align: left;\n          cursor: pointer;\n          display: grid;\n          grid-template-columns: minmax(0, 1fr) auto;\n          gap: 8px;\n          align-items: center;\n          transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;\n        }\n\n        .entity-row:hover { transform: translateY(-1px); }\n        .entity-row.is-active {\n          border-color: rgba(230,0,0,.46);\n          box-shadow: 0 8px 22px rgba(230,0,0,.08);\n          background: linear-gradient(180deg, #fff, rgba(230,0,0,.025));\n        }\n\n        .entity-main {\n          min-width: 0;\n        }\n\n        .entity-name {\n          display: flex;\n          align-items: center;\n          gap: 6px;\n          color: var(--obex-navy);\n          font-size: 0.86rem;\n          font-weight: 700;\n          line-height: 1.1;\n        }\n\n        .entity-name span {\n          max-width: 100%;\n          overflow: hidden;\n          text-overflow: ellipsis;\n          white-space: nowrap;\n        }\n\n        .entity-meta {\n          margin-top: 4px;\n          color: var(--obex-muted);\n          font-size: 0.70rem;\n          line-height: 1.25;\n        }\n\n        .entity-value {\n          color: var(--obex-navy);\n          font-size: 0.83rem;\n          font-weight: 700;\n          text-align: right;\n          white-space: nowrap;\n        }\n\n        .bar-track {\n          grid-column: 1 \/ -1;\n          height: 6px;\n          border-radius: 999px;\n          background: var(--obex-soft-2);\n          overflow: hidden;\n        }\n\n        .bar-track i {\n          display: block;\n          height: 100%;\n          border-radius: inherit;\n          background: linear-gradient(90deg, var(--obex-navy), var(--obex-red));\n        }\n\n        .market-rows {\n          display: grid;\n          gap: 8px;\n        }\n\n        .market-row {\n          display: grid;\n          grid-template-columns: minmax(0, 1fr) auto;\n          gap: 10px;\n          align-items: center;\n          padding: 10px;\n          border: 1px solid var(--obex-line);\n          border-radius: 16px;\n          background: #fff;\n        }\n\n        .market-row h3 {\n          margin: 0;\n          color: var(--obex-navy);\n          font-size: 0.83rem;\n          line-height: 1.2;\n        }\n\n        .market-row p {\n          margin: 4px 0 0;\n          color: var(--obex-muted);\n          font-size: 0.72rem;\n          line-height: 1.35;\n        }\n\n        .range-pill {\n          display: inline-flex;\n          align-items: center;\n          justify-content: center;\n          max-width: 220px;\n          padding: 7px 9px;\n          border-radius: 999px;\n          background: var(--obex-navy);\n          color: #fff;\n          font-size: 0.73rem;\n          font-weight: 700;\n          line-height: 1.15;\n          text-align: center;\n          overflow-wrap: anywhere;\n        }\n\n        .playbook-grid {\n          display: grid;\n          grid-template-columns: repeat(4, minmax(0, 1fr));\n          gap: 9px;\n        }\n\n        .action-card {\n          min-width: 0;\n          padding: 11px;\n          border-radius: 18px;\n          border: 1px solid var(--obex-line);\n          background:\n            linear-gradient(180deg, rgba(255,255,255,.98), rgba(244,246,251,.72));\n          position: relative;\n        }\n\n        .step-dot {\n          width: 24px;\n          height: 24px;\n          display: inline-flex;\n          align-items: center;\n          justify-content: center;\n          border-radius: 999px;\n          background: var(--obex-red);\n          color: #fff;\n          font-size: 0.72rem;\n          font-weight: 700;\n          margin-bottom: 8px;\n        }\n\n        .action-card h3 {\n          margin: 0;\n          color: var(--obex-navy);\n          font-size: 0.88rem;\n          line-height: 1.2;\n          letter-spacing: -0.015em;\n        }\n\n        .action-card p {\n          margin: 6px 0 0;\n          color: var(--obex-muted);\n          font-size: 0.75rem;\n          line-height: 1.38;\n        }\n\n        .signals {\n          display: grid;\n          grid-template-columns: repeat(3, minmax(0, 1fr));\n          gap: 9px;\n        }\n\n        .signal {\n          min-width: 0;\n          padding: 10px;\n          border-radius: 17px;\n          border: 1px solid var(--obex-line);\n          background: #fff;\n        }\n\n        .signal-top {\n          display: flex;\n          justify-content: space-between;\n          gap: 8px;\n          align-items: center;\n        }\n\n        .signal h3 {\n          margin: 0;\n          color: var(--obex-navy);\n          font-size: 0.83rem;\n          line-height: 1.18;\n        }\n\n        .status {\n          padding: 4px 7px;\n          border-radius: 999px;\n          font-size: 0.66rem;\n          font-weight: 700;\n          background: var(--obex-soft-2);\n          color: var(--obex-navy);\n          white-space: nowrap;\n        }\n\n        .signal.hot .status { background: var(--obex-red-soft); color: var(--obex-red); }\n        .signal.watch .status { background: var(--obex-navy-soft); color: var(--obex-navy); }\n        .signal.low .status { background: var(--obex-soft); color: var(--obex-muted); }\n        .signal.good .status { background: var(--obex-navy); color: #fff; }\n\n        .signal p {\n          margin: 6px 0 0;\n          color: var(--obex-muted);\n          font-size: 0.72rem;\n          line-height: 1.35;\n        }\n\n        .signal .meter i {\n          background: var(--obex-navy);\n        }\n\n        .signal.hot .meter i {\n          background: linear-gradient(90deg, var(--obex-red), var(--obex-red));\n        }\n\n        .signal.good .meter i {\n          background: var(--obex-navy);\n        }\n\n        .footer-actions {\n          display: flex;\n          align-items: center;\n          justify-content: space-between;\n          gap: 10px;\n          flex-wrap: wrap;\n          margin-top: 12px;\n          padding: 12px 4px 2px;\n        }\n\n        .tools {\n          display: flex;\n          flex-wrap: wrap;\n          gap: 8px;\n        }\n\n        .tool-btn {\n          appearance: none;\n          border: 1px solid var(--obex-line-strong);\n          background: rgba(255,255,255,.88);\n          color: var(--obex-navy);\n          border-radius: 999px;\n          padding: 8px 11px;\n          font-size: 0.78rem;\n          font-weight: 700;\n          cursor: pointer;\n        }\n\n        .tool-btn:hover {\n          border-color: var(--obex-red);\n          color: var(--obex-red);\n        }\n\n        .footer-note {\n          color: var(--obex-muted);\n          font-size: 0.74rem;\n          line-height: 1.35;\n          max-width: 680px;\n        }\n\n        .sr-only {\n          position: absolute;\n          width: 1px;\n          height: 1px;\n          padding: 0;\n          margin: -1px;\n          overflow: hidden;\n          clip: rect(0, 0, 0, 0);\n          white-space: nowrap;\n          border: 0;\n        }\n\n        @container (max-width: 960px) {\n          .control-rail {\n            grid-template-columns: 1fr;\n          }\n          .kpi-strip {\n            grid-template-columns: repeat(2, minmax(0, 1fr));\n          }\n          .grid {\n            grid-template-columns: 1fr;\n            grid-template-areas:\n              \"network\"\n              \"focus\"\n              \"entities\"\n              \"market\"\n              \"playbook\"\n              \"monitor\";\n          }\n          .playbook-grid {\n            grid-template-columns: repeat(2, minmax(0, 1fr));\n          }\n          .signals {\n            grid-template-columns: repeat(2, minmax(0, 1fr));\n          }\n        }\n\n        @container (max-width: 760px) {\n          .shell {\n            border-radius: 22px;\n          }\n          h1 {\n            font-size: clamp(1.55rem, 8cqi, 2.25rem);\n          }\n          .topline,\n          .card-head {\n            align-items: stretch;\n          }\n          .state-badge,\n          .pill {\n            white-space: normal;\n          }\n          .detail-grid {\n            grid-template-columns: 1fr;\n          }\n          .market-row {\n            grid-template-columns: 1fr;\n          }\n          .range-pill {\n            justify-self: start;\n            max-width: 100%;\n          }\n          .network-wrap, svg.network {\n            min-height: 300px;\n          }\n        }\n\n        @container (max-width: 560px) {\n          .command {\n            padding-inline: 4px;\n          }\n          .kpi-strip,\n          .signals,\n          .playbook-grid {\n            grid-template-columns: 1fr;\n          }\n          .control-head {\n            display: block;\n          }\n          .control-head small {\n            display: block;\n            margin-top: 3px;\n            white-space: normal;\n          }\n          .chip {\n            width: 100%;\n            justify-content: space-between;\n          }\n          .entity-row {\n            grid-template-columns: 1fr;\n          }\n          .entity-value {\n            text-align: left;\n          }\n          .path-row {\n            grid-template-columns: 38px minmax(0, 1fr) 50px;\n          }\n          .node .node-label {\n            font-size: 12px;\n          }\n          .node .score-label {\n            font-size: 9.5px;\n          }\n        }\n      <\/style>\n\n      <section class=\"shell\" aria-label=\"OBEX connected dashboard\">\n        <header class=\"command\">\n          <div class=\"topline\">\n            <span class=\"eyebrow\"><span class=\"dot\"><\/span><span data-eyebrow><\/span><\/span>\n            <div class=\"state-badge\" data-state-badge aria-live=\"polite\"><\/div>\n          <\/div>\n          <h1 data-title><\/h1>\n          <p class=\"subtitle\" data-subtitle><\/p>\n          <p class=\"briefing\" data-briefing aria-live=\"polite\"><\/p>\n        <\/header>\n\n        <section class=\"control-rail\" aria-label=\"Global controls\">\n          <div class=\"control-card\">\n            <div class=\"control-head\"><span>Scenario<\/span><small>Stress regime<\/small><\/div>\n            <div class=\"button-group\" data-scenario-controls><\/div>\n          <\/div>\n          <div class=\"control-card\">\n            <div class=\"control-head\"><span>Field<\/span><small>Production exposure<\/small><\/div>\n            <div class=\"button-group\" data-entity-controls><\/div>\n          <\/div>\n          <div class=\"control-card\">\n            <div class=\"control-head\"><span>Focus<\/span><small>Transmission lens<\/small><\/div>\n            <div class=\"button-group\" data-focus-controls><\/div>\n          <\/div>\n        <\/section>\n\n        <section class=\"kpi-strip\" aria-label=\"Scenario indicators\">\n          <article class=\"kpi\">\n            <div class=\"label\">Stress regime<\/div>\n            <div class=\"value\" data-kpi-stress><\/div>\n            <div class=\"note\" data-kpi-stress-note><\/div>\n            <div class=\"meter\" aria-hidden=\"true\"><i data-kpi-stress-bar><\/i><\/div>\n          <\/article>\n          <article class=\"kpi\">\n            <div class=\"label\">Export loss<\/div>\n            <div class=\"value\" data-kpi-primary><\/div>\n            <div class=\"note\" data-kpi-primary-note><\/div>\n            <div class=\"meter\" aria-hidden=\"true\"><i data-kpi-primary-bar><\/i><\/div>\n          <\/article>\n          <article class=\"kpi\">\n            <div class=\"label\">Production impact<\/div>\n            <div class=\"value\" data-kpi-secondary><\/div>\n            <div class=\"note\" data-kpi-secondary-note><\/div>\n            <div class=\"meter\" aria-hidden=\"true\"><i data-kpi-secondary-bar><\/i><\/div>\n          <\/article>\n          <article class=\"kpi\">\n            <div class=\"label\">Dominant channel<\/div>\n            <div class=\"value\" data-kpi-channel><\/div>\n            <div class=\"note\" data-kpi-channel-note><\/div>\n            <div class=\"meter\" aria-hidden=\"true\"><i data-kpi-channel-bar><\/i><\/div>\n          <\/article>\n        <\/section>\n\n        <main class=\"grid\">\n          <article class=\"card network-card\" aria-label=\"Transmission web\">\n            <div class=\"card-head\">\n              <div>\n                <h2>Transmission web<\/h2>\n                <p>Click a channel node to change the active focus. Links reweight with scenario, field and lens.<\/p>\n              <\/div>\n              <span class=\"pill\" data-network-pill><\/span>\n            <\/div>\n            <div class=\"network-wrap\">\n              <svg class=\"network\" viewBox=\"0 0 780 430\" role=\"img\" aria-label=\"Blockade-to-production transmission network\" data-network>\n                <path class=\"link\" data-link=\"shock-marine\" d=\"M112 214 C142 170 174 132 214 118\"><\/path>\n                <path class=\"link\" data-link=\"marine-terminal\" d=\"M250 118 C290 92 332 88 370 112\"><\/path>\n                <path class=\"link\" data-link=\"marine-storage\" d=\"M244 136 C282 166 318 210 366 246\"><\/path>\n                <path class=\"link\" data-link=\"marine-residual\" d=\"M254 106 C350 54 438 58 548 88\"><\/path>\n                <path class=\"link\" data-link=\"terminal-storage\" d=\"M398 144 C410 178 405 212 394 245\"><\/path>\n                <path class=\"link\" data-link=\"terminal-production\" d=\"M410 118 C500 126 610 154 672 198\"><\/path>\n                <path class=\"link\" data-link=\"storage-production\" d=\"M418 262 C492 234 592 213 662 207\"><\/path>\n                <path class=\"link\" data-link=\"storage-field\" d=\"M419 284 C462 306 504 312 544 302\"><\/path>\n                <path class=\"link\" data-link=\"field-production\" d=\"M584 292 C636 272 660 244 680 222\"><\/path>\n                <path class=\"link\" data-link=\"field-recovery\" d=\"M586 318 C626 342 654 350 680 346\"><\/path>\n                <path class=\"link\" data-link=\"production-recovery\" d=\"M700 228 C716 270 712 310 694 334\"><\/path>\n                <path class=\"link\" data-link=\"recovery-capacity\" d=\"M652 360 C570 392 460 392 330 362\"><\/path>\n\n                <g class=\"node source-node\" data-node=\"shock\" transform=\"translate(82 214)\">\n                  <circle class=\"ring\" r=\"36\"><\/circle><circle class=\"core\" r=\"13\"><\/circle>\n                  <text class=\"node-label\" text-anchor=\"middle\" y=\"-3\">Blockade<\/text>\n                  <text class=\"score-label\" text-anchor=\"middle\" y=\"14\" data-score>shock<\/text>\n                <\/g>\n\n                <g class=\"node focus-node\" data-node=\"marine\" data-focus=\"marine\" role=\"button\" tabindex=\"0\" aria-label=\"Set focus to Marine access\" transform=\"translate(224 116)\">\n                  <circle class=\"ring\" r=\"40\"><\/circle><circle class=\"core\" r=\"13\"><\/circle>\n                  <text class=\"node-label\" text-anchor=\"middle\" y=\"-4\">Marine<\/text>\n                  <text class=\"score-label\" text-anchor=\"middle\" y=\"15\" data-score><\/text>\n                <\/g>\n\n                <g class=\"node focus-node\" data-node=\"terminal\" data-focus=\"terminal\" role=\"button\" tabindex=\"0\" aria-label=\"Set focus to Terminal assets\" transform=\"translate(390 118)\">\n                  <circle class=\"ring\" r=\"40\"><\/circle><circle class=\"core\" r=\"13\"><\/circle>\n                  <text class=\"node-label\" text-anchor=\"middle\" y=\"-4\">Terminal<\/text>\n                  <text class=\"score-label\" text-anchor=\"middle\" y=\"15\" data-score><\/text>\n                <\/g>\n\n                <g class=\"node focus-node\" data-node=\"storage\" data-focus=\"storage\" role=\"button\" tabindex=\"0\" aria-label=\"Set focus to Storage pressure\" transform=\"translate(390 264)\">\n                  <circle class=\"ring\" r=\"42\"><\/circle><circle class=\"core\" r=\"14\"><\/circle>\n                  <text class=\"node-label\" text-anchor=\"middle\" y=\"-4\">Storage<\/text>\n                  <text class=\"score-label\" text-anchor=\"middle\" y=\"15\" data-score><\/text>\n                <\/g>\n\n                <g class=\"node focus-node\" data-node=\"field\" data-focus=\"field\" role=\"button\" tabindex=\"0\" aria-label=\"Set focus to Field shut-in\" transform=\"translate(566 304)\">\n                  <circle class=\"ring\" r=\"40\"><\/circle><circle class=\"core\" r=\"13\"><\/circle>\n                  <text class=\"node-label\" text-anchor=\"middle\" y=\"-4\">Field<\/text>\n                  <text class=\"score-label\" text-anchor=\"middle\" y=\"15\" data-score><\/text>\n                <\/g>\n\n                <g class=\"node outcome-node\" data-node=\"residual\" transform=\"translate(574 94)\">\n                  <circle class=\"ring\" r=\"38\"><\/circle><circle class=\"core\" r=\"12\"><\/circle>\n                  <text class=\"node-label\" text-anchor=\"middle\" y=\"-4\">Residual<\/text>\n                  <text class=\"score-label\" text-anchor=\"middle\" y=\"15\" data-score><\/text>\n                <\/g>\n\n                <g class=\"node outcome-node\" data-node=\"production\" transform=\"translate(696 208)\">\n                  <circle class=\"ring\" r=\"42\"><\/circle><circle class=\"core\" r=\"14\"><\/circle>\n                  <text class=\"node-label\" text-anchor=\"middle\" y=\"-4\">Output<\/text>\n                  <text class=\"score-label\" text-anchor=\"middle\" y=\"15\" data-score><\/text>\n                <\/g>\n\n                <g class=\"node focus-node\" data-node=\"recovery\" data-focus=\"recovery\" role=\"button\" tabindex=\"0\" aria-label=\"Set focus to Recovery and scarring\" transform=\"translate(692 350)\">\n                  <circle class=\"ring\" r=\"42\"><\/circle><circle class=\"core\" r=\"14\"><\/circle>\n                  <text class=\"node-label\" text-anchor=\"middle\" y=\"-4\">Recovery<\/text>\n                  <text class=\"score-label\" text-anchor=\"middle\" y=\"15\" data-score><\/text>\n                <\/g>\n              <\/svg>\n            <\/div>\n          <\/article>\n\n          <article class=\"card focus-card\" aria-label=\"Focus detail panel\">\n            <div class=\"card-head\">\n              <div>\n                <h2>Focus detail<\/h2>\n                <p>Selected lens, field weight, timing and model path.<\/p>\n              <\/div>\n              <span class=\"pill\" data-focus-pill><\/span>\n            <\/div>\n            <h3 class=\"detail-title\" data-focus-title><\/h3>\n            <p class=\"detail-body\" data-focus-body><\/p>\n            <div class=\"detail-grid\" data-focus-tiles><\/div>\n            <div class=\"path-bars\">\n              <h3>Production path<\/h3>\n              <div data-path-bars><\/div>\n            <\/div>\n          <\/article>\n\n          <article class=\"card entities-card\" aria-label=\"Field comparison panel\">\n            <div class=\"card-head\">\n              <div>\n                <h2>Field comparison<\/h2>\n                <p>Bars show selected-focus weighted field-at-risk contribution.<\/p>\n              <\/div>\n              <span class=\"pill\" data-entity-pill><\/span>\n            <\/div>\n            <div class=\"entity-list\" data-entity-list><\/div>\n          <\/article>\n\n          <article class=\"card market-card\" aria-label=\"Scenario benchmark panel\">\n            <div class=\"card-head\">\n              <div>\n                <h2>Scenario benchmarks<\/h2>\n                <p>Workbook-derived model values and operational reference rows.<\/p>\n              <\/div>\n              <span class=\"pill\" data-market-pill><\/span>\n            <\/div>\n            <div class=\"market-rows\" data-market-rows><\/div>\n          <\/article>\n\n          <article class=\"card playbook-card\" aria-label=\"Response playbook panel\">\n            <div class=\"card-head\">\n              <div>\n                <h2>Response playbook<\/h2>\n                <p>Action cards change with scenario, field and focus.<\/p>\n              <\/div>\n              <span class=\"pill\" data-playbook-pill><\/span>\n            <\/div>\n            <div class=\"playbook-grid\" data-playbook><\/div>\n          <\/article>\n\n          <article class=\"card monitor-card\" aria-label=\"Monitoring dashboard panel\">\n            <div class=\"card-head\">\n              <div>\n                <h2>Monitoring dashboard<\/h2>\n                <p>Six compact signals derived from selected state.<\/p>\n              <\/div>\n              <span class=\"pill\" data-monitor-pill><\/span>\n            <\/div>\n            <div class=\"signals\" data-monitor><\/div>\n          <\/article>\n        <\/main>\n\n        <footer class=\"footer-actions\">\n          <div class=\"tools\" aria-label=\"Dashboard tools\">\n            <button class=\"tool-btn\" type=\"button\" data-copy>Copy current briefing<\/button>\n            <button class=\"tool-btn\" type=\"button\" data-csv>Download current CSV<\/button>\n          <\/div>\n          <div class=\"footer-note\" data-footer-note><\/div>\n        <\/footer>\n      <\/section>\n    `;\n\n    class ObexLinkedDashboard extends HTMLElement {\n      connectedCallback() {\n        if (this.shadowRoot) return;\n        this.attachShadow({ mode: \"open\" });\n        this.shadowRoot.appendChild(template.content.cloneNode(true));\n        this.data = dashboardData;\n        this.state = {\n          scenario: this.data.meta.defaultScenario || this.data.scenarioOrder[0],\n          entity: this.data.meta.defaultEntity || this.data.entityOrder[0],\n          focus: this.data.meta.defaultFocus || this.data.focusOrder[0]\n        };\n        this.cache();\n        this.buildControls();\n        this.bind();\n        this.render();\n      }\n\n      cache() {\n        const q = (sel) => this.shadowRoot.querySelector(sel);\n        this.els = {\n          title: q(\"[data-title]\"),\n          subtitle: q(\"[data-subtitle]\"),\n          eyebrow: q(\"[data-eyebrow]\"),\n          briefing: q(\"[data-briefing]\"),\n          badge: q(\"[data-state-badge]\"),\n          scenarioControls: q(\"[data-scenario-controls]\"),\n          entityControls: q(\"[data-entity-controls]\"),\n          focusControls: q(\"[data-focus-controls]\"),\n          kpiStress: q(\"[data-kpi-stress]\"),\n          kpiStressNote: q(\"[data-kpi-stress-note]\"),\n          kpiStressBar: q(\"[data-kpi-stress-bar]\"),\n          kpiPrimary: q(\"[data-kpi-primary]\"),\n          kpiPrimaryNote: q(\"[data-kpi-primary-note]\"),\n          kpiPrimaryBar: q(\"[data-kpi-primary-bar]\"),\n          kpiSecondary: q(\"[data-kpi-secondary]\"),\n          kpiSecondaryNote: q(\"[data-kpi-secondary-note]\"),\n          kpiSecondaryBar: q(\"[data-kpi-secondary-bar]\"),\n          kpiChannel: q(\"[data-kpi-channel]\"),\n          kpiChannelNote: q(\"[data-kpi-channel-note]\"),\n          kpiChannelBar: q(\"[data-kpi-channel-bar]\"),\n          network: q(\"[data-network]\"),\n          networkPill: q(\"[data-network-pill]\"),\n          focusPill: q(\"[data-focus-pill]\"),\n          focusTitle: q(\"[data-focus-title]\"),\n          focusBody: q(\"[data-focus-body]\"),\n          focusTiles: q(\"[data-focus-tiles]\"),\n          pathBars: q(\"[data-path-bars]\"),\n          entityPill: q(\"[data-entity-pill]\"),\n          entityList: q(\"[data-entity-list]\"),\n          marketPill: q(\"[data-market-pill]\"),\n          marketRows: q(\"[data-market-rows]\"),\n          playbookPill: q(\"[data-playbook-pill]\"),\n          playbook: q(\"[data-playbook]\"),\n          monitorPill: q(\"[data-monitor-pill]\"),\n          monitor: q(\"[data-monitor]\"),\n          footerNote: q(\"[data-footer-note]\"),\n          copyBtn: q(\"[data-copy]\"),\n          csvBtn: q(\"[data-csv]\")\n        };\n      }\n\n      buildControls() {\n        const scenarios = this.data.scenarioOrder.map((key) => {\n          const item = this.data.scenarios[key];\n          return { key, label: item.shortLabel, sub: item.riskLevel };\n        });\n        const entities = this.data.entityOrder.map((key) => {\n          const item = this.data.entities[key];\n          return { key, label: item.label, sub: `${item.share}%` };\n        });\n        const focuses = this.data.focusOrder.map((key) => {\n          const item = this.data.channels[key];\n          return { key, label: item.label, sub: item.layer };\n        });\n        this.fillButtonGroup(this.els.scenarioControls, scenarios, \"scenario\");\n        this.fillButtonGroup(this.els.entityControls, entities, \"entity\");\n        this.fillButtonGroup(this.els.focusControls, focuses, \"focus\");\n      }\n\n      fillButtonGroup(container, items, control) {\n        const focusClass = control === \"focus\" ? \" focus-chip\" : \"\";\n        container.innerHTML = items.map((item) =>\n          `<button class=\"chip${focusClass}\" type=\"button\" data-control=\"${control}\" data-key=\"${this.esc(item.key)}\" aria-pressed=\"false\"><span>${this.esc(item.label)}<\/span><small>${this.esc(item.sub)}<\/small><\/button>`\n        ).join(\"\");\n      }\n\n      bind() {\n        this.shadowRoot.addEventListener(\"click\", (event) => {\n          const control = event.target.closest(\"[data-control]\");\n          if (control) {\n            const type = control.dataset.control;\n            const key = control.dataset.key;\n            this.setState({ [type]: key });\n            return;\n          }\n\n          const entityRow = event.target.closest(\"[data-entity-row]\");\n          if (entityRow) {\n            this.setState({ entity: entityRow.dataset.entityRow });\n            return;\n          }\n\n          const node = event.target.closest(\".focus-node[data-focus]\");\n          if (node) {\n            this.setState({ focus: node.dataset.focus });\n          }\n        });\n\n        this.els.network.addEventListener(\"keydown\", (event) => {\n          if (event.key !== \"Enter\" && event.key !== \" \") return;\n          const node = event.target.closest(\".focus-node[data-focus]\");\n          if (!node) return;\n          event.preventDefault();\n          this.setState({ focus: node.dataset.focus });\n        });\n\n        this.els.copyBtn.addEventListener(\"click\", () => this.copyBriefing());\n        this.els.csvBtn.addEventListener(\"click\", () => this.downloadCsv());\n      }\n\n      setState(patch) {\n        this.state = { ...this.state, ...patch };\n        this.render();\n      }\n\n      setText(el, text) {\n        if (el) el.textContent = text == null ? \"\" : String(text);\n      }\n\n      setHtml(el, markup) {\n        if (el) el.innerHTML = markup || \"\";\n      }\n\n      esc(value) {\n        return String(value ?? \"\").replace(\/[&<>\"']\/g, (ch) => ({\n          \"&\": \"&amp;\",\n          \"<\": \"&lt;\",\n          \">\": \"&gt;\",\n          '\"': \"&quot;\",\n          \"'\": \"&#39;\"\n        }[ch]));\n      }\n\n      scenarioData() { return this.data.scenarios[this.state.scenario]; }\n      entityData(key = this.state.entity) { return this.data.entities[key]; }\n      focusData(key = this.state.focus) { return this.data.channels[key]; }\n\n      clamp(value, min = 0, max = 100) {\n        const num = Number(value);\n        if (!Number.isFinite(num)) return min;\n        return Math.max(min, Math.min(max, num));\n      }\n\n      fmtMbd(value, digits = 2) {\n        if (value == null || Number.isNaN(Number(value))) return \"\u2014\";\n        return `${Number(value).toFixed(digits)} mb\/d`;\n      }\n\n      fmtPct(value, digits = 0) {\n        if (value == null || Number.isNaN(Number(value))) return \"\u2014\";\n        return `${Number(value).toFixed(digits)}%`;\n      }\n\n      fmtDay(value) {\n        if (value == null || Number.isNaN(Number(value))) return \"\u2014\";\n        return `${Math.round(Number(value))}d`;\n      }\n\n      fmtRange(low, high, unit = \"mb\/d\") {\n        if (low == null && high == null) return \"\u2014\";\n        if (low === high) return `${Number(low).toFixed(2)} ${unit}`;\n        return `${Number(low).toFixed(2)}\u2013${Number(high).toFixed(2)} ${unit}`;\n      }\n\n      scenarioMood(stress = this.scenarioData().stress) {\n        if (stress >= 80) return \"Systemic\";\n        if (stress >= 50) return \"Compounding\";\n        return \"Contained but live\";\n      }\n\n      selectedPrimaryRange() {\n        const s = this.scenarioData();\n        return this.fmtRange(s.exportLoss[0], s.exportLoss[2], \"mb\/d\");\n      }\n\n      selectedSecondaryRange() {\n        const s = this.scenarioData();\n        return `${this.fmtMbd(s.prodLoss[\"90\"])} loss; ${this.fmtMbd(s.remainingProd[\"90\"])} remaining`;\n      }\n\n      storageAtDay(day = 30) {\n        const row = (this.scenarioData().storagePath || []).find((item) => Number(item.day) === Number(day));\n        return row ? Number(row.value) : 0;\n      }\n\n      channelWeightedScore(channelKey, entityKey = this.state.entity) {\n        const focus = this.data.channels[channelKey];\n        const entity = this.entityData(entityKey);\n        if (!focus || !entity) return 0;\n        const intensity = Number(focus.intensity[this.state.scenario] || 0);\n        const weight = Number(entity.weights[channelKey] || 0);\n        return this.clamp(intensity * weight);\n      }\n\n      dominantChannel() {\n        let bestKey = this.data.focusOrder[0];\n        let bestValue = -1;\n        this.data.focusOrder.forEach((key) => {\n          const score = this.channelWeightedScore(key);\n          if (score > bestValue) {\n            bestValue = score;\n            bestKey = key;\n          }\n        });\n        return { key: bestKey, value: bestValue, label: this.data.channels[bestKey].label };\n      }\n\n      fieldRiskAt(entityKey = this.state.entity) {\n        const s = this.scenarioData();\n        const e = this.entityData(entityKey);\n        const prodLoss = Number(s.prodLoss[\"90\"] || 0);\n        const weighted = this.channelWeightedScore(this.state.focus, entityKey);\n        const proportionalLoss = prodLoss * Number(e.shareRaw || 0);\n        return {\n          loss: proportionalLoss,\n          weighted,\n          combined: proportionalLoss * (0.72 + weighted \/ 250)\n        };\n      }\n\n      buildBriefing() {\n        const s = this.scenarioData();\n        const e = this.entityData();\n        const f = this.focusData();\n        const fieldRisk = this.fieldRiskAt();\n        const curtail = s.curtailmentStart ? `Curtailment signal: day ${Math.round(s.curtailmentStart)}.` : \"No storage curtailment signal in the baseline case.\";\n        return `${s.shortLabel} regime for ${e.label}: ${f.label} is the active lens. Export loss sits at ${this.selectedPrimaryRange()} with ${this.fmtMbd(s.exportLoss[1])} central, while day-90 production is ${this.fmtMbd(s.remainingProd[\"90\"])}. ${e.label} represents ${this.fmtPct(e.share, 1)} of baseline output and carries about ${this.fmtMbd(fieldRisk.loss, 3)} of proportional day-90 loss exposure. ${curtail}`;\n      }\n\n      stateBadgeHtml() {\n        const s = this.scenarioData();\n        const e = this.entityData();\n        const d = this.dominantChannel();\n        return `<b>${this.esc(s.shortLabel)}<\/b><span>\u00b7<\/span><span>${this.esc(this.scenarioMood())}<\/span><span>\u00b7<\/span><span>${this.esc(d.label)}<\/span><span>\u00b7<\/span><b>${this.esc(e.label)}<\/b>`;\n      }\n\n      focusRangeText() {\n        const s = this.scenarioData();\n        const focus = this.state.focus;\n        if (focus === \"marine\") return `${this.selectedPrimaryRange()} export loss; residual crude exports ${this.fmtMbd(s.residualExports)}`;\n        if (focus === \"terminal\") return `${this.fmtMbd(s.directPhysicalLoss)} direct loss; affected first: ${s.firstAssets}`;\n        if (focus === \"storage\") return s.storageFullDays ? `${this.fmtDay(s.storageFullDays)} to storage-full; curtailment ${this.fmtDay(s.curtailmentStart)}` : \"No storage surplus under baseline\";\n        if (focus === \"field\") return `${this.selectedSecondaryRange()} by day 90`;\n        if (focus === \"recovery\") return `${s.recoveryWindow}; scarring ${this.fmtPct(s.scarring[0], 1)}\u2013${this.fmtPct(s.scarring[1], 1)}`;\n        return \"\u2014\";\n      }\n\n      buildFocusTiles() {\n        const s = this.scenarioData();\n        const e = this.entityData();\n        const f = this.focusData();\n        const weight = e.weights[this.state.focus] || 0;\n        const score = this.channelWeightedScore(this.state.focus);\n        const curtailText = s.curtailmentStart ? `Curtailment around ${this.fmtDay(s.curtailmentStart)}` : \"No modeled curtailment\";\n        const tiles = [\n          { label: \"Current range\", value: this.focusRangeText(), note: `${s.shortLabel} scenario output` },\n          { label: \"Field weight\", value: `${this.fmtPct(weight * 100, 0)} exposure`, note: `${this.fmtPct(score, 0)} weighted score` },\n          { label: \"Operational layer\", value: f.layer, note: f.layerCopy },\n          { label: \"Timing signal\", value: f.timing, note: focusTimingOverride(this.state.focus, s, curtailText) }\n        ];\n        return tiles.map((tile) =>\n          `<div class=\"mini-tile\"><span>${this.esc(tile.label)}<\/span><b>${this.esc(tile.value)}<\/b><p>${this.esc(tile.note)}<\/p><\/div>`\n        ).join(\"\");\n\n        function focusTimingOverride(focus, scenario, fallback) {\n          if (focus === \"storage\") return fallback;\n          if (focus === \"recovery\") return scenario.recoveryWindow;\n          return dashboardData.channels[focus].timingCopy;\n        }\n      }\n\n      buildPathBars() {\n        const s = this.scenarioData();\n        const max = Number(this.data.meta.baselineProduction || 3.4);\n        const days = [\"30\", \"60\", \"90\"];\n        return days.map((day) => {\n          const value = Number(s.remainingProd[day] || 0);\n          const width = this.clamp((value \/ max) * 100);\n          return `<div class=\"path-row\"><b>D${day}<\/b><div class=\"track\" aria-hidden=\"true\"><i style=\"width:${width}%\"><\/i><\/div><span>${this.esc(this.fmtMbd(value))}<\/span><\/div>`;\n        }).join(\"\");\n      }\n\n      buildEntityList() {\n        const values = this.data.entityOrder.map((key) => this.fieldRiskAt(key).combined);\n        const max = Math.max(...values, 0.01);\n        return this.data.entityOrder.map((key) => {\n          const e = this.entityData(key);\n          const risk = this.fieldRiskAt(key);\n          const width = this.clamp((risk.combined \/ max) * 100, 4, 100);\n          const active = key === this.state.entity ? \" is-active\" : \"\";\n          return `\n            <button class=\"entity-row${active}\" type=\"button\" data-entity-row=\"${this.esc(key)}\" aria-pressed=\"${key === this.state.entity}\">\n              <div class=\"entity-main\">\n                <div class=\"entity-name\"><span>${this.esc(e.label)}<\/span><\/div>\n                <div class=\"entity-meta\">${this.esc(e.beta)} \u00b7 ${this.esc(e.type)} \u00b7 ${this.fmtPct(e.share, 1)} baseline share<\/div>\n              <\/div>\n              <div class=\"entity-value\">${this.fmtMbd(risk.loss, 3)}<\/div>\n              <div class=\"bar-track\" aria-hidden=\"true\"><i style=\"width:${width}%\"><\/i><\/div>\n            <\/button>`;\n        }).join(\"\");\n      }\n\n      assetsMatching(regex) {\n        return this.data.assetRows.filter((row) => regex.test(row.asset));\n      }\n\n      buildMarketRows() {\n        const s = this.scenarioData();\n        const e = this.entityData();\n        const focus = this.state.focus;\n        let rows = [];\n\n        if (focus === \"marine\") {\n          rows = [\n            { name: \"Export-loss band\", note: \"Low\u2013high range from the scenario matrix.\", value: this.selectedPrimaryRange() },\n            { name: \"Residual crude exports\", note: \"Baseline crude exports less capped central export loss.\", value: this.fmtMbd(s.residualExports) },\n            { name: \"Daily surplus to storage\", note: \"Crude that cannot exit after domestic absorption and residual liftings.\", value: this.fmtMbd(s.dailySurplus) },\n            { name: \"First assets affected\", note: s.firstAssets, value: s.riskLevel }\n          ];\n        } else if (focus === \"terminal\") {\n          rows = this.assetsMatching(\/Fixed jetty|SBM|SPM|Tank farm|Terminal OT\\\/IT|Subsea\/i).slice(0, 5).map((row) => ({\n            name: row.asset,\n            note: row.implication,\n            value: s.stress >= 70 ? `${row.severeLow}\u2013${row.severeHigh}d severe` : `${row.bestLow}\u2013${row.bestHigh}d best`\n          }));\n        } else if (focus === \"storage\") {\n          const headroom = this.data.assumptions[\"effective-storage-headroom\"];\n          rows = [\n            { name: \"Effective storage headroom\", note: headroom ? headroom.notes : \"Onshore plus floating storage relief.\", value: headroom ? `${headroom.central} ${headroom.unit}` : \"46.5 Mbbl\" },\n            { name: \"Storage-full days\", note: \"Headroom divided by daily surplus to storage.\", value: s.storageFullDays ? this.fmtDay(s.storageFullDays) : \"No surplus\" },\n            { name: \"Day 30 uncurtailed fill\", note: \"Storage fill if production were not curtailed.\", value: this.fmtPct(this.storageAtDay(30), 1) },\n            { name: \"Curtailment start\", note: \"Earlier of storage-full days and severe-outage operational trigger.\", value: s.curtailmentStart ? this.fmtDay(s.curtailmentStart) : \"None\" }\n          ];\n        } else if (focus === \"field\") {\n          const risk = this.fieldRiskAt();\n          rows = [\n            { name: `${e.label} production`, note: e.characteristics, value: this.fmtMbd(e.productionMbd) },\n            { name: \"Baseline share\", note: \"Share of modeled 3.4 mb\/d baseline production.\", value: this.fmtPct(e.share, 1) },\n            { name: \"Shut-in vulnerability\", note: e.vulnerability, value: e.beta },\n            { name: \"Proportional day-90 loss\", note: \"Total scenario loss multiplied by field production share.\", value: this.fmtMbd(risk.loss, 3) }\n          ];\n        } else if (focus === \"recovery\") {\n          rows = [\n            { name: \"Recovery window\", note: \"Scenario matrix restart and restoration timing.\", value: s.recoveryWindow },\n            { name: \"3M \/ 6M restoration\", note: \"Lost-output restoration percentages in the model.\", value: `${this.fmtPct(s.restoration[\"3m\"], 1)} \/ ${this.fmtPct(s.restoration[\"6m\"], 1)}` },\n            { name: \"Scarring band\", note: \"Long-term capacity impairment range.\", value: `${this.fmtPct(s.scarring[0], 1)}\u2013${this.fmtPct(s.scarring[1], 1)}` },\n            { name: \"Long-term sustainable capacity\", note: s.keyDrivers, value: this.fmtMbd(s.longTermCapacity, 3) }\n          ];\n        }\n\n        return rows.map((row) =>\n          `<div class=\"market-row\"><div><h3>${this.esc(row.name)}<\/h3><p>${this.esc(row.note)}<\/p><\/div><span class=\"range-pill\">${this.esc(row.value)}<\/span><\/div>`\n        ).join(\"\");\n      }\n\n      buildPlaybook() {\n        const s = this.scenarioData();\n        const e = this.entityData();\n        const f = this.focusData();\n        const focusCards = {\n          marine: {\n            title: \"Secure export optionality\",\n            body: `Preserve any residual lifting route, floating-storage relief and dispatch control while ${s.shortLabel} export loss is ${this.selectedPrimaryRange()}.`\n          },\n          terminal: {\n            title: \"Pre-stage terminal repair packages\",\n            body: \"Prioritize loading arms, SBM\/SPM gear, metering, firewater, OT\/IT backups and marine access clearance before the outage becomes a field shut-in problem.\"\n          },\n          storage: {\n            title: \"Manage tank-top before it manages output\",\n            body: s.curtailmentStart ? `Treat ${this.fmtDay(s.curtailmentStart)} as the operational cutover signal; align storage, domestic absorption and field throttling before tank-top.` : \"Keep storage and dispatch on normal surveillance while export outlets remain open.\"\n          },\n          field: {\n            title: `Protect ${e.label} restart integrity`,\n            body: e.mitigation\n          },\n          recovery: {\n            title: \"Sequence recovery by barrels returned\",\n            body: `Use ${s.recoveryWindow} as the planning window and triage scarce repair resources to the assets that unlock the most sustainable capacity.`\n          }\n        };\n\n        const severity = s.stress >= 80\n          ? \"Use crisis governance: daily production cut decisions, repair-resource rationing and restart sequencing.\"\n          : s.stress >= 50\n            ? \"Use a joint logistics\/operations cadence: storage, terminal repair and field integrity thresholds should be reviewed together.\"\n            : \"Maintain watch-state controls and document fallback options before insurance, chartering or dispatch conditions deteriorate.\";\n\n        const cards = [\n          focusCards[this.state.focus],\n          {\n            title: `Field-specific control: ${e.label}`,\n            body: `${e.vulnerability} Mitigation: ${e.mitigation}`\n          },\n          {\n            title: `${s.shortLabel} recovery drivers`,\n            body: s.keyDrivers || \"No exceptional recovery driver in the baseline scenario.\"\n          },\n          {\n            title: \"Decision threshold\",\n            body: `${severity} Dominant current channel: ${this.dominantChannel().label}.`\n          }\n        ];\n\n        return cards.map((card, index) =>\n          `<article class=\"action-card\"><span class=\"step-dot\">${index + 1}<\/span><h3>${this.esc(card.title)}<\/h3><p>${this.esc(card.body)}<\/p><\/article>`\n        ).join(\"\");\n      }\n\n      monitorValues() {\n        const s = this.scenarioData();\n        const e = this.entityData();\n        const exportValue = this.clamp((Number(s.exportLoss[1] || 0) \/ Number(this.data.meta.totalOilExports || 2.41)) * 100);\n        const storageValue = this.clamp(this.storageAtDay(30) + (s.curtailmentStart && s.curtailmentStart <= 16 ? 10 : 0));\n        const terminalValue = this.channelWeightedScore(\"terminal\");\n        const fieldValue = this.clamp(this.channelWeightedScore(\"field\") * 0.82 + Number(e.producerSensitivity || 0) * 18);\n        const recoveryValue = this.channelWeightedScore(\"recovery\");\n        const residualShare = Number(s.residualExports || 0) \/ Number(this.data.meta.baselineExports || 1.69);\n        const buffers = this.clamp(100 - Number(s.stress || 0) * 0.68 + Number(e.bufferScore || 0) * 0.42 + residualShare * 18, 8, 100);\n        return { export: exportValue, storage: storageValue, terminal: terminalValue, field: fieldValue, recovery: recoveryValue, buffers };\n      }\n\n      signalStatus(value, good = false) {\n        const v = Number(value || 0);\n        if (good) {\n          if (v >= 67) return { label: \"Available\", cls: \"good\" };\n          if (v >= 34) return { label: \"Thin\", cls: \"watch\" };\n          return { label: \"Critical\", cls: \"hot\" };\n        }\n        if (v >= 67) return { label: \"Hot\", cls: \"hot\" };\n        if (v >= 34) return { label: \"Watch\", cls: \"watch\" };\n        return { label: \"Low\", cls: \"low\" };\n      }\n\n      buildMonitor() {\n        const values = this.monitorValues();\n        return this.data.monitorDefs.map((def) => {\n          const value = this.clamp(values[def.key]);\n          const status = this.signalStatus(value, def.good);\n          const cls = def.good && status.cls === \"good\" ? \"good\" : status.cls;\n          return `\n            <article class=\"signal ${cls}\">\n              <div class=\"signal-top\"><h3>${this.esc(def.label)}<\/h3><span class=\"status\">${this.esc(status.label)}<\/span><\/div>\n              <p>${this.esc(def.desc)}<\/p>\n              <div class=\"meter\" aria-label=\"${this.esc(def.label)} score ${Math.round(value)} out of 100\"><i style=\"width:${value}%\"><\/i><\/div>\n            <\/article>`;\n        }).join(\"\");\n      }\n\n      updateNetwork() {\n        const s = this.scenarioData();\n        const e = this.entityData();\n        const activeLinks = new Set(this.data.focusLinkMap[this.state.focus] || []);\n        const hotWidth = 2.6 + (Number(s.stress || 0) \/ 100) * 4.2;\n\n        this.shadowRoot.querySelectorAll(\".link\").forEach((link) => {\n          const isHot = activeLinks.has(link.dataset.link);\n          link.classList.toggle(\"hot\", isHot);\n          link.classList.toggle(\"dim\", !isHot);\n          link.style.setProperty(\"--hot-width\", `${hotWidth}px`);\n        });\n\n        this.shadowRoot.querySelectorAll(\".node\").forEach((node) => {\n          const focus = node.dataset.focus;\n          const key = node.dataset.node;\n          let score = 0;\n          if (focus) score = this.channelWeightedScore(focus);\n          if (key === \"shock\") score = Number(s.stress || 0);\n          if (key === \"residual\") score = this.clamp((1 - Number(s.residualExports || 0) \/ Number(this.data.meta.baselineExports || 1.69)) * 100);\n          if (key === \"production\") score = this.clamp((Number(s.prodLoss[\"90\"] || 0) \/ Number(this.data.meta.baselineProduction || 3.4)) * 100);\n          node.classList.toggle(\"active\", focus === this.state.focus);\n          node.classList.toggle(\"hot\", focus && score >= 34);\n          node.classList.toggle(\"dim\", focus && focus !== this.state.focus && !activeLinks.size);\n          const core = node.querySelector(\".core\");\n          const label = node.querySelector(\"[data-score]\");\n          if (core) {\n            core.setAttribute(\"r\", String(8 + this.clamp(score) * 0.16));\n            core.style.opacity = String(0.55 + this.clamp(score) \/ 220);\n          }\n          if (label) {\n            if (key === \"shock\") label.textContent = `${Math.round(score)} stress`;\n            else if (key === \"residual\") label.textContent = `${Math.round(score)}% denied`;\n            else if (key === \"production\") label.textContent = `${Math.round(score)}% loss`;\n            else label.textContent = `${Math.round(score)} score`;\n          }\n        });\n\n        this.setText(this.els.networkPill, `${this.focusData().label} \u00b7 ${this.fmtPct(this.channelWeightedScore(this.state.focus), 0)}`);\n      }\n\n      syncButtons() {\n        this.shadowRoot.querySelectorAll(\"[data-control]\").forEach((button) => {\n          const control = button.dataset.control;\n          const isActive = this.state[control] === button.dataset.key;\n          button.classList.toggle(\"is-active\", isActive);\n          button.setAttribute(\"aria-pressed\", String(isActive));\n        });\n      }\n\n      render() {\n        const s = this.scenarioData();\n        const e = this.entityData();\n        const f = this.focusData();\n        const dominant = this.dominantChannel();\n        const briefing = this.buildBriefing();\n        const productionLossRatio = this.clamp((Number(s.prodLoss[\"90\"] || 0) \/ Number(this.data.meta.baselineProduction || 3.4)) * 100);\n        const exportRatio = this.clamp((Number(s.exportLoss[1] || 0) \/ Number(this.data.meta.totalOilExports || 2.41)) * 100);\n\n        this.setText(this.els.title, this.data.meta.title);\n        this.setText(this.els.subtitle, this.data.meta.subtitle);\n        this.setText(this.els.eyebrow, this.data.meta.eyebrow);\n        this.setText(this.els.briefing, briefing);\n        this.setHtml(this.els.badge, this.stateBadgeHtml());\n\n        this.setText(this.els.kpiStress, `${Math.round(s.stress)} \/ 100`);\n        this.setText(this.els.kpiStressNote, `${s.riskLevel} risk \u00b7 ${this.scenarioMood(s.stress)}`);\n        this.els.kpiStressBar.style.width = `${this.clamp(s.stress)}%`;\n\n        this.setText(this.els.kpiPrimary, this.fmtMbd(s.exportLoss[1]));\n        this.setText(this.els.kpiPrimaryNote, `${this.selectedPrimaryRange()} range`);\n        this.els.kpiPrimaryBar.style.width = `${exportRatio}%`;\n\n        this.setText(this.els.kpiSecondary, this.fmtMbd(s.remainingProd[\"90\"]));\n        this.setText(this.els.kpiSecondaryNote, `${this.fmtMbd(s.prodLoss[\"90\"])} day-90 loss`);\n        this.els.kpiSecondaryBar.style.width = `${productionLossRatio}%`;\n\n        this.setText(this.els.kpiChannel, dominant.label);\n        this.setText(this.els.kpiChannelNote, `${this.fmtPct(dominant.value, 0)} weighted score for ${e.label}`);\n        this.els.kpiChannelBar.style.width = `${this.clamp(dominant.value)}%`;\n\n        this.setText(this.els.focusPill, `${s.shortLabel} \u00b7 ${e.label}`);\n        this.setText(this.els.focusTitle, f.label);\n        this.setText(this.els.focusBody, f.body);\n        this.setHtml(this.els.focusTiles, this.buildFocusTiles());\n        this.setHtml(this.els.pathBars, this.buildPathBars());\n\n        this.setText(this.els.entityPill, `${f.label} lens`);\n        this.setHtml(this.els.entityList, this.buildEntityList());\n\n        this.setText(this.els.marketPill, `${s.shortLabel} values`);\n        this.setHtml(this.els.marketRows, this.buildMarketRows());\n\n        this.setText(this.els.playbookPill, `${this.scenarioMood(s.stress)} mode`);\n        this.setHtml(this.els.playbook, this.buildPlaybook());\n\n        this.setText(this.els.monitorPill, `${e.label} \u00b7 live state`);\n        this.setHtml(this.els.monitor, this.buildMonitor());\n\n        const caveat = (this.data.caveats || []).find((line) => line.toLowerCase().includes(\"analytical scenario model\")) || \"Analytical scenario model, not a forecast.\";\n        this.setText(this.els.footerNote, `${caveat} Current briefing and CSV reflect the selected dashboard state.`);\n        this.updateNetwork();\n        this.syncButtons();\n      }\n\n      copyBriefing() {\n        const text = this.buildBriefing();\n        const done = () => {\n          this.setText(this.els.footerNote, \"Briefing copied to clipboard.\");\n          window.setTimeout(() => this.render(), 1200);\n        };\n        if (navigator.clipboard && navigator.clipboard.writeText) {\n          navigator.clipboard.writeText(text).then(done).catch(() => this.copyFallback(text, done));\n        } else {\n          this.copyFallback(text, done);\n        }\n      }\n\n      copyFallback(text, done) {\n        const area = document.createElement(\"textarea\");\n        area.value = text;\n        area.setAttribute(\"readonly\", \"\");\n        area.style.position = \"fixed\";\n        area.style.left = \"-9999px\";\n        document.body.appendChild(area);\n        area.select();\n        try { document.execCommand(\"copy\"); } catch (error) {}\n        document.body.removeChild(area);\n        done();\n      }\n\n      downloadCsv() {\n        const s = this.scenarioData();\n        const e = this.entityData();\n        const f = this.focusData();\n        const d = this.dominantChannel();\n        const rows = [\n          [\"Field\", \"Value\"],\n          [\"Scenario\", s.label],\n          [\"Risk level\", s.riskLevel],\n          [\"Stress\", s.stress],\n          [\"Entity \/ field\", e.label],\n          [\"Focus\", f.label],\n          [\"Dominant channel\", d.label],\n          [\"Export loss range\", this.selectedPrimaryRange()],\n          [\"Central export loss\", this.fmtMbd(s.exportLoss[1])],\n          [\"Residual crude exports\", this.fmtMbd(s.residualExports)],\n          [\"Production impact\", this.selectedSecondaryRange()],\n          [\"Curtailment start\", s.curtailmentStart ? this.fmtDay(s.curtailmentStart) : \"None\"],\n          [\"Recovery window\", s.recoveryWindow],\n          [\"Scarring band\", `${this.fmtPct(s.scarring[0], 1)}\u2013${this.fmtPct(s.scarring[1], 1)}`],\n          [\"Field production\", this.fmtMbd(e.productionMbd)],\n          [\"Field baseline share\", this.fmtPct(e.share, 1)],\n          [\"Field vulnerability\", e.vulnerability],\n          [\"Entity note\", e.mitigation],\n          [\"Briefing\", this.buildBriefing()]\n        ];\n        const csv = rows.map((row) => row.map((cell) => `\"${String(cell ?? \"\").replace(\/\"\/g, '\"\"')}\"`).join(\",\")).join(\"\\n\");\n        const blob = new Blob([csv], { type: \"text\/csv;charset=utf-8\" });\n        const url = URL.createObjectURL(blob);\n        const anchor = document.createElement(\"a\");\n        anchor.href = url;\n        anchor.download = `obex-iran-blockade-${this.state.scenario}-${this.state.entity}-${this.state.focus}.csv`;\n        document.body.appendChild(anchor);\n        anchor.click();\n        document.body.removeChild(anchor);\n        URL.revokeObjectURL(url);\n        this.setText(this.els.footerNote, \"CSV downloaded for the current dashboard state.\");\n        window.setTimeout(() => this.render(), 1200);\n      }\n    }\n\n    customElements.define(tagName, ObexLinkedDashboard);\n  })();\n  <\/script>\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Iran entered the 2026 crisis with crude production of approximately 3.3 to 3.5 million barrels per day (mb\/d), of which 1.5 to 1.6 mb\/d reached international buyers through an export network almost entirely dependent on the Strait of Hormuz. The Strait handles approximately 20 mb\/d of hydrocarbons \u2014 roughly 20 percent of global petroleum liquids [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":738,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[176,5],"tags":[62],"class_list":["post-725","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-situation-assessments","category-5","tag-featured"],"_links":{"self":[{"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/posts\/725","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/comments?post=725"}],"version-history":[{"count":4,"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/posts\/725\/revisions"}],"predecessor-version":[{"id":739,"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/posts\/725\/revisions\/739"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/media\/738"}],"wp:attachment":[{"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/media?parent=725"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/categories?post=725"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/obexanalytica.com\/ar\/wp-json\/wp\/v2\/tags?post=725"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}