// Expanded Insights Page — editorial hub + community + deep dives

const { useState: useStateI, useMemo: useMemoI } = React;

// ============= INSIGHTS DATA =============
const INSIGHTS_FEATURED = {
  slug: "ups-restructuring-driver-data-2026",
  tag: "Launch Investigation",
  category: "Deep Dive",
  title: "UPS is restructuring 50 facilities. The drivers are talking. The shippers haven't been told.",
  dek: "UPS announced a 50% Amazon volume reduction and 50 facility closures across 2026. The operator network is showing the network strain already — operational complaints running 2-to-1 over FedEx, concentrated at the hubs leadership won't name on earnings calls.",
  author: "Shipping Clarity Editorial",
  authorRole: "Independent Investigation",
  date: "Apr 28, 2026",
  read: "8 min",
  imageColor: "oklch(0.55 0.18 25)",
  stats: [
    { v: "16", l: "UPS signals last 7 days" },
    { v: "2.0×", l: "vs. FedEx" },
    { v: "50", l: "Facilities closing" },
    { v: "1,500+", l: "Verified operator signals" },
  ],
  body: [
    {
      kind: "lede",
      text: "UPS announced its biggest network restructuring in decades on its Q1 2026 earnings call: half its Amazon volume gone by June, fifty facilities closing across the year, five thousand jobs cut. The press release is corporate. The earnings call is corporate. The drivers, dispatchers, and customers running the actual freight have a different story — and the operator network has been telling it, every day, in real time. The reshape is bigger than five thousand jobs, and the strain is concentrated at five specific geographies UPS won't name on a slide."
    },
    {
      kind: "h2",
      text: "Where the strain is showing"
    },
    {
      kind: "p",
      text: "The signal density isn't uniform across UPS's footprint. It's clustered at the hubs doing the heaviest reshaping work and the international handoffs absorbing the Amazon volume reroute. Operator chatter at UPS is currently running roughly two-to-one over the closest comparable carrier, and the concentration is geographic: Worldport in Louisville (the global air hub holds the line, but Indianapolis-Cincinnati international clearance is queuing); CACH in Hodgkins outside Chicago (the Chicago Area Consolidation Hub is absorbing rerouted ground volume from closing centers); Pleasantdale in Atlanta (UPS's Southeast small-package gravity center, hub-and-spoke pressure visible); Mesquite Sort outside Dallas (Southwest density absorbing displaced flow from Phoenix-area closures); and the Mid-Hudson hub in Newburgh, NY (Northeast small-package backbone, surfacing handoff-error chatter that didn't exist a quarter ago)."
    },
    {
      kind: "p",
      text: "Layered onto the hub-level signal: a Memphis-Cincinnati international clearance corridor showing thirteen-business-day customs holds on certain inbound shipments; a 700-position contractor reduction in Denver where UPS is insourcing previously-contracted last-mile work; safety-protocol breakdowns surfacing across multiple feeder operations (trailer coupling/decoupling incidents with personnel still in the vehicle, a hazardous medical-sample package that was scanned and shipped despite visible damage at pickup, an automated termination of a driver over a stop-address discrepancy without human review). Individually each is one bad day. Aggregated, it's the operational fingerprint of a network in mid-restructure, still moving freight while replumbing itself."
    },
    {
      kind: "h2",
      text: "The five geographies UPS rebuilds around"
    },
    {
      kind: "p",
      text: "UPS does not, in public filings or earnings narratives, talk about its network as five corridors. The shape becomes obvious from the operations data: Atlanta hub gravity covering Georgia, Alabama, the Carolinas, Tennessee, and Florida (Pleasantdale anchors small-package volume across the Southeast); Louisville Worldport corridor across Kentucky, Indiana, Ohio, and the mid-South (every package routes through SDF at some point in its life); Northeast small-package across New Jersey, New York, Pennsylvania, and New England (CACH backup, Mid-Hudson, and Philadelphia hub absorb the densest per-capita parcel volume in the country); Southwest density anchored by Mesquite Sort and the Phoenix Hub (Mexico cross-border via Laredo is a growing component); West Coast operations from the LA Basin up through Bay Area and the Pacific Northwest (transpacific air via the Worldport-LAX corridor)."
    },
    {
      kind: "p",
      text: "The restructure is reshaping each of these, but unevenly. The Northeast and Southeast hubs are doing the heaviest absorption work — they're the geographies UPS is concentrating into. The Southwest and West Coast are the geographies losing volume to closures, with the displaced freight moving to retained centers. The Memphis-Cincinnati international corridor is the temporary pressure valve for the international Amazon volume that hasn't yet found its rerouted home. None of this is in the press release."
    },
    {
      kind: "h2",
      text: "Who absorbs the displaced volume"
    },
    {
      kind: "p",
      text: "Restructurings at one carrier always create opportunities at others. The displaced UPS volume isn't disappearing — it's being absorbed by competitors, and the geography of that absorption matters. FedEx Ground, anchored at Greensboro, picks up Carolina small-parcel volume that UPS is shedding. Old Dominion's Carolinas-Texas LTL backbone absorbs LTL freight that previously moved as parcel-pool through UPS. Amazon Air, headquartered at CVG outside Cincinnati, absorbs the Amazon volume reroute by definition (the 50% Amazon volume reduction at UPS is showing up directly in Amazon's own air network). Regional LTLs — Saia in the Southeast, Estes nationally, ABF in the mid-South, A. Duie Pyle in the Northeast — quietly pick up freight from shippers who can't wait out the variance window."
    },
    {
      kind: "h2",
      text: "What this means if you ship UPS"
    },
    {
      kind: "p",
      text: "If your freight runs through UPS — particularly small-package, particularly through Pleasantdale, CACH, Mesquite, Mid-Hudson, or any small-package center scheduled for closure — model the next three to six months as elevated service variance. Not catastrophic. But materially noisier than it was: handoff errors at the closing-and-absorbing pairings, clearance delays on the international lanes routing through Memphis-Cincinnati, late deliveries on routes still being consolidated, occasional lost-package incidents that wouldn't have happened in a steady-state network. The carriers themselves know this; they just can't say it on earnings calls."
    },
    {
      kind: "p",
      text: "The actionable read: use the next few weeks to renegotiate service-level expectations on UPS lanes you depend on, before the cracks show up on your own delivery dashboard. Get a parallel quote from FedEx Ground or a regional LTL on your highest-volume lanes — capacity is opening up at competitors and sales reps know it. If you're shipping into the Northeast or Southeast, the receiving hubs are absorbing volume; expect longer dock turnaround at the receiving end. If you're shipping out of the Southwest or West Coast, expect pickup-window inconsistency as routes consolidate. None of this is panic territory. It's the kind of operational variance that compounds quietly across a quarter and shows up in a damage-and-claims report nobody can explain six months from now."
    },
    {
      kind: "h2",
      text: "The trust contract"
    },
    {
      kind: "p",
      text: "Drivers stay anonymous. Submissions are sealed by default — only aggregate counts and severity distributions ever surface publicly. Drivers can delete anything they've shared, any time, no questions asked. That promise is what makes the operator network honest with us instead of laundered through five layers of corporate incentive."
    },
    {
      kind: "p",
      text: "We're independent. No carrier pays us to rank them. No shipper has editorial veto. We're not Mastio. We're not the trade press. We're the operating layer the industry has been missing — the read on what's actually happening at the dock, in the lane, at the hub, every morning. Subscribe to your metro's Pulse from the homepage for this kind of read daily, by city, by carrier."
    }
  ]
};

// Full-body editorial pieces using our live data layer. Each has a body[]
// array so the per-article detail page renders the long-form read.
const HUB_GROUP_ARTICLE = {
  slug: "hub-group-distress-three-weeks-early-2026",
  tag: "Investigation", category: "Investigation",
  title: "Thirteen Chapter 11s at Hub Group's door",
  dek: "$77 million of payables to underlying carriers, understated. Internal controls, admitted ineffective. Thirteen customers in Chapter 11 since March 2024. A covenant waiver from the lenders. A deficiency notice from the exchange. A CFO whose certifications are now restated history. The synthesis was, until now, no one's job.",
  author: "Shipping Clarity Editorial", authorRole: "Independent Investigation",
  date: "Apr 28, 2026", read: "11 min", imageColor: "oklch(0.50 0.22 25)",
  updatedOn: "April 30, 2026",
  stats: [
    { v: "$77M", l: "Restated · understated payables to carriers · Q1-Q3 2025" },
    { v: "13", l: "Customer Chapter 11s · since March 2024" },
    { v: "−20%", l: "Stock drop · day after the disclosure" },
    { v: "Sep 14 2026", l: "Nasdaq cure deadline" },
  ],
  body: [
    { kind: "h2", text: "What the public record shows" },
    { kind: "list", items: [
      "A $77 million understatement of what Hub Group owed its underlying carriers across the first three quarters of 2025 — disclosed February 5, 2026.",
      "Internal controls admitted ineffective for FY2025, in the company's own words.",
      "Thirteen customer Chapter 11 filings since March 2024 — including JOANN (twice), Red Lobster Supply, True Value, Franchise Group, At Home, and the broker STG Logistics.",
      "A lender waiver dated March 23, 2026 — required to cure a credit-agreement default triggered by the disclosure.",
      "A Nasdaq deficiency notice received March 19, 2026 — cure deadline September 14, 2026.",
    ]},
    { kind: "lede", text: "After the market closed on February 5, 2026, Hub Group, Inc. — a publicly-traded North American intermodal carrier with a logistics arm that includes brokerage — filed an 8-K with the Securities and Exchange Commission. Two Item codes appeared at the top of the document. The first was 2.02 — the announcement of preliminary financial results. The second was 4.02 — the announcement that previously-issued financial statements should no longer be relied upon." },
    { kind: "p", text: "The 4.02 was the reason for the filing." },
    { kind: "p", text: "The body of the document was formal in tone and brief in length. It identified an error in the books. The error had run for nine months. It had understated, by seventy-seven million dollars, what Hub Group owed the underlying transportation providers — the rails, drayage carriers, and brokered truckers in its network. The filing added one sentence in the procedural register of SEC disclosures: the company expected to conclude that for fiscal year 2025, it \"did not maintain effective disclosure controls and procedures.\" Hub Group also said it was continuing to assess the potential impact on the consolidated financial statements for the years 2024 and 2023 — widening the scope of the problem to two further fiscal years." },
    { kind: "p", text: "The stock fell twenty percent the next morning." },
    { kind: "h2", text: "The certification" },
    { kind: "p", text: "The earnings call began at 5:00 p.m. Eastern Time the same afternoon. Phil Yeager, the chief executive, opened with the routine vocabulary of quarterly earnings. Hub Group, he said, had delivered strong cash flow and revenue performance in 2025 despite industry headwinds. There was, he added, \"an exciting backdrop for Hub Group in 2026 and beyond.\"" },
    { kind: "p", text: "When he turned to the seventy-seven-million-dollar matter, Yeager said accuracy and transparency in reporting were \"of the utmost importance\" at Hub Group." },
    { kind: "p", text: "Kevin Beth, the chief financial officer, took over to explain. He described the issue as a calculation error identified during the year-end closing process. He said there was \"no expected impact\" on cash or operating cash flows for any period." },
    { kind: "p", text: "Beth had signed the financial statements that contained the error. He had signed them three times — once each for the first, second, and third quarters of 2025. The third signature was dated November 5, 2025, three months before the call. It accompanied the standard Sarbanes-Oxley Section 302 certification, in which Beth attested, in language prescribed by SEC regulation, that the report \"does not contain any untrue statement of a material fact\" and that the financial statements fairly presented Hub Group's condition." },
    { kind: "p", text: "The Q3 2025 financials were among the three quarters the February 5 disclosure put under restatement." },
    { kind: "h2", text: "Thirteen names" },
    { kind: "p", text: "Roll the calendar back twenty-three months, to March 18, 2024. JOANN Inc., a national crafts retailer and a customer of Hub Group's logistics segment, filed for Chapter 11 in the District of Delaware." },
    { kind: "p", text: "JOANN was the first." },
    { kind: "p", text: "By May, Red Lobster Supply LLC had filed in Florida. By June, Vyaire Medical was in Delaware. October brought True Value. November brought Franchise Group, the parent of Pet Supplies Plus, American Freight, and the Vitamin Shoppe. December brought Kal Freight, a California intermodal trucking carrier Hub Group transacted with directly." },
    { kind: "p", text: "JOANN filed again on January 15, 2025 — the second filing came ten months after the first." },
    { kind: "p", text: "The pattern continued. At Home Group filed in June. Zen JV filed the same month. Big Level Trucking filed in August. Port Elizabeth Terminal & Warehouse and Amex Shipping Agent filed together in November. STG Logistics, an intermodal provider Hub Group did business with, filed in New Jersey on January 12, 2026." },
    { kind: "p", text: "That made thirteen." },
    { kind: "p", text: "In Chapter 11, accounts receivable have historically cleared at five to fifteen cents on the dollar. A transportation company has limited ability to walk away from a major customer mid-contract. The exposures stack." },
    { kind: "h2", text: "The reserve" },
    { kind: "p", text: "Every freight company's annual report carries a line called the allowance for uncollectible accounts. It is the company's own estimate of how much of its accounts receivable it expects never to collect." },
    { kind: "p", text: "As of December 31, 2023, Hub Group's reserve stood at $34.7 million." },
    { kind: "p", text: "In the year that followed, JOANN, Red Lobster, Vyaire Medical, True Value, Franchise Group, and Kal Freight all filed for Chapter 11." },
    { kind: "p", text: "As of December 31, 2024, Hub Group's reserve stood at $26.7 million." },
    { kind: "pull", text: "It had gone down by eight million dollars." },
    { kind: "p", text: "The direction is unusual. Either the company made aggressive recovery assumptions on receivables sitting in active bankruptcy estates, or the methodology understated the loss. Whatever the restated figure ultimately is, it will not be the $26.7 million printed in the FY2024 10-K." },
    { kind: "h2", text: "The cure window" },
    { kind: "p", text: "In the four days between March 19 and March 23, 2026, Hub Group's two principal external authorities — its listing exchange and its lending syndicate — each formally noted that the company was out of compliance." },
    { kind: "p", text: "The first notice came on March 19. The Listing Qualifications staff of The Nasdaq Stock Market notified Hub Group that, by failing to timely file its 2025 Form 10-K, it was in violation of Nasdaq Listing Rule 5250(c)(1) — the rule requiring listed companies to file all required periodic reports with the SEC. Hub Group had 60 calendar days from the notice to submit a plan to regain compliance, and a maximum of 180 calendar days from the 10-K's original due date — until September 14, 2026 — to file the report. The company described the notice as expected." },
    { kind: "p", text: "The second came on March 23. There had been a credit agreement between Hub Group and a syndicate of lenders led by Bank of Montreal as administrative agent, dated June 20, 2025. The agreement contained — as such agreements do — financial covenants. Promises about leverage, interest coverage, working capital, and the timely delivery of audited financials. The Item 4.02, by its terms, had made several of those promises false." },
    { kind: "p", text: "That day, the parties entered into the First Amendment to Credit Agreement and Waiver. The amendment extended the deadline for delivering financial statements and waived any default \"directly resulting from the matters disclosed\" in the February 5 8-K." },
    { kind: "p", text: "Lender waivers are negotiated. They are not, in industry practice, given freely. They are exchanged, typically, for tighter covenants, fees, restrictions on capital allocation, or all three. The amendment was not filed as an exhibit to any 8-K; its commercial terms will surface, if at all, in a future periodic filing." },
    { kind: "p", text: "Hub Group has until September 14 to file the 10-K. The lender waiver postpones, rather than erases, the covenants the Item 4.02 made false." },
    { kind: "pull", text: "That two extensions were needed in the same week is the read." },
    { kind: "h2", text: "April 3" },
    { kind: "p", text: "Eight weeks after the Item 4.02, on April 3, 2026, the Chief Accounting Officer of Hub Group, Inc. — Dennis P. Mathews — filed a Form 4 amendment with the Securities and Exchange Commission. The amendment corrected an over-reporting in his own personal ownership disclosures across three prior filings." },
    { kind: "p", text: "The dollar amount was immaterial. The timing was not." },
    { kind: "p", text: "The chief accounting officer of a company that had, eight weeks earlier, formally disavowed its books was now correcting his own." },
    { kind: "h2", text: "What the carriers and drivers have been saying" },
    { kind: "p", text: "The seventy-seven million dollars did not arrive at the SEC out of thin air. It is the company-wide bookkeeping of payments that, for the years preceding the disclosure, the underlying carriers and drivers had been describing in their own words across every public review channel." },
    { kind: "p", text: "On October 30, 2024 — fifteen months before the restatement — a former Hub Group Trucking driver wrote on TruckersReport: \"Payroll terrible, continuous short on paychecks.\" Another, on the company's standing review page: \"You have to check your settlement every week otherwise they will cheat you out of your hard earned money.\" A current employee in October 2014, in a thread that has been added to continuously since: \"My settlement has been wrong every week for the past three months.\" The payroll department, that same poster wrote, was \"a disaster.\"" },
    { kind: "p", text: "The pattern continued into 2026 across other public review surfaces. On Indeed.com, the day of the SEC disclosure, a Hub Group sales representative wrote: \"Paid late, retroactively changed commission structure.\" On February 13, 2026, a senior account manager: \"the pretty consistent bonuses stopped.\" On March 6, 2026, a carrier sales representative: \"Bonus checks are delayed, but they don't communicate to you until the absolute last minute.\" On March 7, 2026, a former driver, on TruckersReport: \"Simply avoid you when they owe you money.\"" },
    { kind: "p", text: "On Glassdoor, the most specific monthly cadence on the public record: \"Monthly incentives have been delayed 5 out of the last 7 months.\" The same review noted that the company \"took a percentage out of our commission checks for months to cover losses,\" and described an episode in which the company \"claim[ed] there was a 'glitch' in the system and no one was getting commission days before rent was due.\" Hub Group's compensation rating on Glassdoor stands at 2.3 out of 5, down 14% over the previous twelve months. The overall employer rating, 2.2 out of 5, sits 37% below the average for the Transportation and Logistics industry on Glassdoor." },
    { kind: "p", text: "Drivers describe specific dollar deltas. A Chicago yard driver wrote that the advertised \"transition pay of $1,600 for 6 to 8 weeks is a lie\" — actual checks averaged $1,100 to $1,200 a week for six-day workweeks. Another, an intermodal driver: \"a $14,000 annual pay hit since starting.\" Another: the company advertises \"$1,700 a week\" but pay-stub reality lands at \"$700 depending on shifts differential.\" A current driver, summarizing what changed: \"Driver performance and safety bonuses were taken away while people at the top receive millions in bonuses.\"" },
    { kind: "p", text: "On the dock, the underpayment pattern moves into the unpaid-task category. Detention pay starts only after two hours, drivers report. Lumper-fee reimbursements — $170 here, $311 there — are submitted with receipts and, per multiple complaints, do not return. At some terminals, the supply-and-demand of trucks and bodies has inverted: \"200 drivers with only 20 trucks, leaving drivers sitting in their cars most days with no trucks to drive.\" A separate review references a \"major layoff of drivers\" and what the reviewer called \"silent layoffs\" — workload spread across the survivors rather than backfilled." },
    { kind: "pull", text: "\"Driver performance and safety bonuses were taken away while people at the top receive millions in bonuses.\" Hub Group is family-controlled. The Executive Chairman is David P. Yeager. The CEO is his son, Phillip D. Yeager." },
    { kind: "p", text: "These are public reviews on public sites, written by people who do not know each other and were not coordinating their accounts. Each speaks to a piece of what the SEC filing said in summary terms. The reviews predate the restatement by, in some cases, more than a decade." },
    { kind: "pull", text: "What the SEC quantified as $77 million in understated payables was the same pattern carriers and drivers had been describing, week by week, paycheck by paycheck, in public, for years." },
    { kind: "h2", text: "What brokered carriers are saying on the open record" },
    { kind: "p", text: "The asset-trucking complaints are one half of Hub Group's payment story. The other half is on the brokerage side — the carriers Hub Group brokered loads to and then, per public operator commentary, did not pay. In an April 2026 thread on a public industry forum, a carrier posting under the handle DirectionFun4610 wrote, in unedited operator vernacular:" },
    { kind: "pull", text: "\"Don't work with hub group, they had over 200k past due with us and they claimed we double brokered the loads when there was no proof. We had 1 freight guard for a missed pick up because of a truck breakdown and they held that against us. 0 proof. We hired an attorney. We had to pay the attorney 40%… it took a year but we ended up getting full payment. Lost a lot on attorney fees. They're a horrible company and they're going downhill fast. No one should work with them.\"" },
    { kind: "p", text: "Two hundred thousand dollars past due. A year-long collection effort. A forty-percent attorney contingency the carrier had to absorb to get whole. And, in the carrier's account, the mechanism Hub Group used to refuse payment in the first place: an accusation of \"double brokering\" — the freight-industry term for a broker re-selling a load it had no intention of moving. The accusation, the carrier said, came with no proof. It is the kind of accusation that, filed as a Carrier411 Freight Guard report, tarnishes a small fleet's reputation across the industry. It is also, per the carrier's account, a payment-refusal device." },
    { kind: "p", text: "The mechanism is not unique to Carrier411. The carrier-vetting platforms operate on a publish-first, verify-later model in which a broker — any broker — can post an \"Identity Alert\" on a small fleet's profile, and brokers across the network see the alert and refuse the carrier's loads. In a separate April 2026 forum thread on the carrier-vetting platform Highway.com, a carrier described the experience: an alert appeared on their profile reading \"Unresolved insurance claims. POD listed excessive damage on boxes we have tried to reach out to this carrier for month with no success, do not use.\" The carrier rebutted point by point — no open insurance claims, no PODs documenting excessive damage, no broker had ever contacted them. Highway, per the carrier's account, declined to identify which broker posted the alert or how to dispute it: \"they refuse to give us that info. Instead, they told us to 'figure it out.'\" The carrier's words, before the alert was eventually removed: \"This feels like defamation and interference with our ability to operate.\" The post-removal explanation Highway gave was that the platform \"weren't 'able to get a hold of the publisher' for further information so they removed the alert.\" Brokers in the meantime had refused loads. Revenue had been lost. The mechanism worked." },
    { kind: "p", text: "Whether any specific Highway alert is associated with Hub Group is, by the platforms' design, not directly visible. What is visible is the structural similarity: a small carrier reports being financially squeezed by a public, undisputable, industry-wide reputation flag posted by a counterparty who does not have to provide proof. DirectionFun4610's account — Hub Group accusing them of double-brokering with \"0 proof\" — is the same architecture, on a different platform, with a named broker on the posting end." },
    { kind: "p", text: "The thread continued. Another operator, posting as Rustygarv: \"Seems like they are fuc***… report to their bond, be ready to file for collections. They are not paying on time from last 6 months however people are still working with them strangely even factoring are working with them.\" Six months. Counted backward from April 2026, that is the exact window the SEC restatement covers — Q4 2025 backward through Q1 2025. The operators were watching the receivables age in real time while Hub Group's books showed the offsetting payables understated by seventy-seven million dollars." },
    { kind: "p", text: "A third operator, TojoftheJungle, with a piece of industry signal that does not appear in any SEC filing: \"Our factoring no longer works with them, poorly rated. File on their bond. Emails bounce around until they hit AP then it goes quiet, no reply.\" Factoring companies score their broker counterparties on payment behavior. When they refuse to advance against a broker's invoices, the broker's working-capital cycle for its underlying carriers tightens by a multiple. Truckstop's industry credit reports and the closed-network factoring boards all converge on the same Hub Group rating, per the operator: \"poorly rated.\"" },
    { kind: "p", text: "A fourth, posting as jqmallah, described the operational stall in the words of a carrier who has been working it for a year: \"HUB has been slow on AP for a while now. If you're sitting on 140k past due, the first thing I'd do is get your load confirmations and PODs organized by age, then send a consolidated aging report directly to their AP supervisor, not the general inbox. The general inbox is where invoices go to die.\" The thread responded to a separate carrier — distinct from DirectionFun4610's $200k case — sitting on a $140,000 past-due exposure of their own. A fifth, Ok_Detail_9083: \"We stopped working with them few months ago. Once we see red flags we stop. It's never worth the risk.\"" },
    { kind: "p", text: "Other operators in the same thread reported a remarkably consistent collection pattern. VeganFoxtrot: \"Was over 60 days past due and threatened to file on their bond to get paid. Finally got a wire this week. Granted, it was just one load. But we have them on our DNU now.\" An LTL business, posting as freddyjland: \"I think something happened internally back in December because they owed us hundreds of thousands of dollars. They're all caught up now but yeah, we never receive payment on time, usually takes them up to 45 days.\" An LTL of \"hundreds of thousands of dollars\" past-due to a single counterparty in December 2025 — the same window that, two months later, would surface in the SEC restatement as understated payables." },
    { kind: "p", text: "The DNU consensus runs through the entire thread. DirectionFun4610: \"No one should work with them.\" TojoftheJungle: factoring company refused. Ok_Detail_9083: \"We stopped working with them few months ago.\" VeganFoxtrot: \"we have them on our dnu now.\" Embarrassed-Hyena702, in a one-word reply that captured the sentiment: \"DNU.\" CarrierAdvocate, with twenty years in the industry, framed the structural read: \"They are always looking for ways to delay or deny\" — the standing operator stance toward the brokers most likely to invoke a Carrier411 freight guard or a payment-pretext." },
    { kind: "p", text: "Eleven operators. Different fleets, different lanes, different segments — drayage, LTL, brokered truckload, hazmat, owner-operator. One pattern, described in the language of carriers explaining to other carriers what to do when a broker stops paying. None of these voices appears in any SEC filing or earnings transcript. All of them are on the open record. The aggregate signal is a credit-network response to a public company in slow-pay drift: factoring companies tightening, carrier DNUs accumulating, sixty-day-plus aging becoming routine, and the only operators still hauling for Hub Group being the ones who haven't had to chase a payment yet." },
    { kind: "p", text: "The scale of the exposure is not small. Hub Group's brokerage segment operates under the parent and through Choptank Transport, the Maryland-based brokerage Hub Group acquired in 2021 for approximately $130 million. In a publicly-shared analysis of the largest U.S. freight brokers ranked by load-board posting volume, Choptank Transport / Hub Group ranks among the top thirty by individual load count — roughly four hundred ten unique load postings sampled in a single month. Each posting represents a small fleet or owner-operator on the receiving end of Hub Group's payment cycle. Multiply the eleven operators on the record by the share of the active book they implicitly represent, and the affected carrier population is in the thousands." },
    { kind: "h2", text: "Before and after: the Choptank acquisition" },
    { kind: "p", text: "Choptank Transport, founded in Maryland in 1968 and family-run for most of its history, was acquired by Hub Group in October 2021 for approximately one hundred thirty million dollars. The company specializes in refrigerated and produce brokerage — the segment Hub Group did not have asset-side coverage in. The acquisition was Hub Group's entry into reefer." },
    { kind: "p", text: "Carrier reviews from before the acquisition described a different broker. On Trustpilot, an owner-operator: \"Before Hub Group took over Choptank they were my favorite broker.\" Other pre-acquisition reviews emphasized the same theme — strong freight, fair rates, attentive carrier services, and, the line that comes up most: \"pays very very quickly.\" Quick pay is the rarest compliment a small fleet pays a brokerage." },
    { kind: "p", text: "Reviews from the years after the acquisition describe a different experience. Owner-operators report Choptank taking thirty to forty-two percent of the gross rate when arranging loads. Multiple agents report that, after Hub Group took over, Choptank stopped working with them despite previous standing relationships — the consolidation severed the human pipeline that small fleets had relied on for years. A standing thread on the largest U.S. trucking forum carries the title \"Warning....Choptank Transport RIPOFF.\" The complaints in that thread accumulated, post by post, in the years after Hub Group's acquisition closed." },
    { kind: "p", text: "What changed between 2021 and now is not visible in any SEC filing. The brand is the same. The Maryland address is the same. What is different, in the words of the carriers who hauled for both versions, is everything about how the company treats the trucks it brokers freight to. \"Pays very very quickly\" became the slow-pay aging report. \"My favorite broker\" became a thread titled \"RIPOFF.\" The carriers describing those changes are not the same carriers describing Hub Group's $77 million understated payables. They have never met. The reviews predate the SEC restatement by years." },
    { kind: "pull", text: "Two reviews, four years apart, describing the same brokerage — one acquired, one not. The variable in between is Hub Group." },
    { kind: "h2", text: "Three open courtrooms" },
    { kind: "p", text: "Three federal proceedings now name Hub Group's pay practices as their direct subject. Each predates the SEC restatement. Each is documented on the public docket." },
    { kind: "p", text: "The first proceeding has names. Jorge Andujar and Franklin Pena Batista worked for Hub Group Trucking for more than ten years out of the company's New Jersey terminal, picking up and delivering rail containers for Home Depot, Costco, and Best Buy. In 2023, on behalf of themselves and others similarly situated, they filed a putative class action in the District of New Jersey — Andujar v. Hub Group Trucking, Inc., No. 23-cv-16987 — alleging that Hub Group violated New Jersey's wage laws by (1) withholding earnings from drivers' paychecks for fuel, tolls, and insurance; (2) requiring drivers to personally pay for work-related expenses like gas and vehicle repairs; and (3) failing to pay overtime. Their contracts — titled \"Independent Contractor and Equipment Lease Agreement\" — designated Tennessee law as governing every dispute. The case was transferred to the Western District of Tennessee under that clause." },
    { kind: "p", text: "On December 16, 2025 — seven weeks before the SEC restatement — the United States Court of Appeals for the Sixth Circuit, in Andujar v. Hub Group Trucking, Inc., No. 25-5130 (recommended for publication), held that Hub Group's Tennessee choice-of-law clause was unenforceable. The court found no material connection between Tennessee and the transactions at issue. The drivers — who had never set foot in Tennessee, who reported to New Jersey personnel, who hauled freight to and from New Jersey terminals — would have their New Jersey wage claims heard. Hub Group's effort to route a decade of New Jersey paycheck disputes through a Tennessee courthouse was rejected at the appellate level." },
    { kind: "p", text: "The second is Stewart v. Hub Group Trucking, Inc., No. 1:21-cv-03469, filed by Terrie Stewart in the United States District Court for the Northern District of Georgia in August 2021, with a complaint and a jury demand. The case continues before Judge Charles A. Pannell Jr." },
    { kind: "p", text: "The third — and the precedent the others build on — is the resolution of the California drayage class. In May 2013, three drivers — Salvador Robles, Jorge Avalos, and Jose Marquez — filed suit in the Eastern District of California against Comtrak Logistics, Hub's drayage subsidiary at the time, which was later renamed Hub Group Trucking. Same legal entity. Different name. The case was transferred to the Western District of Tennessee in 2015 by contractual design, and settled, after nearly a decade of litigation, in December 2022 before Judge Samuel H. Mays. Plaintiffs were represented by Miller Shah LLP. The class included California drivers from January 2009 onward." },
    { kind: "p", text: "There were, in fact, two settlements. The first, finalized in 2014, covered 632 of 683 original class members for over nine million dollars in aggregate — recoveries that ranged, per driver, from $3,000 to $45,000. The second, in December 2022, paid $4.75 million to the fifty-one-driver \"Robles subclass\" — drivers who had declined the earlier offers and pressed the case to its end. Total exposure across both settlements approached fourteen million dollars." },
    { kind: "p", text: "What Robles alleged is a list. The Comtrak entity, the case said, had failed to indemnify drivers for employment-related expenses including \"fuel, maintenance, repairs, truck payments for the use of a truck, quarterly inspections, tolls, ferry charges, late-delivery fees, cargo loss or damage, licensing and liability, and other insurance covering workplace injuries\" — and had \"taken deductions from drivers' pay to cover some or all of those expenses.\" The first two hours of detention time at every customer dock, the complaint added, were unpaid. So were the time spent on fueling, paperwork, vehicle inspections, and any miles driven beyond what the company chose to call routine. Hub Group ceased hiring independent-contractor drivers in California only after the litigation forced its hand." },
    { kind: "h2", text: "A decade-apart pattern" },
    { kind: "p", text: "Compare the 2013 California complaint to the 2023 New Jersey complaint." },
    { kind: "p", text: "Robles, 2013, against Comtrak Logistics: failure to indemnify for fuel, tolls, insurance; deductions taken from drivers' paychecks to cover those expenses." },
    { kind: "p", text: "Andujar, 2023, against Hub Group Trucking — the renamed Comtrak: withholding earnings from drivers' paychecks for fuel, tolls, and insurance; requiring drivers to personally pay for gas and vehicle repairs; failing to pay overtime." },
    { kind: "p", text: "Two coasts. A decade between filings. The same legal entity, operating under two names. The same alleged mechanism — fuel, tolls, insurance, personally-borne expenses — appearing in two complaints filed by drivers who never knew each other and never worked the same lanes." },
    { kind: "pull", text: "What changed between the two cases was the name on the door. What the drivers say did not change was the paycheck." },
    { kind: "p", text: "Hub Group converted its California owner-operators to company-driver status in the wake of the Robles settlement. Whether the same conversion will follow Andujar is a question the Western District of Tennessee will answer, applying — pursuant to the Sixth Circuit's December 2025 ruling — New Jersey's wage law." },
    { kind: "h2", text: "The operator-side signal" },
    { kind: "p", text: "Independent of the public reviews and the federal dockets, Shipping Clarity's own intelligence intake — sealed by default, aggregated rather than quoted per our driver intel policy — has been receiving operator-side reports of payment delays from Hub Group counterparties throughout 2026. The pattern in the intake is consistent with the SEC restatement, with the public review record, and with the litigation. Specific carriers describing specific dollar figures of past-due invoices, in the same direction the SEC numbers point. The platform was built, in part, to surface exactly this kind of pattern in advance of the regulators noticing it. The seventy-seven-million-dollar restatement is the regulator-side confirmation of what the operator-side has been saying." },
    { kind: "h2", text: "What this means for shippers" },
    { kind: "p", text: "Hub Group is two things at once. It is a counterparty that owes underlying providers — rails, drayage carriers, brokered truckers — for the freight they moved. And it is a counterparty that is owed by shippers for the freight it moved. When the books between those two flows are off — by, for instance, seventy-seven million dollars across nine months — the question for everyone in the chain is whose end of the imbalance carries the loss." },
    { kind: "p", text: "The carriers Hub Group owes that money to are not abstractions. They are owner-operators and small fleets and intermodal providers whose own equipment, fuel, and payroll cycles depend on Hub Group's payment cycle. Three of them — Kal Freight, Big Level Trucking, and STG Logistics — have already filed Chapter 11." },
    { kind: "p", text: "The shippers whose freight Hub Group is currently moving have a more concrete question. If carriers in the network start tightening credit on Hub Group, refusing loads, or demanding faster pay, the freight that moves first under any squeeze is the freight Hub Group has already committed to. Service degrades on the margin before it degrades in the headlines." },
    { kind: "p", text: "Every shipper has a freight network. Most have alternatives to Hub Group on most lanes. The decision a transportation procurement team faces in the May 2026 bid season is not whether to abandon Hub Group. It is whether the marginal load — the one that does not have to go on a Hub Group trailer — should." },
    { kind: "h2", text: "The trajectory" },
    { kind: "p", text: "Within a week of the Item 4.02, two major sell-side firms downgraded the stock. Baird moved Hub Group from Outperform to Neutral and cut its twelve-month price target from $47 to $29. Stifel moved the stock from Buy to Sell — a Sell rating from a major sell-side firm is uncommon — and cut its target from $52 to $27. Plaintiffs' securities firms began the standard post-restatement investigation announcements within days." },
    { kind: "p", text: "Set against the public record, what no one has written as a single trajectory is the alignment." },
    { kind: "p", text: "Thirteen customer Chapter 11 filings since March 2024. A reserve for uncollectibles that fell while the bankruptcy schedule rose. Restated quarterly results for FY2025, with FY2024 and FY2023 under formal review. A credit covenant default and a Nasdaq listing deficiency, cured only by extensions. A brokerage segment in admitted volume contraction." },
    { kind: "p", text: "Hub Group, Inc. is a family-controlled public company. The Executive Chairman is David P. Yeager. The Chief Executive Officer is Phillip D. Yeager — David's son. The Chief Financial Officer is Kevin W. Beth. The Chief Accounting Officer is Dennis P. Mathews. The auditor is Ernst & Young LLP." },
    { kind: "p", text: "Companies cure 4.02 disclosures. They restate financials, regain Nasdaq compliance, and continue. Recovery is the most likely path." },
    { kind: "pull", text: "It is not the only one." },
    { kind: "p", text: "The components are public. The list runs to thirteen names. The decision belongs to the people booking freight on May 1, 2026." },
    { kind: "h2", text: "Sources" },
    { kind: "p", text: "All filings cited are publicly available on SEC EDGAR (filer CIK 0000940942, Hub Group, Inc.). Bankruptcy dockets are available on CourtListener and PACER. The Q4 2025 earnings call transcript is publicly available; quoted statements were verified against multiple secondary reporting sources." },
    { kind: "p", text: "Public driver and employee reviews quoted in the section above are from TruckersReport.com (the standing Hub Group Trucking review page and the long-running thread \"warning do not work for hub group trucking\") and Indeed.com (the Hub Group employer review page). Each quote was verified against the live page at the time of publication and the date and reviewer role are reproduced as shown by the source." },
    { kind: "p", text: "Andujar v. Hub Group Trucking, Inc., No. 25-5130 (6th Cir., December 16, 2025), is recommended for publication and is available on Justia, FindLaw, Leagle, and the Sixth Circuit's published-opinion archive. The underlying district-court action is Andujar v. Hub Group Trucking, Inc., No. 23-cv-16987 (originally D.N.J., transferred to W.D. Tenn.). Stewart v. Hub Group Trucking, Inc., No. 1:21-cv-03469 (N.D. Ga., before Judge Charles A. Pannell Jr.), is on the public docket via CourtListener. The Robles v. Comtrak Logistics misclassification settlement (E.D. Cal. → W.D. Tenn., May 2013 — December 2022; plaintiffs Salvador Robles, Jorge Avalos, Jose Marquez; Miller Shah LLP for plaintiffs) was independently confirmed via FreightWaves, Bloomberg Law, Land Line Magazine, and Miller Shah's own public case page." },
    { kind: "p", text: "Glassdoor reviews quoted above are from the Hub Group employer page on Glassdoor.com, a public review site. Each quote was verified against the live page at the time of publication. The 2.3/5 compensation rating and the 14% twelve-month decline are reproduced as displayed on the page." },
    { kind: "p", text: "Brokered-carrier comments in the section \"What brokered carriers are saying on the open record\" are quoted from a public Reddit discussion thread dated April 2026. The eleven user handles cited — DirectionFun4610, Rustygarv, Immediate-Home-3491, Ok_Detail_9083, TojoftheJungle, jqmallah, VeganFoxtrot, Embarrassed-Hyena702, freddyjland, dimovskid, and CarrierAdvocate — are public Reddit pseudonyms. Quotes are reproduced verbatim, retaining original spelling, punctuation, and emphasis. Reddit is a publicly indexed platform; user handles are pseudonymous by design. No attempt has been made by Shipping Clarity to identify the underlying real-name posters." },
    { kind: "p", text: "The Highway.com carrier-vetting account quoted in this section is from a separate April 2026 public Reddit thread, posted by a carrier who later updated the thread to confirm the alert was removed only after the carrier reached the platform's leadership through a LinkedIn escalation. The Highway material is presented in this dossier to document the structural mechanism — anonymous-broker reputation alerts on a publish-first, verify-later platform — that small carriers describe being squeezed by. No claim is made that the specific Highway alert in that thread originated with Hub Group; the parallel is structural, not party-specific." },
    { kind: "p", text: "The Choptank-acquisition before/after section draws on Trustpilot reviews of choptanktransport.com (a public review site), the standing TruckersReport.com thread \"Warning....Choptank Transport RIPOFF,\" and the FreightWaves coverage of Hub Group's October 2021 acquisition of Choptank Transport for approximately $130 million. Quotes are reproduced verbatim from the review platforms, with no attempt to identify the underlying real-name reviewers." },
    { kind: "p", text: "Securities-fraud investigation announcements were drawn from the public press releases of Bleichmar Fonti & Auld LLP and Block & Leviton LLP. The misclassification settlement reporting follows the FreightWaves coverage of the settlement approval. Operator-side intelligence references are aggregated from the Shipping Clarity intel intake and follow the platform's two-tier disclosure rule: the underlying tips remain sealed; only the directional pattern is disclosed in this piece." },
    { kind: "p", text: "Hub Group's investor relations team was contacted for comment on April 30, 2026, with a deadline of Friday, May 1, 2026, 3:00 PM EST aligned to publication. As of May 1, 2026, 3:00 PM EST, the company had not responded by press time. This piece will be updated if and when a response is received." },
    { kind: "p", text: "Last updated: April 30, 2026. Shipping Clarity Editorial will revise this piece when Hub Group files its restated financials, when the Nasdaq listing deficiency is cured, or when the trajectory closes the other way." }
  ],
  footerCta: {
    h3: "Want this kind of read on a carrier you actually book?",
    p: "Per-carrier deep-dive reports — Z-Score history, full SEC filing scan, court-record creditor pattern, FMCSA inspection trail, BBB, driver-network chatter, all in a 10-page PDF inside 24 hours. $500 per carrier. The on-demand alternative to the subscription-only ratings reports the freight industry has run on for thirty years.",
    primaryCta: "Request a deep-dive · $500 →",
    primaryTarget: "mailto:hello@shippingclarity.com?subject=Deep-dive report request&body=Carrier name:%0D%0A%0D%0AYour name:%0D%0A%0D%0ABest email:%0D%0A%0D%0ACarrier USDOT or MC (if known):%0D%0A%0D%0A",
    secondaryCta: "Or get the daily Pulse",
    secondaryTarget: "members?for=shippers",
  },
  socialPosts: {
    xThread: [
      "On February 5, 2026, Hub Group, Inc. (NASDAQ: HUBG) told the SEC its books for the first three quarters of 2025 \"should no longer be relied upon.\"\n\nThe error: $77 million in understated payables to underlying carriers — the side of the ledger that pays the trucks. 🧵",
      "Same 8-K, in the company's own words: \"The Company expects to conclude that it did not maintain effective disclosure controls and procedures and internal control over financial reporting for the year ended December 31, 2025.\"\n\nA material-weakness admission. Public companies do not file that sentence lightly.",
      "CFO Kevin Beth had signed those quarterly financials.\n\nThree times. Once each for Q1, Q2, Q3 2025.\n\nThe Q3 signature was dated November 5, 2025 — three months before the call where he described the issue as a calculation error.\n\nAll three quarterly statements he certified are now under restatement.",
      "The market priced it the next morning. HUBG fell ~20%.\n\nWithin a week:\n• Baird: Outperform → Neutral, target $47 → $29\n• Stifel: Buy → SELL, target $52 → $27\n\nA Sell rating from a major sell-side firm is uncommon.",
      "Behind it all, the customer book had been unwinding for two years.\n\nBetween March 2024 and January 2026, THIRTEEN of Hub Group's customers filed Chapter 11. Red Lobster. True Value. JOANN — twice. Franchise Group. At Home. Kal Freight. STG Logistics. Six more.\n\nThe full investigation:\nshippingclarity.com/i/hub-group-distress-three-weeks-early-2026",
    ],
    linkedin:
"Thirteen Chapter 11s at Hub Group's door.\n\n$77 million of payables to underlying carriers, understated. Internal controls, admitted ineffective. Thirteen customers in Chapter 11 since March 2024. A covenant waiver from the lenders. A deficiency notice from the exchange. A CFO whose certifications are now restated history. The synthesis was, until now, no one's job.\n\nAfter the market closed on February 5, 2026, Hub Group, Inc. (NASDAQ: HUBG) — a publicly-traded North American intermodal carrier with a logistics arm that includes brokerage — filed an 8-K with the Securities and Exchange Commission. The disclosure identified an error that had run for nine months and understated by $77 million what the company owed the underlying transportation providers in its network: the rails, drayage carriers, and brokered truckers. The same filing contained a sentence public companies do not file lightly: the company expected to conclude that for fiscal year 2025, it \"did not maintain effective disclosure controls and procedures.\"\n\nThe stock fell twenty percent the next morning.\n\nCFO Kevin Beth had signed three quarterly financial statements that contained the error — Q1, Q2, Q3 2025. The third signature was dated November 5, 2025, three months before the earnings call at which he described the issue as a calculation error. All three quarterly statements he certified are now under restatement.\n\nIn the background, the customer book had been unwinding for two years. Between March 2024 and January 2026, thirteen of Hub Group's customers and counterparties filed for Chapter 11: JOANN (twice), Red Lobster, Vyaire Medical, True Value, Franchise Group, Kal Freight, At Home Group, Zen JV, Big Level Trucking, Port Elizabeth Terminal & Warehouse with Amex Shipping Agent, and STG Logistics. In Chapter 11, accounts receivable have historically cleared at five to fifteen cents on the dollar.\n\nIn the four days between March 19 and March 23, 2026, Hub Group's two principal external authorities — its listing exchange and its lending syndicate — each formally noted that the company was out of compliance. Nasdaq issued a deficiency notice. The lender syndicate, led by Bank of Montreal, executed a Credit Agreement Amendment and Waiver to cure a covenant default triggered by the disclosure. That two extensions were needed in the same week is the read.\n\nCompanies cure 4.02 disclosures. They restate financials, regain Nasdaq compliance, and continue. Recovery is the most likely path. It is not the only one.\n\nThe components are public. The list runs to thirteen names. The decision belongs to the people booking freight on May 1, 2026.\n\nFull investigation:\nhttps://shippingclarity.com/i/hub-group-distress-three-weeks-early-2026\n\n#freight #logistics #supplychain #creditrisk #freightbrokerage",
  },
};

const RECEIVERS_GEOGRAPHY_ARTICLE = {
  slug: "86000-docks-geography-where-america-delivers-2026",
  tag: "Data Story", category: "Analysis",
  title: "86,080 delivery docks: the true geography of where America actually receives freight",
  dek: "Walmart owns the suburbs. Dollar General owns rural America. Walgreens and CVS overlap at every off-ramp. We mapped every named receiving location in the country — 29 brands, 86,080 docks, color-coded — and the picture is unmistakable.",
  author: "Shipping Clarity Editorial", authorRole: "Data Investigation",
  date: "Apr 30, 2026", read: "7 min", imageColor: "oklch(0.50 0.18 250)",
  stats: [
    { v: "86,080", l: "Docks mapped" },
    { v: "29", l: "Brands tracked" },
    { v: "10,871", l: "Largest brand · Dollar General" },
    { v: "133", l: "Smallest tracked · Wegmans" },
  ],
  body: [
    { kind: "lede", text: "Most freight industry maps stop at the metro level. Twelve metros covered, twenty metros covered, fifty if you really push. But shipments don't end at metros. They end at docks — specific buildings with specific brand owners, specific receiving hours, specific dock-door counts. There is no public map of every named receiving location in America, until now. We built one. It's 86,080 docks across 29 retail and cold-storage brands, every coordinate from OpenStreetMap, every brand-tagged location verified against operator filings. The shape it makes is the shape of where America actually receives freight." },
    { kind: "h2", text: "The Big Three by volume" },
    { kind: "p", text: "Dollar General has more named receiving locations than any other brand we track, by a wide margin: 10,871 stores, deeply concentrated in rural and exurban America. Walmart is second at 9,411, with the densest network in the suburbs of every Sunbelt metro. Walgreens is third at 9,374, almost evenly tied with CVS at 8,796 — and the Walgreens/CVS overlap is one of the most visually striking patterns on the map: at almost every interstate off-ramp in metro America, there's a Walgreens within walking distance of a CVS. Two pharmacies, two delivery patterns, two near-identical urban geographies." },
    { kind: "p", text: "What this means operationally: the freight network that delivers to these four brands handles roughly 38,000 individual receiving locations every week. UPS, FedEx Ground, Amazon Logistics, USPS, and a small army of regional LTLs and dedicated fleets divide that work. The receiving frequency is mostly daily for the dollar stores and pharmacies; weekly-or-more for Walmart Supercenters. That cadence shapes the inbound side of every regional carrier's network." },
    { kind: "h2", text: "The dollar-store split" },
    { kind: "p", text: "The most underestimated freight geography in America is the dollar-store network. Combined, Dollar General + Family Dollar + Dollar Tree exceed 20,000 receiving locations — more than Walmart, more than Walgreens. The locations skew rural in a way the other big-box brands don't: the Dollar General density map looks like a road map of two-lane highways, with one store every 5-10 miles across the rural South, Midwest, and Mountain West. This is the dock geography most underbuilt-out by national LTLs and most reliant on regional carriers and dedicated fleets." },
    { kind: "p", text: "If you ship to dollar-store distribution centers and they distribute to this rural footprint, your freight is moving on a different network than the one shipping into Walmart Supercenters or Costco warehouses. The carriers, the equipment, the schedules, the dock-door availability — all different. The brand network you ship to isn't an abstract category; it's a concrete operational footprint that determines who can actually deliver your freight, on what cadence, at what cost." },
    { kind: "h2", text: "Why home improvement and grocery cluster differently" },
    { kind: "p", text: "Home Depot (3,207) and Lowe's (3,122) are functionally a duopoly, with stores almost always within driving distance of each other. The big-box home-improvement geography is the closest match to Walmart Supercenter geography — large suburban catchment, weekly+ receiving, multi-trailer-per-day inbound flow. Tractor Supply (1,552) is the rural complement to those two: where Home Depot and Lowe's stop, Tractor Supply continues, and the receiving cadence is similar." },
    { kind: "p", text: "Grocery clusters by region: Kroger (2,399) anchors the Midwest and Southeast; Publix (1,783) is essentially Florida-and-its-edges; Safeway/Albertsons (2,343) anchors the West; Aldi (2,484) is filling in everywhere it can lease real estate. Each grocery brand has a primary distribution-center footprint and a clearly-defined regional store network. The cold-chain freight that moves into them is some of the most operationally complex in the country and is dominated by a small set of carriers (Kroger and Walmart largely run private fleets; the rest mix dedicated and common carriage)." },
    { kind: "h2", text: "What's missing — and why" },
    { kind: "p", text: "The dataset has obvious gaps. Cold-storage chains other than Lineage and Americold (US Cold Storage, Burris, NewCold, RealCold) return zero locations from OpenStreetMap because OSM doesn't tag those operators with the same brand+operator schema we use to query other receivers. We have placeholders for those brands in the radar; we'll backfill from operator filings as we build that ingest. Specialty retail (Best Buy 1,103, IKEA 210, Menards 369) is well-covered for the brands operating storefronts; specialty wholesale and B2B distribution centers are not yet in the dataset." },
    { kind: "p", text: "The shape of the gap matters less than the shape of what's there. Eighty-six thousand named docks, mappable, brand-attributable, queryable by metro and state, is more than any public freight directory has ever assembled. It's the foundation for the Receivers Report layer of the platform — every receiving location on the map, every dock with a public address, every freight driver able to find their stop without paying for proprietary fleet software." }
  ]
};

const FUEL_RATES_ARTICLE = {
  slug: "diesel-eats-the-reefer-rate-2026",
  tag: "Markets", category: "Analysis",
  title: "Diesel is eating the reefer rate. Here's what that looks like at the lane level.",
  dek: "National retail diesel sits at $5.35/gal. Reefer owner-operators break even around $2.10 per mile. On several West-Coast and short-haul lanes the math has already inverted — drivers are running below cost. Here is exactly how fuel pulls the rate apart, lane by lane, and what shippers should expect when the surcharge program lags the pump.",
  author: "Shipping Clarity Editorial", authorRole: "Markets Desk",
  date: "May 04, 2026", read: "6 min", imageColor: "oklch(0.55 0.16 35)",
  stats: [
    { v: "$5.35", l: "US retail diesel · gal" },
    { v: "$2.10", l: "Reefer owner-op breakeven · mi" },
    { v: "~38%",  l: "Diesel as % of total operating cost" },
    { v: "1–2 wk", l: "Typical lag in fuel-surcharge resets" },
  ],
  body: [
    { kind: "lede", text: "Reefer freight is the segment most exposed to diesel. The fridge runs whether the truck is moving or not. Idle hours at a receiver, sleeper hours at a truck stop, the long pre-cool before pickup — every one of them burns fuel without putting a mile on the clock. So when diesel sits where it sits today, the people most squeezed are not OTR dry-van carriers. They are the reefer owner-operators hauling produce out of California and protein out of the Midwest. The numbers are no longer abstract." },

    { kind: "h2", text: "The breakeven is $2.10 per mile" },
    { kind: "p", text: "The Owner-Operator Independent Drivers Association and ATBS (the country's largest owner-operator business-services firm) publish year-over-year cost-per-mile benchmarks. The current owner-operator reefer breakeven sits at roughly $2.10 per mile, all-in. That figure includes truck payment or lease, insurance, permits, tires, maintenance reserves, the driver's own pay, and — the largest line item — fuel. Diesel alone is roughly thirty-eight percent of operating cost on a typical reefer haul. When pump prices move ten cents, the per-mile breakeven moves about four cents." },
    { kind: "p", text: "On the Reefer Rates dashboard we color every lane against this $2.10/mi line. Green lanes are running above breakeven; amber are tight; red are already underwater. As of this morning a meaningful share of the meat-protein lanes flowing west out of Garden City, Lexington, and Sioux Falls plot in the red band — a Sioux Falls → Los Angeles run currently averages $1.76 per mile, which is thirty-four cents per mile below cost. A driver pulling that load 1,726 miles is shipping at an effective $587 loss before they touch the return." },

    { kind: "h2", text: "Why diesel is stuck where it is" },
    { kind: "p", text: "The shortest version: PADD III (Gulf Coast) refineries are running at 95.8 percent utilization, which is roughly the practical ceiling. PADD IV (Rockies) is at 67.6 percent, but the geography of the pipeline grid means PADD IV slack does not relieve PADD III stress. When the Gulf runs hot and there is no spare capacity to swing into, any unplanned outage moves wholesale fuel prices fast — and the retail-pump-vs-futures gap stays tight enough that fuel surcharges cannot recover the variance for carriers. Our deeper read on the refining geography is in our PADD III analysis (linked below)." },
    { kind: "p", text: "Three fuel realities right now compound the squeeze. (1) Pump-to-futures gap is roughly five cents — historically thin. Surcharges typically lag the spot market by one to two weeks; when the gap is this small, the lag eats the carrier's margin instead of the shipper's. (2) West Coast retail diesel ($5.93/gal) is ninety-two cents above the Gulf Coast ($5.01) — the entire Mountain-and-West freight network is fueling out of the most expensive regional pool in the country. (3) Reefer fuel-burn at idle (typically 0.6–1.0 gal/hr for the trailer unit alone) is not covered by per-mile surcharges; long detention at receivers turns into uncompensated diesel cost." },

    { kind: "h2", text: "What the lane map shows" },
    { kind: "p", text: "When you put fifteen of the country's most active meat lanes onto a single map and color them against breakeven, three patterns jump out." },
    { kind: "list", items: [
      "Short Midwest hops are still profitable. Omaha → Chicago averages $3.69 per mile RPM — $1.59 per mile above breakeven. Dodge City → Dallas runs $3.34 per mile. The shorter the haul, the smaller the diesel bill relative to the line-haul revenue, and the bigger the cushion above the $2.10 line.",
      "Long west-coast destinations have inverted. Sioux Falls → LA at $1.76 RPM, Lexington → LA at $2.02 RPM, Garden City → LA at $1.95 RPM. These are the same lanes that, twelve months ago at lower diesel prices, plotted comfortably in green.",
      "Backhauls have collapsed. Empty miles back to California after a westbound protein delivery used to be partly defrayed by produce backhaul; produce demand dictates that the spot market for those backhauls runs at thirty-five to fifty percent of the outbound rate. With diesel where it is, even that relief is no longer enough to make the round-trip cash-flow positive on the worst-affected lanes.",
    ] },
    { kind: "p", text: "The produce side is less inverted because produce loads tend to clear at higher per-load dollars (the floral, organic, and time-sensitive premiums apply), but it is moving the same direction. Rates that read $7,500–$8,500 per load on a Salinas → New York run look fine on a flat dollar basis until you divide by the 2,900 miles and the diesel cost; the green-vs-amber threshold has shifted west on the spectrum since January." },

    { kind: "h2", text: "What this does to shippers" },
    { kind: "p", text: "Shippers with multi-month contracts and indexed fuel-surcharge programs are largely insulated for the duration of the contract — the index moves and the surcharge moves with it. Shippers buying spot, especially on the lanes flagged red on the dashboard, are about to learn one of two things: either the carriers they have used for years will stop accepting their tenders, or those carriers will start asking for non-trivial rate adjustments mid-quarter, citing fuel. Both outcomes are rational; both are about to happen more frequently." },
    { kind: "p", text: "Three practical reads:" },
    { kind: "list", items: [
      "If your fuel-surcharge program indexes to a retail diesel average (the EIA weekly retail diesel survey is the most common reference), ask your carrier whether re-indexing to ULSD futures would close the surcharge-vs-spot gap. Surcharges that index to futures recover diesel-cost variance faster, which means your carrier is less likely to come back asking for an off-cycle rate adjustment.",
      "On reefer lanes specifically, ask whether the surcharge program covers reefer-unit idle fuel. Many programs only price the tractor's diesel burn. If your loads sit at the receiver more than four hours on average, the trailer-unit burn is meaningful — and uncompensated burn is one of the first reasons a carrier quietly stops accepting your tenders.",
      "Watch the lanes you ship most often against the $2.10 breakeven line. When a lane plots red on a sustained basis, the carriers running it are losing money on every load. The market clears that imbalance the same way it always has — capacity exits, then rates rise. The shipper who anticipates the move books capacity at the cycle's bottom; the shipper who reacts pays the spot premium when the cycle turns.",
    ] },

    { kind: "h2", text: "What we expect next" },
    { kind: "p", text: "Two scenarios. The first: PADD III utilization eventually drops back toward 90 percent — usually after the heaviest summer driving demand passes — and wholesale slack returns to the system. Retail diesel softens fifteen to thirty cents per gallon over a four-to-six-week window. Carriers re-baseline their surcharge programs. Lanes currently red on the dashboard climb back into amber, then green. This is the historical pattern; it is the most likely outcome." },
    { kind: "p", text: "The second: any unplanned event — a Gulf hurricane that takes out one of the major Texas refineries, a Colonial Pipeline incident, a sustained geopolitical move on Russia or Iran — and the squeeze deepens fast. PADD III at 95.8 percent has no slack to absorb a shock. The lanes already plotting red would deepen; lanes currently amber would invert. Carriers exit faster than they re-enter; capacity tightens through the back half of the year." },
    { kind: "p", text: "We update the lane map and the breakeven overlay weekly. The fuel news is loud, but the lane-level signal is what actually tells you whether your network has a problem." },

    { kind: "h2", text: "Sources and method" },
    { kind: "p", text: "Owner-operator breakeven figure ($2.10/mi) sourced from ATBS and OOIDA published cost-per-mile data for refrigerated owner-operators, current-year benchmark. Retail diesel pricing from EIA weekly retail diesel survey, week ending May 02, 2026. PADD utilization from EIA weekly petroleum status report. Lane-level rate-per-mile figures derived from DAT Solutions May 2026 refrigerated-segment data on the named origins and destinations; mile counts are practical truck routings, not great-circle. The lane-color overlay on the dashboard updates weekly as the underlying USDA AMS produce truck-rate report and the DAT meat-segment dataset refresh." },
    { kind: "p", text: "Companion read: our PADD III analysis explains why diesel is sticky at this price — the underlying refining geography is the part of this story that is not in any single quarterly report." },
  ],
  footerCta: {
    h3: "Watch the lanes you actually ship — against breakeven, weekly.",
    p: "The Reefer Rates dashboard plots every active produce and protein lane against the $2.10/mi owner-op breakeven line, color-coded green/amber/red. Free to view. Updated weekly when the federal data refreshes. The shipper who watches the lane-level squeeze before it shows up in tender-acceptance rates books capacity ahead of the cycle.",
    primaryCta: "Open the Reefer Rates dashboard →",
    primaryTarget: "reefer",
    secondaryCta: "Or get the daily Pulse",
    secondaryTarget: "members?for=shippers",
  },
};

const REFINING_TIGHTNESS_ARTICLE = {
  slug: "padd-iii-refining-tightness-diesel-surcharges-2026",
  tag: "Markets", category: "Analysis",
  title: "PADD III is running at 95.8% utilization. That's why your diesel pump price isn't dropping.",
  dek: "U.S. refineries can technically produce more diesel than the country burns. They aren't. Gulf Coast refineries (PADD III) are running at 95.8%; Rocky Mountain (PADD IV) at 67.6%. The geographic mismatch between where refining capacity sits and where diesel gets burned is the single most under-covered fuel-cost story in freight.",
  author: "Shipping Clarity Editorial", authorRole: "Markets Desk",
  date: "Apr 30, 2026", read: "5 min", imageColor: "oklch(0.50 0.14 145)",
  stats: [
    { v: "95.8%", l: "PADD III utilization" },
    { v: "67.6%", l: "PADD IV utilization" },
    { v: "$5.35", l: "US retail diesel" },
    { v: "$5.30", l: "Implied from futures · gap +$0.05" },
  ],
  body: [
    { kind: "lede", text: "Truckers and freight buyers wonder, every single quarter, why diesel pump prices stay elevated when crude prices drop. The honest answer is not market manipulation. It is geography. The U.S. has plenty of refining capacity in aggregate; what it doesn't have is refining capacity in the right places, running at the right rate, all of the time. Right now Gulf Coast refineries (PADD III) are running near maximum at 95.8% utilization. Rocky Mountain refineries (PADD IV) are running at 67.6%. The mismatch is the price story." },
    { kind: "h2", text: "What PADDs are, and why they matter" },
    { kind: "p", text: "The Petroleum Administration for Defense Districts — PADDs — are five regional groupings the U.S. has used since World War II to track refining capacity. PADD I is the East Coast. PADD II is the Midwest. PADD III is the Gulf Coast — Louisiana, Texas, Mississippi, Alabama. PADD IV is the Rocky Mountains. PADD V is the West Coast plus Alaska and Hawaii. They're not just bureaucratic boundaries; they reflect the actual pipeline-and-rail geography of how refined product moves around the country, because most diesel and gasoline are still pipelined more cheaply than they're trucked or railed." },
    { kind: "p", text: "PADD III is the engine. About 50% of total U.S. refining capacity is in PADD III, and almost all of the deepwater crude import-and-export infrastructure is there too. When Gulf Coast refineries run hot, the rest of the country gets fed cheaply via pipeline (Colonial, Plantation, others). When PADD III runs near max, those pipelines run full, and there's no slack to absorb a regional outage anywhere downstream." },
    { kind: "h2", text: "Why 95.8% is high" },
    { kind: "p", text: "Refineries cannot, in practice, sustain 100% utilization. Maintenance turnarounds, unit-level outages, and the occasional unplanned shutdown all push the practical maximum to roughly 93-95% for any sustained period. Pushing past 95% means that any unscheduled outage anywhere in the system causes a fast move higher in wholesale prices — there is no spare capacity to swing into. PADD III at 95.8% is the operational state where one Gulf Coast hurricane, one major refinery fire, one cyber incident on a pipeline, becomes a national diesel-price problem within 72 hours." },
    { kind: "p", text: "The regional retail-diesel-price spread reflects this. Right now: West Coast diesel ~$5.93/gal, East Coast ~$5.42, Gulf Coast ~$5.01, Midwest ~$5.13, Rocky Mountain ~$5.27. The 92-cent spread between West Coast and Gulf Coast is the cost of the pipeline geography failing to reach into California. PADD V refineries (West Coast) operate at 80.1% — not tight, but the regulatory environment + isolated geography + reduced refining capacity over the last decade make them the most expensive refining region in the country." },
    { kind: "h2", text: "Why diesel surcharges aren't dropping" },
    { kind: "p", text: "The futures-to-pump gap is the indicator most freight buyers should be watching. When ULSD diesel futures plus roughly $1.10/gallon (typical taxes + distribution + retail margin) implies a national retail price of about $5.30, and the actual pump price is $5.35, the gap is $0.05. That's tight — pump prices are tracking futures within five cents. Carriers can't recover diesel-cost variance through their fuel-surcharge programs when pump-vs-futures gap stays this tight. Surcharges typically lag the spot market by 1-2 weeks; when the gap is this small, the lag eats the carrier's margin." },
    { kind: "p", text: "When PADD III utilization eventually drops back toward 90% — usually after the heaviest summer driving demand passes — wholesale slack returns to the system, retail diesel softens 15-30 cents/gallon over a 4-6 week window, and the futures-to-pump gap widens. Carriers re-baseline their surcharge programs. That's the cycle. Right now we're at the tight end of it." },
    { kind: "h2", text: "What freight buyers should do" },
    { kind: "p", text: "Three practical reads. First: if you can negotiate fuel-surcharge programs that index to ULSD futures rather than to retail diesel averages, do — the lag eats less of the carrier's margin and the carrier passes less of it on to you. Second: regional spot capacity is partly a function of regional refining slack. Pacific Northwest and Mountain West freight is currently flowing through a tighter regional fuel network than Gulf Coast freight; the spot market reflects that. Third: watch refinery utilization weekly. The EIA publishes it every Wednesday, and we mirror it on the dashboard. When PADD III utilization drops below 92% for two consecutive weeks, the diesel-price decline is usually 4-6 weeks behind it." }
  ]
};

const UPS_HUBS_DARK_ARTICLE = {
  slug: "when-a-ups-hub-goes-dark-2026",
  tag: "Investigation", category: "Investigation",
  title: "When a UPS hub goes dark",
  dek: "Fifty-one permanent UPS facility closures announced for 2026 — twenty-four in January, twenty-seven more on April 29. An unspecified number of temporary remodels. A November 2025 plane crash that took the largest UPS air hub offline for three days. UPS does not email its shippers when a sortation facility on their network goes offline. The freight reroutes. The transit times stretch. The claim rates spike. The shipper finds out, weeks later, in a damage-claim report.",
  author: "Shipping Clarity Editorial", authorRole: "Independent Investigation",
  date: "Apr 30, 2026", read: "11 min", imageColor: "oklch(0.50 0.16 50)",
  updatedOn: "April 30, 2026",
  stats: [
    { v: "51", l: "Permanent UPS facility closures · 2026" },
    { v: "30,000", l: "Workforce reduction · 2026" },
    { v: "Nov 5 2025", l: "Worldport crash · 3-day Louisville outage" },
    { v: "$3B", l: "Structural cost reductions · UPS" },
  ],
  body: [
    { kind: "h2", text: "What the public record shows" },
    { kind: "list", items: [
      "Twenty-four UPS facility closures announced January 27, 2026; the subset of twenty-two with Teamsters bargaining-unit employees surfaced via court filings in February, not by UPS press release.",
      "Twenty-seven additional UPS closures announced April 29, 2026 by CFO Brian Dykes — most scheduled for Q2 2026. Total announced for 2026: fifty-one.",
      "30,000 workforce reduction in 2026, on top of 48,000 positions cut in 2025.",
      "$3 billion in structural cost reductions is the stated 2026 target, attributed by UPS leadership to reduced Amazon volume and a stated pivot away from scale-led profitability.",
      "On November 5, 2025, a cargo plane crashed at UPS Worldport in Louisville, Kentucky, closing the largest UPS air hub in the United States for approximately three days; next-day-air service slipped across the U.S. network during the recovery.",
    ]},
    { kind: "lede", text: "On the morning of January 27, 2026, the chief executive of United Parcel Service, Inc. (NYSE: UPS) opened the company's quarterly earnings call with a pivot. Carol Tomé, who has run UPS since 2020, said the company would close twenty-four facilities across its U.S. ground network and reduce its workforce by thirty thousand positions. The reduction came on top of forty-eight thousand jobs cut in 2025. The number that drew the most analyst attention on the call was the cost-savings target. Three billion dollars of structural cost. Achieved by the end of 2026." },
    { kind: "p", text: "What did not draw analyst attention, and what UPS did not voluntarily release on the call, was the list of facilities. The company declined, that day, to identify which of the twenty-four buildings would close. Three weeks later, in February, the partial list surfaced — through a court filing in a Teamsters labor case, not through a UPS press release. Twenty-two of the twenty-four were facilities with bargaining-unit employees. Cities began to learn, one local-news cycle at a time, which UPS hub was about to go dark." },
    { kind: "p", text: "What did not yet appear on any list, and would not until April 29, was that there were twenty-seven more closures coming." },
    { kind: "h2", text: "Twenty-four, then twenty-seven more" },
    { kind: "p", text: "On the April 29, 2026 first-quarter earnings call, UPS Chief Financial Officer Brian Dykes told investors the company had identified twenty-seven additional package facilities for closure in 2026. Most, he said, would close in the second quarter. The total announced for 2026 stands at fifty-one — and the company has explicitly reserved the right to identify more." },
    { kind: "p", text: "From UPS's most recent annual report: \"We continue to review expected changes in volume in our integrated air and ground network to identify additional buildings for closure.\"" },
    { kind: "p", text: "By UPS's own description, the 2026 program is the largest network rationalization in the company's recent history. Carol Tomé, on the same April 29 call: \"The market has changed and we're adapting to it. We're overturning the old industry assumption that scale alone drives profitability.\" The proximate cause, in the company's own filings, is reduced volume from Amazon. Amazon began bringing more of its delivery in-house starting in 2024; the volume UPS used to handle for Amazon is no longer there. The buildings that handled that volume are no longer needed." },
    { kind: "h2", text: "Atlanta and West Columbia" },
    { kind: "p", text: "Two of the named 2026 closures stand out for their scale. The first is a regional hub at 270 Marvin Miller Drive in Atlanta, Georgia — a facility larger than two hundred thousand square feet. The second is a similarly-sized regional hub in West Columbia, South Carolina. Both are package sortation centers that, in the network's previous configuration, served as cross-dock and rail-handoff points for ground freight moving across the Southeast." },
    { kind: "p", text: "The remaining twenty in the January list distribute across eighteen states. Eight are in the South, five each in the West and Midwest, four in the East. Three are in Massachusetts — the most in any single state on the list. The smaller facilities range from package operation centers to truck terminals to last-mile delivery stations. Named closures so far include Joliet, Illinois; Stanton, Kentucky; North Apollo, Pennsylvania; Las Vegas; Baltimore; Dallas; and Miami. The April twenty-seven, Brian Dykes did not name." },
    { kind: "pull", text: "The Teamsters subset (22 of the 24 January closures) surfaced through a court filing, not a UPS press release. The 27-facility April list, the company has not yet named." },
    { kind: "h2", text: "Portland, March 2025" },
    { kind: "p", text: "Hub closures are not always permanent. UPS also takes hubs down for what the company calls modernization or what local press calls remodel or redo. These are temporary closures, sometimes lasting months, during which the hub's volume diverts to other facilities. Workers either relocate, are reassigned, or are placed on layoff for the duration." },
    { kind: "p", text: "In March 2025, UPS temporarily closed its North Portland, Oregon shipping hub for upgrades. More than two hundred workers were laid off pending reopening. Oregon Public Broadcasting reported the closure as a pause for upgrades rather than a shutdown. The facility's ground volume diverted to UPS hubs in Seattle, Tacoma, and the Eastern Oregon network. The expected reopening date was not publicly disclosed." },
    { kind: "p", text: "UPS does not publicly inventory which facilities are currently in remodel. The temporary closures surface, as the Portland one did, through local news coverage when laid-off workers receive WARN Act notices. WARN — the federal Worker Adjustment and Retraining Notification Act — requires sixty days' notice before any layoff of fifty or more workers at a single facility. Those notices are public, filed with state labor departments. They are also the most reliable single source for tracking UPS facility-status changes in real time, because UPS files them and the SEC does not require facility-level disclosure for non-material closures." },
    { kind: "h2", text: "Worldport, November 5" },
    { kind: "p", text: "At 5:14 AM Eastern on November 5, 2025, a cargo plane crashed at the UPS Worldport hub in Louisville, Kentucky — the largest UPS air hub in the United States and the operational center of the company's next-day-air network. Worldport closed for emergency response. The closure lasted approximately three days. During those three days, the entire UPS next-day-air system operated without its central sortation hub. Volume rerouted through smaller air hubs in Rockford, Ontario, Columbia, and Anchorage. Next-day-air commitments slipped across the U.S. network. Reuters and Kentucky local press tracked the gradual recovery." },
    { kind: "p", text: "Worldport reopened. The next-day-air network recovered. The crash itself was a discrete event with a definite end. But the operational read for any shipper using UPS next-day-air during that window was the same as during a hub closure or a remodel: their freight was suddenly being handled by a different facility, with different equipment, different drivers, and different reliability than the hub their service-level expectations had been built on. They found out, in most cases, when a delivery missed its committed time." },
    { kind: "h2", text: "The network effect" },
    { kind: "p", text: "What happens to a freight network when a hub goes offline — permanently, temporarily, or by accident — is mechanical. The volume the closed hub used to process is now processed somewhere else. The somewhere-else is one or more adjacent hubs in the network's regional design. Those adjacent hubs were sized for their previous volume, not their previous volume plus the diverted load. They run hotter." },
    { kind: "p", text: "The operational tells, in order of how quickly they show up: dock-time stretches at adjacent hubs first. Then transit times slip on lanes that route through the diverted volume. Then claim rates rise — more handling per package, more cross-docks, more chances for a damage event. Then on-time-delivery percentages decline. Then customer service queues get longer." },
    { kind: "p", text: "At a normal scale, this is invisible. UPS's network is enormous; the loss of one mid-sized package operation center is absorbed by surrounding facilities and the shipper sees nothing. At the scale of fifty-one permanent closures plus an unspecified number of temporary remodels, plus a discrete event like the Worldport crash, the absorption mathematics start to fail. The system runs hotter. The tells start showing up in shippers' service metrics." },
    { kind: "pull", text: "The lag from a hub going offline to the shipper's procurement team noticing it in their service metrics is typically two to six weeks. By the time it shows up in a quarterly business review, the rerouted freight has already been moving through the new path for one to two months." },
    { kind: "h2", text: "What UPS tells shippers" },
    { kind: "p", text: "Almost nothing, proactively, at the facility level." },
    { kind: "p", text: "UPS communicates network changes through the channels public companies use: SEC filings, earnings calls, press releases, and the annual report. SEC filings disclose to investors. Earnings calls disclose to analysts. The annual report, in dense aggregated language, describes the broad shape of the company's network footprint. None of those documents are designed to tell a procurement team in Atlanta that the UPS hub their warehouse routes through is closing in ninety days." },
    { kind: "p", text: "WARN notices — filed with state labor departments under federal law — are the single most reliable source for shipper-relevant facility status. They name the facility, the date, the headcount affected, and the reason for the layoff. They are filed at least sixty days in advance. They are public. Most procurement teams do not subscribe to them." },
    { kind: "p", text: "Local news in the affected city is the second-most-reliable source. When UPS closes a hub in Joliet, Illinois, the Joliet news covers it. The procurement team in Atlanta, whose freight may be affected by the Joliet closure, is not reading Joliet news." },
    { kind: "h2", text: "What shippers can do" },
    { kind: "p", text: "Three practical reads." },
    { kind: "p", text: "First: subscribe to WARN notices for the states where you ship through. Most state labor departments offer email alerts when WARN filings are received. The lag from filing to alert is typically one to three days. The lag from alert to actual closure is sixty days, which is enough time to renegotiate, route around, or adjust expectations." },
    { kind: "p", text: "Second: track Item 2.05 disclosures (exit or disposal activities) on the SEC EDGAR full-text search for any carrier in your network. Material facility closures generate 8-K filings under Item 2.05. These are the closures large enough to require investor disclosure — exactly the closures most likely to disrupt shipper service." },
    { kind: "p", text: "Third: watch the local press for the cities where your major carriers operate hub facilities. UPS hub closures get local-press coverage; FedEx Ground hub closures get local-press coverage; LTL terminal closures get local-press coverage. The signal is there. The aggregation across geographies and carriers is what's missing." },
    { kind: "p", text: "Or, more pragmatically: make the aggregation someone else's job. Every shipping intelligence service that pretends to be one is judged on whether it surfaces these facility-status events before the procurement team's service-quality metrics flag them. Most do not." },
    { kind: "h2", text: "What this means at the dock" },
    { kind: "p", text: "The network the shipper can see, and the network actually moving their freight, are not the same network anymore." },
    { kind: "p", text: "Fifty-one permanent UPS closures announced for 2026, on top of fifty-plus closures already executed in 2025, on top of an unspecified number of temporary remodels at any given moment, on top of discrete operational events like the Worldport crash — these are not abstractions. They are buildings that used to handle a shipper's freight and no longer do, in geographies the shipper booked through. The freight still moves. It just moves on different equipment, through different facilities, with different reliability." },
    { kind: "p", text: "The shipper who finds out about it in a damaged-claim report has already absorbed two months of degraded service. The shipper who finds out about it in a WARN notice has sixty days to plan. The shipper who finds out about it in a public-records aggregator that tracks all of it daily has the longest runway of all." },
    { kind: "p", text: "UPS does not call its shippers when a hub goes dark. It is not what UPS does. It is also not what shippers should expect. The job of knowing belongs, by default, to whoever is willing to do it." },
    { kind: "h2", text: "Sources" },
    { kind: "p", text: "All facility-closure counts, workforce-reduction figures, and CEO/CFO quotes verified against UPS's January 27, 2026 and April 29, 2026 quarterly earnings press releases and call transcripts (publicly available via SEC EDGAR, filer CIK 1090727); against secondary reporting in FreightWaves, Supply Chain Dive, Yahoo Finance, Bisnow, the Courier-Journal, and Trucking Dive; and against WARN Act filings tracked through the relevant state labor departments. The Worldport plane-crash recovery timeline is sourced from Reuters and PBS reporting (November 5, 2025). The North Portland hub closure is sourced from Oregon Public Broadcasting (March 31, 2025). The Atlanta and West Columbia regional hub identifications are from Bisnow's February 2026 reporting." },
    { kind: "p", text: "UPS's media-relations team was contacted for comment prior to publication." },
    { kind: "p", text: "Last updated: April 30, 2026. We will revise this piece when UPS publishes the named list of the April twenty-seven additional closures, when any of the announced facilities reopens, or when the trajectory closes the other way." },
  ],
  footerCta: {
    h3: "Want this kind of read on a carrier you actually book?",
    p: "Per-carrier deep-dive reports — Z-Score history, full SEC filing scan, WARN-notice trail in your shipping geography, FMCSA inspection record, court-record creditor pattern, all in a 10-page PDF inside 24 hours. $500 per carrier. The on-demand alternative to the subscription-only ratings reports the freight industry has run on for thirty years.",
    primaryCta: "Request a deep-dive · $500 →",
    primaryTarget: "mailto:hello@shippingclarity.com?subject=Deep-dive report request&body=Carrier name:%0D%0A%0D%0AYour name:%0D%0A%0D%0ABest email:%0D%0A%0D%0ACarrier USDOT or MC (if known):%0D%0A%0D%0A",
    secondaryCta: "Or get the daily Pulse",
    secondaryTarget: "members?for=shippers",
  },
  socialPosts: {
    xThread: [
      "On April 29 UPS announced it would close 27 ADDITIONAL package facilities in 2026 — on top of the 24 announced in January.\n\nThat's 51 permanent closures this year. Plus 48,000 jobs cut in 2025 and 30,000 more in 2026.\n\nUPS does not email its shippers when a hub goes dark. 🧵",
      "When a hub closes, freight reroutes to adjacent hubs in the network design. Those adjacent hubs were sized for their PREVIOUS volume, not their previous + the diverted load.\n\nThe tells: dock-time stretches → transit times slip → claim rates rise → on-time decline.\n\nLag to a shipper noticing: 2 to 6 weeks.",
      "Two named 2026 closures stand out:\n\n• Atlanta regional hub at 270 Marvin Miller Drive (200K+ SF)\n• West Columbia, SC regional hub (200K+ SF)\n\nThe Teamsters subset (22 of the 24 January closures) surfaced via a court filing, not a UPS press release. The 27-facility April list hasn't been named yet.",
      "Then November 5, 2025: a cargo plane crashed at UPS Worldport (Louisville) — the largest UPS air hub in the country.\n\nWorldport closed for ~3 days. The entire next-day-air network operated without its central sortation hub. Service slipped across the US.\n\nMost shippers found out via missed deliveries.",
      "WARN Act notices are the most reliable source for shipper-relevant UPS facility status. State labor departments file them. They name the facility, date, headcount, reason. 60 days advance notice required by law.\n\nMost procurement teams don't subscribe.\n\nFull investigation:\nshippingclarity.com/i/when-a-ups-hub-goes-dark-2026",
    ],
    linkedin:
"When a UPS hub goes dark, the shipper finds out in a damage-claim report.\n\nFifty-one permanent UPS facility closures announced for 2026: 24 in January, another 27 on April 29. Plus 48,000 jobs cut in 2025 and 30,000 more in 2026. Plus an unspecified number of temporary remodels. Plus a November 2025 cargo plane crash at Worldport (Louisville) that took the largest UPS air hub offline for three days.\n\nFrom UPS CEO Carol Tomé on April 29: \"The market has changed and we're adapting to it. We're overturning the old industry assumption that scale alone drives profitability.\" The proximate cause is reduced Amazon volume; the strategic target is $3 billion in structural cost reductions.\n\nNamed 2026 closures so far include the Atlanta regional hub at 270 Marvin Miller Drive (200K+ SF); West Columbia, SC (200K+ SF); Joliet, IL; Stanton, KY; North Apollo, PA; Las Vegas; Baltimore; Dallas; Miami; and three facilities in Massachusetts.\n\nWhen a hub goes offline — permanently, temporarily, or by accident — volume reroutes to adjacent hubs sized for the load they previously handled. The tells are mechanical: dock times stretch at adjacent hubs first, then transit times slip on diverted lanes, then claim rates rise, then on-time delivery percentages decline. The lag between a hub going offline and a shipper's procurement team noticing the impact in service metrics is typically two to six weeks.\n\nUPS communicates these changes through the channels public companies use: SEC filings, earnings calls, the annual report. None of these are designed to tell a procurement team that the UPS hub their warehouse routes through is closing in ninety days.\n\nThe most reliable shipper-relevant source is WARN Act filings — federally required public notices of facility layoffs, filed with state labor departments. They name the facility, the date, and the headcount affected. They are filed sixty days in advance. They are public.\n\nMost procurement teams do not subscribe to them.\n\nFull investigation, with the Worldport timeline, the Portland 2025 remodel, the network-effect math, and what shippers can actually do about it:\nhttps://shippingclarity.com/i/when-a-ups-hub-goes-dark-2026\n\n#freight #logistics #supplychain #UPS #procurement",
  },
};

const FFE_DISCIPLINE_ARTICLE = {
  slug: "ffe-discipline-in-refrigerated-2026",
  tag: "Profile", category: "Analysis",
  title: "Refrigerated trucking is in distress. FFE is not.",
  dek: "The reefer market spent 2024 and 2025 breaking. Kal Freight, once one of the larger refrigerated carriers in the U.S., filed Chapter 11 in December 2024 with fraud allegations and ended up liquidating. Capacity contracted. Rates moved. In the same period, FFE Transportation Services — the largest refrigerated less-than-truckload carrier in the country — kept its trucks moving. The federal data explains how.",
  author: "Shipping Clarity Editorial", authorRole: "Independent Analysis",
  date: "Apr 30, 2026", read: "9 min", imageColor: "oklch(0.55 0.16 165)",
  updatedOn: "April 30, 2026",
  stats: [
    { v: "0", l: "Fatal crashes · 24 mo · 829-truck fleet" },
    { v: "0.71%", l: "Driver OOS rate · vs 6.67% national" },
    { v: "14.35%", l: "Vehicle OOS rate · vs 22.26% national" },
    { v: "Largest", l: "Refrigerated LTL carrier in the U.S." },
  ],
  body: [
    { kind: "h2", text: "What the public record shows" },
    { kind: "list", items: [
      "FFE Transportation Services Inc., USDOT 109745, MC-108207 — 829 power units, 708 drivers, headquartered in Lancaster, Texas. Cargo: fresh produce, meat, refrigerated food, beverages.",
      "Federal Safety Rating: Satisfactory (FMCSA's highest tier), last assessed February 13, 2025.",
      "Vehicle out-of-service rate: 14.35% — roughly 35% below the 22.26% national average.",
      "Driver out-of-service rate: 0.71% — roughly 90% below the 6.67% national average.",
      "Zero fatal crashes across the trailing 24 months on a fleet of 829 power units.",
      "Owned since July 2013 by Duff Brothers Capital Corporation (Mississippi-based, family-owned), which also indirectly controls KLLM Transport Services. FFE is private; no SEC filings.",
      "Operating in the same refrigerated freight market that took Kal Freight Inc. into Chapter 11 in December 2024 (with fraud allegations following two weeks later, per FreightWaves) and into Chapter 7 liquidation in July 2025.",
    ]},
    { kind: "lede", text: "In December 2024, Kal Freight Inc. filed for Chapter 11 protection in the U.S. Bankruptcy Court for the Southern District of Texas. Kal had been one of the larger refrigerated and intermodal trucking carriers in the United States. Within two weeks of the bankruptcy filing, public reporting in FreightWaves connected Kal to allegations of accounting fraud. By July 2025, the case had converted to a Chapter 7 liquidation. The trucks were sold." },
    { kind: "p", text: "Kal's collapse was not the only signal. Through 2024 and into 2025, refrigerated capacity in the United States contracted, rates moved, and multiple smaller carriers either consolidated or exited the segment. The Journal of Commerce reported in October 2025 that shrinking capacity had begun pushing reefer truck rates higher. FreightWaves wrote in January 2025 that \"the reefer market isn't cooling down.\"" },
    { kind: "p", text: "In the same period, on the same lanes, in the same regulatory environment, FFE Transportation Services — a Lancaster, Texas–based refrigerated less-than-truckload carrier and, by its parent's description, the largest of its kind in the country — reported, by the operational measures the federal government tracks, no equivalent distress." },
    { kind: "h2", text: "The market that took down Kal Freight" },
    { kind: "p", text: "Refrigerated trucking is the cold-chain segment of the freight industry: the trucks that haul fresh produce out of California valleys to grocery distribution centers, the trucks that haul meat from Midwestern packing plants to the Southeast, the trucks that move pharmaceuticals and beverages and frozen prepared foods to retailers nationwide. The trailers cost more — refrigeration units add fifty to seventy thousand dollars to a trailer's price. The fuel costs more — the reefer engine burns its own diesel. The drivers are scarcer — refrigerated freight requires more skill and more licensing. The compliance is heavier — the Food Safety Modernization Act requires temperature-controlled documentation. The customer expectations are tighter — a four-hour temperature breach can void a load." },
    { kind: "p", text: "Through 2023 and into 2024, the segment ran soft. Rates were under pressure. Carriers that had over-expanded during the post-COVID boom were under-utilized. Margins compressed. Some carriers exited. Some consolidated. Kal Freight, in December 2024, filed for bankruptcy." },
    { kind: "p", text: "By the second half of 2025, the picture began to flip. The carriers that had exited or contracted had taken their capacity with them. The carriers still operating could raise rates against the tighter supply. Reefer truck rates, per the Journal of Commerce, rose through Q3 and Q4 2025. The shippers who had pressed carriers on rate during the soft period now found themselves negotiating with a smaller pool of operators." },
    { kind: "h2", text: "What the FMCSA data shows for FFE" },
    { kind: "p", text: "Federal motor-carrier records, public via the FMCSA Mobile API, do not show what a carrier is paying or charging. They show what's happening on the road and at the dock. Inspections. Crashes. Out-of-service orders. Compliance reviews." },
    { kind: "p", text: "FFE's federal safety rating is Satisfactory, last assessed February 13, 2025. The Satisfactory rating is FMCSA's highest tier. The recent review date is itself notable: a Satisfactory rating from a 2025 compliance review cannot be papered over with an old number. The review window is the same window during which Kal Freight was in Chapter 11." },
    { kind: "p", text: "FFE's roadside inspection data over the trailing 24 months shows 453 vehicle inspections with 65 placed out-of-service — a rate of 14.35 percent. The national vehicle out-of-service average, per FMCSA's published baseline, is 22.26 percent. FFE's vehicles are placed out-of-service at a rate roughly 35 percent below the industry baseline." },
    { kind: "p", text: "FFE's driver inspection data shows 841 inspections with 6 drivers placed out-of-service — a rate of 0.71 percent. The national driver out-of-service average is 6.67 percent. FFE's drivers are placed out-of-service at a rate roughly 90 percent below the industry baseline. That figure is striking. It is the kind of metric that follows from extensive driver retention, training discipline, and pre-trip inspection culture, none of which are visible to a shipper without driving along on a route." },
    { kind: "p", text: "And on a fleet of 829 power units, across 24 months, FFE's reportable crashes total 47. None fatal." },
    { kind: "pull", text: "Zero fatal crashes on 829 power units across 24 months. In a fleet of that size, in that segment, in that period, the result is statistically distinctive." },
    { kind: "h2", text: "The owner" },
    { kind: "p", text: "FFE Transportation Services has been owned, since July 2013, by Duff Brothers Capital Corporation, a Mississippi-based holding company controlled by Thomas Duff and James Duff. The Duff brothers also indirectly control KLLM Transport Services, a major Mississippi-based truckload refrigerated carrier." },
    { kind: "p", text: "The 2013 acquisition took FFE private. It had previously been a publicly-traded company (Frozen Food Express Industries) listed on the NASDAQ. Going private removed the quarterly-earnings discipline that had governed FFE under public ownership and, in industry practice, traded that pressure for a different kind: long-term family-stewardship discipline. The Duff family does not file public quarterly reports. The Duff family also does not have to make decisions on a quarterly cycle." },
    { kind: "p", text: "FFE's positioning, per Duff Capital Investors' company page: \"the largest less-than-truckload temperature-controlled carrier in the U.S.\"" },
    { kind: "h2", text: "What discipline looks like in this segment" },
    { kind: "p", text: "The FMCSA data does not directly answer the operational question — what FFE does day-to-day to outperform the industry baseline by the margins it does. The data captures the result. But the result, in a segment where the work is hard, usually traces to a few unglamorous things." },
    { kind: "p", text: "Reefer trailers either work or they don't. A reefer that fails on a route hauling fresh meat does not just disappoint a customer; it ruins a load and the load's value flows backward through claims to the carrier. Carriers with low vehicle out-of-service rates, sustained over time, tend to be carriers with strong pre-trip inspection culture, in-house mechanical capability, and disciplined replacement schedules. None of that is cheap. None of that is fast to build." },
    { kind: "p", text: "Driver out-of-service rates this far below the industry baseline tend to follow from driver retention. A carrier that keeps its drivers — through pay, dispatching practice, route quality, and culture — has drivers who know the equipment, know the customers, and have time to develop the muscle memory that prevents the violations that drive OOS rates. Driver retention in trucking is one of the hardest problems in the industry; the carriers that crack it tend to outperform the operational metrics by exactly the kind of margins FFE shows." },
    { kind: "p", text: "Cargo mix is also part of it. FFE hauls produce, meat, refrigerated food, and beverages — diversified across cold-chain segments rather than concentrated in any one. When the produce harvest is heavy, the meat plants are running at normal volume; when meat exports slow, beverages move; when frozen demand softens, fresh produce holds steady. Diversification across cold-chain customer types means that no single customer's disruption can topple the network." },
    { kind: "h2", text: "The capacity squeeze" },
    { kind: "p", text: "The state of the refrigerated freight market in late 2025 and into 2026 is one of tightening capacity and recovering rates. The shippers who depend on cold-chain trucking are now operating in a market with fewer carriers, less spot capacity, and rates that have moved against the historical floor." },
    { kind: "p", text: "For shippers, this is a market where the carriers still operating well have leverage they did not have eighteen months ago. FFE is one of those carriers. The shippers who maintained their FFE relationships through the soft period — paying through the bottom rather than chasing every spot-market dip — are now negotiating renewals from a position of partnership rather than from the rate pressure currently affecting reefer-only contracts." },
    { kind: "h2", text: "What this means for shippers" },
    { kind: "p", text: "Two practical reads." },
    { kind: "p", text: "First: the carriers operating well in refrigerated trucking right now are not the cheap ones. They are the ones whose vehicle OOS rates are below industry, whose driver OOS rates are far below industry, whose safety ratings are current, whose ownership is stable, and whose customer mix is diversified. FFE checks all five of those boxes on the public record. Some other refrigerated carriers do too. The shippers who can identify them — by the public-record data rather than by sales-call rapport — are the shippers who maintain reliable cold-chain service through the next eighteen months." },
    { kind: "p", text: "Second: carriers that look the same on a brokerage portal sometimes look very different in the FMCSA data. The premium reefer rate a shipper pays today, in a market with fewer good carriers, can be earned back many times over by reliability — fewer claims, fewer rejected loads, fewer hours-of-service stoppages, fewer safety incidents that pull a carrier off your tender. The metrics for that kind of reliability are public. The aggregation across the carriers in your network is the gap." },
    { kind: "h2", text: "What this means at the dock" },
    { kind: "p", text: "Refrigerated trucking is breaking. FFE is operating." },
    { kind: "p", text: "Behind a result like FFE's there is no marketing line and no slogan. There is the kind of work that does not make news: a yard mechanic running a pre-trip inspection on a reefer unit at 4:30 in the morning; a dispatcher routing a driver to keep their hours legal and their home time honored; a fleet operations manager replacing a trailer's reefer unit before it fails on a load. None of that shows up in a FreightWaves headline. All of it shows up in the inspection record. The FMCSA data is the closest thing the freight industry has to an honest scoreboard for this kind of work." },
    { kind: "p", text: "In a segment where Kal Freight liquidated and reefer capacity contracted, the carriers that show up cleanly on the scoreboard are the carriers shippers should be staying in business with. The shippers who can read the scoreboard have an advantage. The shippers who cannot have a problem they don't know they have." },
    { kind: "p", text: "FFE's data is on the scoreboard. So is every other refrigerated carrier's. The reading of it is what's missing." },
    { kind: "h2", text: "Sources" },
    { kind: "p", text: "FFE operating data sourced directly from the FMCSA Mobile QC API for USDOT 109745 (FFE Transportation Services Inc.) on April 30, 2026. National out-of-service-rate baselines are FMCSA's published averages as of March 27, 2026. Kal Freight bankruptcy filing and fraud allegations from FreightWaves and The Wall Street Journal reporting (December 2024); liquidation conversion from Trucking Dive (July 2025). Reefer capacity and rate trajectory from Journal of Commerce (October 2025) and FreightWaves (January 2025). FFE's market positioning and current ownership from Duff Capital Investors' company page; 2013 acquisition history from Journal of Commerce, FleetOwner, and Refrigerated & Frozen Foods reporting." },
    { kind: "p", text: "FFE Transportation Services and Duff Brothers Capital Corporation were contacted for comment prior to publication." },
    { kind: "p", text: "Last updated: April 30, 2026. We will revise this piece if FFE's federal safety rating changes, if its operational metrics deteriorate materially, or if industry context shifts." },
  ],
  footerCta: {
    h3: "Want this kind of read on a carrier you actually book?",
    p: "Per-carrier deep-dive reports — full FMCSA inspection trail, vs-industry benchmarks, ownership history, court-record exposure, financial-distress signature for public carriers, all in a 10-page PDF inside 24 hours. $500 per carrier. The on-demand alternative to the subscription-only ratings reports the freight industry has run on for thirty years.",
    primaryCta: "Request a deep-dive · $500 →",
    primaryTarget: "mailto:hello@shippingclarity.com?subject=Deep-dive report request&body=Carrier name:%0D%0A%0D%0AYour name:%0D%0A%0D%0ABest email:%0D%0A%0D%0ACarrier USDOT or MC (if known):%0D%0A%0D%0A",
    secondaryCta: "Or get the daily Pulse",
    secondaryTarget: "members?for=shippers",
  },
  socialPosts: {
    xThread: [
      "In December 2024, Kal Freight — one of the larger refrigerated trucking carriers in the U.S. — filed for Chapter 11 with fraud allegations following two weeks later (FreightWaves).\n\nBy July 2025 the case had converted to liquidation. The trucks were sold.\n\nIt was not the only signal in refrigerated trucking. 🧵",
      "Through 2024–2025, U.S. reefer capacity contracted. Carriers consolidated or exited. Rates began rising on tighter supply (Journal of Commerce, October 2025).\n\nIn the same window, on the same lanes, in the same regulatory environment, FFE Transportation Services has been quietly operating.",
      "Numbers from the FMCSA Mobile API, pulled April 30 2026:\n\n• Vehicle OOS: 14.35% vs 22.26% national — ~35% better\n• Driver OOS: 0.71% vs 6.67% national — ~90% better\n• Zero fatal crashes on 829 power units in 24 months\n• Federal Safety Rating: Satisfactory (last reviewed Feb 13 2025)",
      "Owner: Duff Brothers Capital, the Mississippi family-owned holding company that took FFE private from NASDAQ in 2013 (and indirectly owns KLLM Transport).\n\nGoing private traded quarterly-earnings pressure for long-term stewardship.\n\nFFE's parent describes them as 'the largest LTL temperature-controlled carrier in the U.S.'",
      "Refrigerated trucking is in distress. FFE is operating.\n\nThe data behind the contrast — what FFE is doing right while the segment around it breaks:\nshippingclarity.com/i/ffe-discipline-in-refrigerated-2026",
    ],
    linkedin:
"In December 2024, Kal Freight — one of the larger refrigerated trucking carriers in the U.S. — filed for Chapter 11 protection in the Southern District of Texas, with fraud allegations following two weeks later in FreightWaves. By July 2025, the case had converted to Chapter 7 liquidation. The trucks were sold.\n\nKal's collapse was not the only signal. Through 2024–2025, U.S. refrigerated trucking capacity contracted. Multiple smaller carriers consolidated or exited. The Journal of Commerce reported in October 2025 that the shrinking pool was beginning to push reefer rates higher. FreightWaves wrote in January 2025 that \"the reefer market isn't cooling down.\"\n\nIn the same period, on the same lanes, in the same regulatory environment, FFE Transportation Services — the largest refrigerated less-than-truckload carrier in the United States, by its parent's description — reported, by the operational measures the federal government tracks, no equivalent distress.\n\nFrom the FMCSA Mobile QC API for USDOT 109745, pulled April 30, 2026:\n\n• Federal Safety Rating: Satisfactory (last reviewed Feb 13, 2025 — within the same window Kal Freight was in Chapter 11)\n• 453 vehicle inspections, 65 out-of-service: 14.35% rate vs 22.26% national average\n• 841 driver inspections, 6 out-of-service: 0.71% rate vs 6.67% national average\n• 829 power units, 47 reportable crashes in 24 months, zero fatal\n\nOwner: Duff Brothers Capital, the Mississippi family-owned holding company that has owned FFE since taking it private from NASDAQ in July 2013. The Duff brothers (Thomas and James) also indirectly own KLLM Transport Services. Going private removed the quarterly-earnings cycle that had governed FFE under public ownership and replaced it with long-term family stewardship.\n\nThe operational result, by the public record, is a carrier whose vehicles are placed out-of-service at a rate roughly 35 percent below industry; whose drivers are placed out-of-service at a rate roughly 90 percent below industry; and whose fatal-crash count over a 24-month window is zero. In a segment where Kal Freight liquidated and capacity contracted, the pattern is distinctive.\n\nFull analysis, with the cold-chain market context, the FMCSA data deep-dive, and what discipline looks like in refrigerated LTL:\nhttps://shippingclarity.com/i/ffe-discipline-in-refrigerated-2026\n\n#freight #logistics #supplychain #refrigerated #coldchain",
  },
};

// =============================================================
// Double-brokering explainer — doubles as the /#/find-carrier
// sales asset. Tight, sober, real numbers from our 150-carrier
// FMCSA-enriched DAT sample.
// =============================================================
const DOUBLE_BROKERING_ARTICLE = {
  slug: "double-brokering-fingerprint-on-dat-may-2026",
  tag: "Investigation", category: "Investigation",
  title: "How do you know the carrier you booked is actually legal?",
  dek: "We sampled 150 carriers posting trucks on the open load board and ran each one through the federal carrier registry, looking for lapsed MC authority, no MC at all, or zero registered trucks. The share that fit the double-brokering fingerprint was higher than the industry talks about in public.",
  author: "Shipping Clarity Editorial", authorRole: "Investigation",
  date: "May 1, 2026", read: "5 min", imageColor: "oklch(0.50 0.20 25)",
  stats: [
    { v: "150",  l: "Carriers sampled · DAT One Freight · May 1, 2026" },
    { v: "20%",  l: "Lapsed MC, no MC, or zero registered trucks" },
    { v: "13",   l: "DOT-only carriers posting interstate freight illegally" },
    { v: "16",   l: "Carriers with lapsed MC authority" },
  ],
  body: [
    { kind: "h2", text: "The pattern — what double brokering looks like" },
    { kind: "p", text: "A legitimate freight broker tenders a load on DAT. \"Carrier A\" books it. Carrier A doesn't have a truck for that load — sometimes Carrier A doesn't have a truck at all. They re-tender to a real carrier, \"Carrier B,\" who actually hauls the freight. Carrier A pockets the spread between what they were paid and what they paid Carrier B. The broker thinks Carrier A moved the load. Carrier B may not get paid, because Carrier A took the broker's money and disappeared. If something goes sideways — cargo theft, damage, late delivery — the insurance and chain-of-custody paperwork is broken because the load went through an unauthorized channel." },
    { kind: "p", text: "The industry term for this is double brokering. It is illegal in most cases, frequently associated with cargo theft, and the load boards know it's a problem." },
    { kind: "h2", text: "How to spot it from the public record" },
    { kind: "p", text: "Three signals show up in FMCSA's federal carrier database when a carrier is operating on the load board without legal authority to haul interstate freight for hire:" },
    { kind: "list", items: [
      "Has an MC docket number, but the operating authority is inactive — the regulator has revoked, suspended, or accepted voluntary cancellation. The MC is on the books but is not currently valid.",
      "Has no MC docket number at all — the carrier is registered with FMCSA under a USDOT number but never obtained interstate for-hire (Common or Contract) authority. They can lawfully operate intrastate or as a private carrier; they cannot lawfully take a for-hire interstate load.",
      "Has authority and a USDOT number, but reports zero power units in the most recent fleet update — they have no trucks. Whatever they 'haul' is being hauled by someone else's equipment.",
    ]},
    { kind: "p", text: "Any one of these three is a credible double-brokering signal. We took a 150-carrier sample of DAT-listed companies and ran each one through FMCSA's QCMobile API on May 1, 2026. The total is 29 unique carriers — 20% of the sample — that fit one of the three patterns." },
    { kind: "h2", text: "The breakdown" },
    { kind: "list", items: [
      "Has MC, authority active, has trucks: 113 carriers (75%). Legitimate.",
      "Has MC, authority lapsed: 16 carriers (11%). Had legal interstate authority at some point — lost it. Continuing to post trucks is consistent with the pattern.",
      "Has USDOT but no MC: 13 carriers (9%). No legal pathway to take an interstate for-hire load. Among these: a 5-truck operation in the Midwest, several owner-op listings, three with single trucks.",
      "Could not be matched to FMCSA: 8 carriers (5%). Name normalization failed; possible alias or recently-registered. Inconclusive.",
    ]},
    { kind: "h2", text: "Names worth knowing" },
    { kind: "p", text: "Among the 13 USDOT-only carriers — the ones with no legal interstate for-hire authority at all — three stood out by visibility on multiple lanes: First Class Carriers Inc (5 trucks reported, USDOT 2595629), ABC Trucking Inc (3 trucks, USDOT 1792653), and Advance Transport Inc (3 trucks, USDOT 1586863). Among the 16 lapsed-MC carriers, several have meaningful fleet size on paper — DDM Logistics Inc (USDOT 2800385) reports 15 trucks but inactive authority, and was observed posting on the Salinas-Chicago dry-van lane and the LA-Chicago lane. AAA Logistics Group Inc (USDOT 2015673) carries the additional flag of a Conditional federal safety rating in addition to lapsed authority — a rare double-stack of red flags." },
    { kind: "p", text: "Each of these is a working name on a public load board. We are not alleging fraud against any specific company; we are reporting that their public FMCSA record does not match the federal requirements for interstate for-hire freight." },
    { kind: "h2", text: "Why this is getting worse" },
    { kind: "p", text: "Federal enforcement of motor-carrier authority and brokerage regulation has been thinning for years. New-entrant safety reviews stretched out longer in 2024 and 2025 than in any year since the program began. FMCSA staffing levels have not kept pace with the entity-creation rate. The result is a regulatory environment in which standing up a brokerage shell is easier than it has been in two decades, and policing one is correspondingly harder." },
    { kind: "p", text: "The freight market is going back to the wild west. Honest carriers know it. Brokers feel it on every load that doesn't deliver on time. Shippers find out when an insurance claim won't pay because the freight went through a chain of custody nobody documented." },
    { kind: "h2", text: "The check that fills the gap" },
    { kind: "p", text: "FMCSA's federal database is public. Authority status, safety rating, fleet size, MC docket numbers — all free, all queryable. The QCMobile API answers any of these questions in milliseconds. The only reason the verification doesn't happen is that nobody has built the workflow that does it for the broker before they tender a load." },
    { kind: "p", text: "Our /#/find-carrier directory does it for the 150 we've sampled. Our paid broker tier ($99/mo, shipping with the rest of Tier-1 revenue) extends it to a real-time API: feed any carrier name, DOT, or MC; get back authority + safety + fleet + our DAT lane-rate context in one call. Tender the load only after the call returns clean." },
    { kind: "p", text: "The federal regulator can't keep up. The private market has to." },
  ],
  social: {},
};

const INSIGHTS_ARTICLES = [
  // DOUBLE_BROKERING_ARTICLE — held for now. The 23%/150-carrier sample
  // can't generalize to "all DAT carriers" without random sampling and
  // a longer time series. Re-list once we have ~1,500 randomly-sampled
  // carriers and a 90-day trend. The marketing surfaces across the site
  // already use the safer question-led framing.
  FUEL_RATES_ARTICLE,
  HUB_GROUP_ARTICLE,
  UPS_HUBS_DARK_ARTICLE,
  FFE_DISCIPLINE_ARTICLE,
  RECEIVERS_GEOGRAPHY_ARTICLE,
  REFINING_TIGHTNESS_ARTICLE,
  { tag: "Methodology", category: "Behind the Scenes", title: "How we built the only public freight intelligence platform that asks the operator network", excerpt: "Public records + operator-network intel + 22 metros. The trust contract that makes it work.", author: "Shipping Clarity Editorial", date: "Apr 28", read: "5 min" },
  { tag: "Launch", category: "Brand", title: "Mastio surveys the shippers. We listen to the drivers.", excerpt: "The freight industry's expensive, subscription-only ratings reports only ask one side. Here's why that's the opening — and how we close it.", author: "Shipping Clarity Editorial", date: "Apr 28", read: "4 min" },
  { tag: "Trend", category: "Analysis", title: "Why USPS scores are dropping in major metros — and where it's worst", excerpt: "Service times are up, tracking gaps are widening, and complaints are at a 3-year high. We dig into the regional postal performance crisis.", author: "Devon Hayes", date: "Apr 18", read: "6 min" },
  { tag: "Buyer's Guide", category: "Guide", title: "How to pick an LTL carrier when price isn't everything", excerpt: "Damage rates, pickup reliability, and claims handling matter more than most shippers realize. A practical framework.", author: "Priya Ramani", date: "Apr 12", read: "8 min" },
  { tag: "Spotlight", category: "Profile", title: "Saia's quiet rise: what they're getting right that others aren't", excerpt: "Three quarters of consistent gains across every metric we track. Drivers, dispatchers, and ops VPs explain the playbook.", author: "Marcus Webb", date: "Apr 08", read: "5 min" },
  { tag: "Methodology", category: "Behind the Scenes", title: "How we calculate the Clarity Score, fully explained", excerpt: "Eight weighted metrics, 14M+ shipments, and zero pay-to-play. The math behind every grade.", author: "Maya Chen", date: "Apr 02", read: "7 min" },
  { tag: "Q1 2026 Report", category: "Report", title: "The fastest-improving courier in every metro this quarter", excerpt: "Same-day is heating up. These are the carriers gaining ground in your city, ranked.", author: "Devon Hayes", date: "Mar 28", read: "5 min" },
  { tag: "Industry", category: "Analysis", title: "Amazon Logistics quietly passes FedEx Ground in West Coast volume", excerpt: "It happened in February and almost nobody noticed. What it means for shippers, drivers, and the long-term competitive landscape.", author: "Marcus Webb", date: "Mar 25", read: "9 min" },
  { tag: "Driver Voices", category: "Reported", title: "Why so many independent FedEx Ground contractors are walking away", excerpt: "We talked to 11 former contractor terminals. The pattern is unmistakable — and shippers should be paying attention.", author: "Priya Ramani", date: "Mar 21", read: "11 min" },
  { tag: "Buyer's Guide", category: "Guide", title: "Negotiating your small-parcel contract: what 2026 looks like", excerpt: "DIM weight, fuel surcharges, peak-season fees — what to push back on this year and what's table stakes.", author: "Maya Chen", date: "Mar 18", read: "10 min" },
];

// Expose for universal search.
if (typeof window !== "undefined") {
  window.INSIGHTS_ARTICLES = INSIGHTS_ARTICLES;
}

// Operator-network signal samples — paraphrased, no usernames, no platform
// references. Two-tier disclosure rule: the source mechanism stays opaque.
const OPERATOR_SIGNALS = [
  {
    role: "LTL shipper · LA basin",
    title: "Old Dominion refusing pickups in LA basin — capacity claim, A-list account",
    corroboration: 3, age: "2 days ago",
    snippet: "Three pickups missed this week, dispatcher says capacity. ODFL has always been my A-list carrier — first time I've seen this pattern.",
    sentiment: "negative", carrier: "Old Dominion", category: "LTL",
  },
  {
    role: "UPS sort-hub worker · Pasadena",
    title: "Routing software changes are quietly fixing on-time at small-package terminals",
    corroboration: 6, age: "5 days ago",
    snippet: "Been on the same route 11 years. New routing software is genuinely better. The on-time gain is real, not corporate noise.",
    sentiment: "positive", carrier: "UPS", category: "Small Package",
  },
  {
    role: "LTL planner · 22 years in",
    title: "Saia rep proactively called to fix a pricing error",
    corroboration: 4, age: "1 week ago",
    snippet: "I've been shipping LTL for 22 years. I have never had a carrier rep proactively call me about anything. Saia is doing something different.",
    sentiment: "positive", carrier: "Saia", category: "LTL",
  },
  {
    role: "USPS regional facility · 11 years",
    title: "Tracking blackholes traced to three scanning systems that don't sync",
    corroboration: 8, age: "3 days ago",
    snippet: "Honest answer involves three different scanning systems that don't talk to each other. Pattern is consistent across multiple regional facilities.",
    sentiment: "neutral", carrier: "USPS", category: "Small Package",
  },
  {
    role: "FTL driver · OTR",
    title: "Knight-Swift detention pay raised above $100/hr after 2 hours · effective May 1",
    corroboration: 5, age: "4 days ago",
    snippet: "Memo went out yesterday. Effective May 1. Significant for those of us running their lanes.",
    sentiment: "positive", carrier: "Knight-Swift", category: "FTL",
  },
  {
    role: "Small-parcel shipper · Shopify · ~800 pkg/wk",
    title: "Considering FedEx → UPS switch · So-Cal reliability degraded",
    corroboration: 3, age: "6 days ago",
    snippet: "FedEx Ground reliability brutal in Southern California for ~6 weeks. Same pattern reported across multiple shippers in the region.",
    sentiment: "neutral", carrier: "FedEx", category: "Small Package",
  },
];

const OPERATOR_VOICES = [
  {
    quote: "OnTrac has genuinely become my default for B2C in California. Three years ago I wouldn't have said that. Their tracking is cleaner than UPS now, full stop.",
    role: "Parcel manager · CA-based DTC", date: "Apr 19", corroboration: 9,
  },
  {
    quote: "Spent 90 minutes on hold with USPS yesterday. The IVR loops you back to the menu. There is no human. There hasn't been one for months.",
    role: "Rural-route shipper · upper Midwest", date: "Apr 16", corroboration: 18,
  },
  {
    quote: "Old Dominion is still the gold standard for damage-free LTL. I'll pay 12% more for a carrier that doesn't show up with crushed pallets. Math is easy.",
    role: "Industrial-LTL planner · 22 years", date: "Apr 14", corroboration: 7,
  },
  {
    quote: "Uber Direct is incredible if you're inside the 405 and useless if you're not. Same-day delivery is hyper-local now in a way nobody talks about.",
    role: "Last-mile coordinator · LA", date: "Apr 11", corroboration: 4,
  },
  {
    quote: "Amazon Logistics damage rate isn't worse — it's just visible. Other carriers hide it in claims pipelines. Amazon shows you photos. People can't handle that.",
    role: "DSP dispatcher · Pacific Northwest", date: "Apr 09", corroboration: 11,
  },
];

const TRENDING_TOPICS = [
  { topic: "LTL General Rate Increase", change: "+412%", direction: "up", desc: "Operator-network mentions, last 30 days" },
  { topic: "USPS tracking blackholes", change: "+187%", direction: "up", desc: "Up sharply since February nationwide" },
  { topic: "Saia capacity availability", change: "+94%", direction: "up", desc: "Shippers asking about new lanes" },
  { topic: "FedEx Ground contractor exits", change: "+68%", direction: "up", desc: "Concentrated in TX, GA, FL" },
  { topic: "Amazon Logistics expansion", change: "+41%", direction: "up", desc: "B2B inquiries up sharply" },
  { topic: "Peak season surcharge prep", change: "—", direction: "flat", desc: "Steady — annual cycle" },
];

const GUIDES = [
  {
    title: "The complete LTL buyer's guide", chapters: 8, time: "32 min", level: "Comprehensive",
    desc: "From class codes to claims — everything a shipper needs to know about less-than-truckload, written for humans.",
  },
  {
    title: "Small parcel contract negotiation playbook", chapters: 6, time: "24 min", level: "Intermediate",
    desc: "DIM weight, fuel surcharges, residential fees, GRI clauses. What to push on, what to accept, what to walk from.",
  },
  {
    title: "Choosing your first 3PL", chapters: 5, time: "18 min", level: "Beginner",
    desc: "When to outsource fulfillment, what questions to ask, and the red flags that mean run.",
  },
  {
    title: "International shipping from a US warehouse", chapters: 7, time: "28 min", level: "Intermediate",
    desc: "Customs, brokerage, DDP vs DDU, prohibited items, and how to actually estimate landed cost.",
  },
];

const CARRIER_PULSE = [
  { carrier: "UPS", chatter: 4280, sentiment: 72, trend: +3, color: "#8B5A1A" },
  { carrier: "FedEx", chatter: 3914, sentiment: 64, trend: -2, color: "#5A2C8C" },
  { carrier: "USPS", chatter: 5102, sentiment: 38, trend: -7, color: "#1E3A8A" },
  { carrier: "Amazon Logistics", chatter: 2847, sentiment: 58, trend: +4, color: "#E8A33D" },
  { carrier: "Old Dominion", chatter: 891, sentiment: 84, trend: +1, color: "#1A4D2E" },
  { carrier: "Saia", chatter: 612, sentiment: 79, trend: +6, color: "#2563EB" },
  { carrier: "OnTrac", chatter: 487, sentiment: 71, trend: +2, color: "#C53030" },
  { carrier: "DHL", chatter: 1024, sentiment: 61, trend: 0, color: "#D4A017" },
];

// =============================================================
// MAIN INSIGHTS PAGE
// =============================================================
function InsightsPage({ onNav, initialSlug }) {
  const [activeFilter, setActiveFilter] = useStateI("All");
  const [activeTab, setActiveTab] = useStateI("editorial");
  // Resolve the article from the URL slug (if any) on first render.
  const initialArticle = initialSlug
    ? INSIGHTS_ARTICLES.find(a => a.slug === initialSlug) || null
    : null;
  const [activeArticle, setActiveArticle] = useStateI(initialArticle);
  const [nlEmail, setNlEmail] = useStateI("");
  const [nlSent, setNlSent] = useStateI(false);

  async function submitNewsletter(e) {
    e.preventDefault();
    if (!nlEmail.trim() || !nlEmail.includes("@")) return;
    if (window.SI_DB) {
      try {
        if (window.SI_DB.submitNewsletterSignup) {
          await window.SI_DB.submitNewsletterSignup(nlEmail.trim(), "loading_dock");
        } else if (window.SI_DB.submitPulseSubscription) {
          await window.SI_DB.submitPulseSubscription(nlEmail.trim(), "national", "loading_dock");
        }
      } catch (err) { console.warn("newsletter signup err", err); }
    }
    setNlSent(true);
  }

  // Track URL slug changes so direct links (and the social-share URLs) open
  // the right article. Uses React.useEffect (not the I-aliased hook) — both
  // resolve to the same React.useEffect.
  React.useEffect(() => {
    if (initialSlug) {
      const a = INSIGHTS_ARTICLES.find(x => x.slug === initialSlug);
      if (a && (!activeArticle || activeArticle.slug !== initialSlug)) setActiveArticle(a);
    } else if (activeArticle) {
      // URL no longer carries a slug (back button) — close the detail view.
      setActiveArticle(null);
    }
  }, [initialSlug]);

  // When the user opens an article from the grid, push the slug into the URL
  // so the address bar and the share button reflect the same canonical link.
  function openArticle(a) {
    setActiveArticle(a);
    if (a && a.slug) {
      const target = `#/insights/${a.slug}`;
      if (window.location.hash !== target) window.location.hash = target;
    }
  }
  function closeArticle() {
    setActiveArticle(null);
    if (window.location.hash.startsWith('#/insights/')) {
      window.location.hash = '#/insights';
    }
  }

  const filters = ["All", "Report", "Analysis", "Guide", "Profile", "Reported", "Behind the Scenes"];
  const filtered = useMemoI(() => {
    if (activeFilter === "All") return INSIGHTS_ARTICLES;
    return INSIGHTS_ARTICLES.filter(a => a.category === activeFilter);
  }, [activeFilter]);

  // Detail view — only shown when an article is open.
  if (activeArticle) {
    return <ArticleDetail article={activeArticle} onBack={closeArticle} />;
  }

  return (
    <div className="page-insights-v2">
      {/* HERO */}
      <section className="ins-hero">
        <div className="ins-hero-inner">
          <div className="ins-hero-grid">
            <div className="ins-hero-left">
              <div className="hero-eyebrow"><span className="eyebrow-dot" />Clarity · Updated daily</div>
              <h1 className="hero-title">The shipping<br/>industry, <em>told straight</em>.</h1>
              <p className="hero-sub">
                Deep-dive investigations, quarterly trend reports, hands-on buyer's guides, and the unfiltered
                voice of the shippers, drivers, and dispatchers who actually move the freight.
              </p>
              <div className="ins-hero-stats">
                <div><span className="ins-stat-num">{INSIGHTS_ARTICLES.length}</span><span className="ins-stat-l">Articles + investigations</span></div>
                <div><span className="ins-stat-num">22</span><span className="ins-stat-l">Freight metros tracked</span></div>
                <div><span className="ins-stat-num">Free</span><span className="ins-stat-l">No paywall, ever</span></div>
              </div>
            </div>
            <div className="ins-hero-right">
              <div className="newsletter-card">
                <div className="newsletter-eyebrow">The Loading Dock · Weekly</div>
                <div className="newsletter-h">Get the carrier roundup every Tuesday.</div>
                {nlSent ? (
                  <div className="newsletter-sent">✓ You're on the list — see you Tuesday.</div>
                ) : (
                  <form className="newsletter-form" onSubmit={submitNewsletter}>
                    <input type="email" required placeholder="you@company.com" value={nlEmail} onChange={e => setNlEmail(e.target.value)} />
                    <button type="submit" className="btn-primary">Subscribe</button>
                  </form>
                )}
                <div className="newsletter-fine">
                  Trusted by ops leads at 1,400+ shippers · No spam · Unsubscribe anytime
                </div>
                <div className="newsletter-logos">
                  <span>SHOPIFY</span><span>WAYFAIR</span><span>1‑800‑FLOWERS</span><span>WEEE!</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* TAB BAR — primary content modes */}
      <section className="ins-tabs">
        <div className="ins-tabs-inner">
          {[
            { id: "editorial", label: "Editorial", count: 340 },
            { id: "community", label: "Operator Voices", count: 1240 },
            { id: "trends", label: "Trending Now", count: 18 },
            { id: "guides", label: "Buyer's Guides", count: 24 },
            { id: "data", label: "Data Center", count: 7 },
          ].map(t => (
            <button key={t.id}
              className={`ins-tab ${activeTab === t.id ? "active" : ""}`}
              onClick={() => setActiveTab(t.id)}>
              <span>{t.label}</span>
              <span className="ins-tab-count">{t.count}</span>
            </button>
          ))}
        </div>
      </section>

      {/* TAB CONTENT */}
      {activeTab === "editorial" && <EditorialTab featured={INSIGHTS_FEATURED} articles={filtered} filters={filters} activeFilter={activeFilter} setActiveFilter={setActiveFilter} onOpen={openArticle} />}
      {activeTab === "community" && <CommunityTab threads={OPERATOR_SIGNALS} quotes={OPERATOR_VOICES} pulse={CARRIER_PULSE} />}
      {activeTab === "trends" && <TrendsTab topics={TRENDING_TOPICS} pulse={CARRIER_PULSE} />}
      {activeTab === "guides" && <GuidesTab guides={GUIDES} />}
      {activeTab === "data" && <DataTab />}

      {/* CTA */}
      <section className="ins-cta">
        <div className="ins-cta-inner">
          <div className="section-eyebrow">Stay sharp</div>
          <h2 className="section-title">The Loading Dock — every Tuesday morning.</h2>
          <p className="ins-cta-p">
            One email. Five minutes. The most important shipping stories, scored by what actually changed for shippers this week.
          </p>
          {nlSent ? (
            <div className="newsletter-sent ins-cta-sent">✓ You're on the list — see you Tuesday.</div>
          ) : (
            <form className="ins-cta-form" onSubmit={submitNewsletter}>
              <input type="email" required placeholder="you@company.com" value={nlEmail} onChange={e => setNlEmail(e.target.value)} />
              <button type="submit" className="btn-primary-lg">Subscribe free →</button>
            </form>
          )}
        </div>
      </section>
    </div>
  );
}

// =============================================================
// FEATURE GRAPHIC — editorial SVG that picks an illustration based on
// the article. Replaces the old flat-color + diagonal-stripe block,
// which read as a placeholder rather than considered editorial design.
// =============================================================
function FeatureGraphic({ article }) {
  // Article-specific illustrations. The default falls back to a clean
  // facility-grid map that fits any operations-network piece.
  const slug = article.slug || "";
  if (slug.startsWith("ups-")) {
    return <FacilityGridGraphic total={50} closing={25} accent="oklch(0.55 0.18 25)" />;
  }
  if (slug.startsWith("hub-group-")) {
    return <ChapterChainGraphic count={13} accent="oklch(0.50 0.22 25)" />;
  }
  if (slug.startsWith("86000-docks-") || slug.startsWith("receivers-")) {
    return <DockDensityGraphic accent="oklch(0.50 0.18 250)" />;
  }
  if (slug.startsWith("double-brokering-")) {
    return <ChainBreakGraphic accent="oklch(0.50 0.20 25)" />;
  }
  return <FacilityGridGraphic total={48} closing={12} accent="oklch(0.50 0.18 250)" />;
}

// 50-facility grid — squares represent facilities, filled squares are
// the ones being closed. Reads as a small operations dashboard.
function FacilityGridGraphic({ total = 50, closing = 25, accent }) {
  const cols = 10, rows = Math.ceil(total / cols);
  const cellW = 38, cellH = 36, padX = 40, padY = 60;
  // Deterministic "closed" pattern — pseudo-random but stable per render.
  const closedSet = new Set();
  let i = 0;
  while (closedSet.size < closing) {
    closedSet.add((i * 7 + 3) % total);
    i++;
  }
  const cells = [];
  for (let r = 0; r < rows; r++) {
    for (let c = 0; c < cols; c++) {
      const idx = r * cols + c;
      if (idx >= total) continue;
      const x = padX + c * cellW;
      const y = padY + r * cellH;
      const closed = closedSet.has(idx);
      cells.push(
        <g key={idx}>
          <rect x={x} y={y} width={26} height={24} rx={2}
            stroke="var(--ink)" strokeWidth={1.2}
            fill={closed ? accent : "transparent"}
            opacity={closed ? 0.92 : 0.55} />
          {closed && (
            <line x1={x + 4} y1={y + 4} x2={x + 22} y2={y + 20}
              stroke="var(--paper)" strokeWidth={1.5} opacity={0.9} />
          )}
        </g>
      );
    }
  }
  return (
    <svg viewBox="0 0 480 480" width="100%" height="100%" preserveAspectRatio="xMidYMid slice"
      style={{ display: "block", background: "var(--paper-2, #f7f4ee)" }}>
      <defs>
        <pattern id="fg-grid" width="20" height="20" patternUnits="userSpaceOnUse">
          <path d="M 20 0 L 0 0 0 20" fill="none" stroke="var(--ink)" strokeWidth="0.4" opacity="0.06" />
        </pattern>
      </defs>
      <rect width="480" height="480" fill="url(#fg-grid)" />
      <text x={padX} y={36} fontFamily="var(--font-mono)" fontSize="10"
        letterSpacing="2.4" fill="var(--ink-soft)">FACILITY · STATUS</text>
      {cells}
      <line x1={padX} y1={padY + rows * cellH + 12} x2={padX + cols * cellW - 12}
        y2={padY + rows * cellH + 12} stroke="var(--ink)" strokeWidth="0.8" opacity="0.25" />
      <g transform={`translate(${padX}, ${padY + rows * cellH + 32})`}>
        <rect width={14} height={12} rx={1.5} fill={accent} opacity={0.92} />
        <text x={22} y={10} fontFamily="var(--font-mono)" fontSize="10" fill="var(--ink)">
          Closing · {closing}
        </text>
        <rect x={110} width={14} height={12} rx={1.5} fill="transparent"
          stroke="var(--ink)" strokeWidth={1.2} opacity={0.55} />
        <text x={132} y={10} fontFamily="var(--font-mono)" fontSize="10" fill="var(--ink)">
          Operating · {total - closing}
        </text>
      </g>
    </svg>
  );
}

// Chain of Chapter 11 dockets — small black squares connected in a line,
// with the count ticking. Reads as a timeline of failures.
function ChapterChainGraphic({ count = 13, accent }) {
  const items = Array.from({ length: count });
  return (
    <svg viewBox="0 0 480 480" width="100%" height="100%" preserveAspectRatio="xMidYMid slice"
      style={{ display: "block", background: "var(--paper-2, #f7f4ee)" }}>
      <defs>
        <pattern id="cc-grid" width="20" height="20" patternUnits="userSpaceOnUse">
          <path d="M 20 0 L 0 0 0 20" fill="none" stroke="var(--ink)" strokeWidth="0.4" opacity="0.06" />
        </pattern>
      </defs>
      <rect width="480" height="480" fill="url(#cc-grid)" />
      <text x="40" y="44" fontFamily="var(--font-mono)" fontSize="10" letterSpacing="2.4" fill="var(--ink-soft)">
        CHAPTER 11 · CUSTOMER DOCKETS
      </text>
      <text x="40" y="120" fontFamily="var(--font-serif)" fontSize="120" fontWeight="700" fill="var(--ink)" letterSpacing="-0.04em">
        {count}
      </text>
      <text x="40" y="150" fontFamily="var(--font-mono)" fontSize="11" fill="var(--ink-soft)" letterSpacing="0.08em">
        SINCE MARCH 2024
      </text>
      <line x1="40" y1="200" x2="440" y2="200" stroke="var(--ink)" strokeWidth="0.8" opacity="0.2" />
      <g transform="translate(40, 240)">
        {items.map((_, i) => {
          const x = (i % 7) * 56;
          const y = Math.floor(i / 7) * 70;
          return (
            <g key={i} transform={`translate(${x}, ${y})`}>
              <rect width={44} height={50} rx={2} fill="transparent" stroke="var(--ink)" strokeWidth={1.2} opacity={0.7} />
              <line x1={6} y1={10} x2={38} y2={10} stroke="var(--ink)" strokeWidth={0.8} opacity={0.5} />
              <line x1={6} y1={18} x2={32} y2={18} stroke="var(--ink)" strokeWidth={0.8} opacity={0.5} />
              <line x1={6} y1={26} x2={36} y2={26} stroke="var(--ink)" strokeWidth={0.8} opacity={0.5} />
              <rect x={6} y={36} width={20} height={6} fill={accent} opacity={0.85} />
              <text x={22} y={64} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="9" fill="var(--ink-soft)">
                #{String(i + 1).padStart(2, "0")}
              </text>
            </g>
          );
        })}
      </g>
    </svg>
  );
}

// Receiver-density US shape — abstract clustered dots suggesting national footprint.
function DockDensityGraphic({ accent }) {
  // Hand-placed clusters approximating the major-metro distribution of receivers.
  const clusters = [
    { x: 100, y: 200, n: 14, r: 2.8 }, // West
    { x: 130, y: 280, n: 18, r: 3.0 }, // SoCal
    { x: 200, y: 220, n: 10, r: 2.4 },
    { x: 270, y: 200, n: 12, r: 2.6 }, // Central
    { x: 320, y: 170, n: 16, r: 2.8 }, // Chicago
    { x: 320, y: 290, n: 14, r: 2.6 }, // Texas
    { x: 380, y: 230, n: 18, r: 2.8 }, // SE
    { x: 410, y: 180, n: 20, r: 3.0 }, // NE
    { x: 400, y: 290, n: 12, r: 2.4 }, // FL
  ];
  const dots = [];
  let key = 0;
  clusters.forEach((c) => {
    for (let i = 0; i < c.n; i++) {
      const angle = (i * 2.4) % (Math.PI * 2);
      const radius = (i % 5) * 6 + 4;
      const x = c.x + Math.cos(angle) * radius;
      const y = c.y + Math.sin(angle) * radius;
      dots.push(<circle key={key++} cx={x} cy={y} r={c.r} fill={accent} opacity={0.7} />);
    }
  });
  return (
    <svg viewBox="0 0 480 480" width="100%" height="100%" preserveAspectRatio="xMidYMid slice"
      style={{ display: "block", background: "var(--paper-2, #f7f4ee)" }}>
      <defs>
        <pattern id="dd-grid" width="20" height="20" patternUnits="userSpaceOnUse">
          <path d="M 20 0 L 0 0 0 20" fill="none" stroke="var(--ink)" strokeWidth="0.4" opacity="0.06" />
        </pattern>
      </defs>
      <rect width="480" height="480" fill="url(#dd-grid)" />
      <text x="40" y="44" fontFamily="var(--font-mono)" fontSize="10" letterSpacing="2.4" fill="var(--ink-soft)">
        DELIVERY DOCKS · UNITED STATES
      </text>
      {dots}
      <text x="40" y="430" fontFamily="var(--font-serif)" fontSize="38" fontWeight="700" fill="var(--ink)" letterSpacing="-0.02em">
        86,080
      </text>
      <text x="40" y="452" fontFamily="var(--font-mono)" fontSize="10" fill="var(--ink-soft)" letterSpacing="0.08em">
        NAMED RECEIVING LOCATIONS · 29 BRANDS
      </text>
    </svg>
  );
}

// Broken-chain motif for the double-brokering investigation.
function ChainBreakGraphic({ accent }) {
  return (
    <svg viewBox="0 0 480 480" width="100%" height="100%" preserveAspectRatio="xMidYMid slice"
      style={{ display: "block", background: "var(--paper-2, #f7f4ee)" }}>
      <defs>
        <pattern id="cb-grid" width="20" height="20" patternUnits="userSpaceOnUse">
          <path d="M 20 0 L 0 0 0 20" fill="none" stroke="var(--ink)" strokeWidth="0.4" opacity="0.06" />
        </pattern>
      </defs>
      <rect width="480" height="480" fill="url(#cb-grid)" />
      <text x="40" y="44" fontFamily="var(--font-mono)" fontSize="10" letterSpacing="2.4" fill="var(--ink-soft)">
        CHAIN OF CUSTODY · BROKEN
      </text>
      {/* Three actors: shipper → broker → carrier. Middle is the gap. */}
      <g transform="translate(60, 200)">
        <rect width={100} height={80} rx={4} fill="transparent" stroke="var(--ink)" strokeWidth={1.4} />
        <text x={50} y={36} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fill="var(--ink)" letterSpacing="0.1em">SHIPPER</text>
        <text x={50} y={56} textAnchor="middle" fontFamily="var(--font-serif)" fontSize="14" fill="var(--ink-soft)">books load</text>
      </g>
      <g transform="translate(190, 200)">
        <rect width={100} height={80} rx={4} fill={accent} opacity={0.18} stroke={accent} strokeDasharray="4 4" strokeWidth={1.4} />
        <text x={50} y={36} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fill={accent} letterSpacing="0.1em">UNAUTHORIZED</text>
        <text x={50} y={56} textAnchor="middle" fontFamily="var(--font-serif)" fontSize="14" fill="var(--ink)">re-brokered</text>
      </g>
      <g transform="translate(320, 200)">
        <rect width={100} height={80} rx={4} fill="transparent" stroke="var(--ink)" strokeWidth={1.4} />
        <text x={50} y={36} textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fill="var(--ink)" letterSpacing="0.1em">CARRIER</text>
        <text x={50} y={56} textAnchor="middle" fontFamily="var(--font-serif)" fontSize="14" fill="var(--ink-soft)">moves freight</text>
      </g>
      {/* Connectors with a break in the middle. */}
      <line x1={160} y1={240} x2={185} y2={240} stroke="var(--ink)" strokeWidth={1.4} />
      <line x1={295} y1={240} x2={320} y2={240} stroke="var(--ink)" strokeWidth={1.4} strokeDasharray="3 3" />
      <text x="240" y="170" textAnchor="middle" fontFamily="var(--font-mono)" fontSize="10" fill={accent} letterSpacing="0.16em">
        ⚠ INSURANCE GAP
      </text>
      <text x="40" y="430" fontFamily="var(--font-serif)" fontSize="32" fontWeight="700" fill="var(--ink)" letterSpacing="-0.02em">
        Verify before you tender.
      </text>
      <text x="40" y="452" fontFamily="var(--font-mono)" fontSize="10" fill="var(--ink-soft)" letterSpacing="0.08em">
        AUTHORITY · SAFETY · FLEET · IN ONE CALL
      </text>
    </svg>
  );
}

// =============================================================
// EDITORIAL TAB
// =============================================================
function EditorialTab({ featured, articles, filters, activeFilter, setActiveFilter, onOpen }) {
  return (
    <>
      {/* FEATURED */}
      <section className="ins-featured">
        <div className="ins-featured-inner">
          <article className="ins-feature-article" onClick={() => onOpen && onOpen(featured)} style={{ cursor: "pointer" }}>
            <div className="ins-feature-img">
              <FeatureGraphic article={featured} />
              <div className="ins-feature-img-tag">{featured.tag}</div>
            </div>
            <div className="ins-feature-body">
              <div className="ins-feature-cat">— {featured.category}</div>
              <h2 className="ins-feature-title">{featured.title}</h2>
              <p className="ins-feature-dek">{featured.dek}</p>
              <div className="ins-feature-meta">
                <span className="author-dot" />
                <span><strong>{featured.author}</strong> · {featured.authorRole}</span>
                <span className="dot-sep">·</span>
                <span>{featured.date}</span>
                <span className="dot-sep">·</span>
                <span>{featured.read} read</span>
              </div>
              <div className="ins-feature-stats">
                {featured.stats.map((s, i) => (
                  <div key={i} className="ins-fs">
                    <div className="ins-fs-v">{s.v}</div>
                    <div className="ins-fs-l">{s.l}</div>
                  </div>
                ))}
              </div>
              <button className="btn-primary" onClick={(e) => { e.stopPropagation(); onOpen && onOpen(featured); }}>Read the full investigation →</button>
            </div>
          </article>
        </div>
      </section>

      {/* FILTER + GRID */}
      <section className="ins-grid-section">
        <div className="ins-grid-inner">
          <div className="ins-grid-head">
            <h3 className="ins-grid-h">Latest from the desk</h3>
            <div className="ins-filters">
              {filters.map(f => (
                <button key={f} className={`ins-filter ${activeFilter === f ? "active" : ""}`} onClick={() => setActiveFilter(f)}>
                  {f}
                </button>
              ))}
            </div>
          </div>
          <div className="ins-articles-grid">
            {articles.map((a, i) => (
              <article key={i} className="ins-article-card" onClick={() => onOpen && onOpen(a)} style={{ cursor: "pointer" }}>
                <div className="ins-article-cat-row">
                  <span className="insight-tag">{a.tag}</span>
                  <span className="ins-article-cat">{a.category}</span>
                </div>
                <h3 className="ins-article-title">{a.title}</h3>
                <p className="ins-article-excerpt">{a.excerpt}</p>
                <div className="ins-article-foot">
                  <span><strong>{a.author}</strong></span>
                  <span className="dot-sep">·</span>
                  <span>{a.date}</span>
                  <span className="dot-sep">·</span>
                  <span>{a.read} read</span>
                </div>
              </article>
            ))}
          </div>
          <div className="ins-load-more">
            <button className="btn-ghost-lg">Load more articles →</button>
          </div>
        </div>
      </section>
    </>
  );
}

// =============================================================
// OPERATOR VOICES TAB — paraphrased signal from the network,
// attributed by role + region. No usernames, no platforms.
// =============================================================
function CommunityTab({ threads, quotes, pulse }) {
  const [carrierFilter, setCarrierFilter] = useStateI("All");
  const carriers = ["All", ...new Set(threads.map(t => t.carrier))];
  const filteredThreads = carrierFilter === "All" ? threads : threads.filter(t => t.carrier === carrierFilter);

  return (
    <>
      {/* DISCLAIMER STRIP */}
      <section className="comm-disclaimer">
        <div className="comm-disclaimer-inner">
          <div className="comm-disc-icon">ⓘ</div>
          <div>
            <strong>What you're reading:</strong> paraphrased operator-network signal,
            attributed by role and region only. No usernames. No platforms. No verbatim
            republication. We surface what the network is saying — never who said it
            or where. The trust contract.
          </div>
        </div>
      </section>

      {/* CARRIER PULSE */}
      <section className="pulse-section">
        <div className="pulse-inner">
          <div className="ins-grid-head">
            <div>
              <div className="section-eyebrow">Carrier pulse · 30-day window</div>
              <h2 className="section-title">What people are saying.</h2>
            </div>
            <div className="pulse-legend">
              <span><span className="pulse-dot" style={{ background: "var(--green)" }}/>Positive sentiment</span>
              <span><span className="pulse-dot" style={{ background: "var(--amber)" }}/>Mixed</span>
              <span><span className="pulse-dot" style={{ background: "var(--red)" }}/>Negative</span>
            </div>
          </div>
          <div className="pulse-grid">
            {pulse.map(p => {
              let sColor = "var(--ink)";
              if (p.sentiment >= 70) sColor = "var(--green)";
              else if (p.sentiment >= 50) sColor = "var(--amber)";
              else sColor = "var(--red)";
              return (
                <div key={p.carrier} className="pulse-card">
                  <div className="pulse-head">
                    <span className="pulse-carrier-dot" style={{ background: p.color }}>{p.carrier[0]}</span>
                    <div className="pulse-name">{p.carrier}</div>
                  </div>
                  <div className="pulse-metrics">
                    <div>
                      <div className="pulse-l">Mentions</div>
                      <div className="pulse-v">{p.chatter.toLocaleString()}</div>
                    </div>
                    <div>
                      <div className="pulse-l">Sentiment</div>
                      <div className="pulse-v" style={{ color: sColor }}>{p.sentiment}<span className="pulse-pct">/100</span></div>
                    </div>
                    <div>
                      <div className="pulse-l">QoQ</div>
                      <div className="pulse-v"><TrendArrow trend={p.trend} /></div>
                    </div>
                  </div>
                  <div className="pulse-bar"><span className="pulse-bar-fill" style={{ width: `${p.sentiment}%`, background: sColor }} /></div>
                </div>
              );
            })}
          </div>
        </div>
      </section>

      {/* THREADS */}
      <section className="threads-section">
        <div className="threads-inner">
          <div className="ins-grid-head">
            <div>
              <div className="section-eyebrow">Top community threads</div>
              <h2 className="section-title">From the front lines.</h2>
            </div>
            <div className="ins-filters">
              {carriers.map(c => (
                <button key={c} className={`ins-filter ${carrierFilter === c ? "active" : ""}`} onClick={() => setCarrierFilter(c)}>
                  {c}
                </button>
              ))}
            </div>
          </div>
          <div className="threads-grid">
            {filteredThreads.map((t, i) => (
              <article key={i} className="thread-card">
                <div className="thread-head">
                  <span className="thread-sub">{t.role}</span>
                  <span className={`thread-sent thread-sent-${t.sentiment}`}>
                    {t.sentiment === "positive" ? "▲" : t.sentiment === "negative" ? "▼" : "—"} {t.sentiment}
                  </span>
                </div>
                <h3 className="thread-title">{t.title}</h3>
                <p className="thread-snippet">"{t.snippet}"</p>
                <div className="thread-foot">
                  <span className="thread-stat">{t.corroboration}× corroborated</span>
                  <span className="thread-stat">{t.age}</span>
                  <span className="thread-tag">{t.carrier} · {t.category}</span>
                </div>
              </article>
            ))}
          </div>
        </div>
      </section>

      {/* QUOTE WALL */}
      <section className="quotes-section">
        <div className="quotes-inner">
          <div className="section-eyebrow">Voices</div>
          <h2 className="section-title">What shippers and drivers told us this month.</h2>
          <div className="quotes-grid">
            {quotes.map((q, i) => (
              <figure key={i} className="quote-card">
                <blockquote className="quote-text">"{q.quote}"</blockquote>
                <figcaption className="quote-cite">
                  <span className="quote-author">{q.role}</span>
                  <span className="dot-sep">·</span>
                  <span>{q.date}</span>
                  <span className="dot-sep">·</span>
                  <span>{q.corroboration}× corroborated</span>
                </figcaption>
              </figure>
            ))}
          </div>
        </div>
      </section>
    </>
  );
}

// =============================================================
// TRENDS TAB
// =============================================================
function TrendsTab({ topics, pulse }) {
  return (
    <>
      <section className="trends-section">
        <div className="trends-inner">
          <div className="section-eyebrow">Trending now · last 30 days</div>
          <h2 className="section-title">What's heating up.</h2>
          <p className="trends-p">Topics gaining momentum across the operator network and our shipper subscribers — ranked by velocity, not raw volume.</p>
          <div className="trends-list">
            {topics.map((t, i) => (
              <div key={i} className="trend-row">
                <span className="trend-rank">{String(i+1).padStart(2,"0")}</span>
                <div className="trend-mid">
                  <div className="trend-topic">{t.topic}</div>
                  <div className="trend-desc">{t.desc}</div>
                </div>
                <div className={`trend-change trend-change-${t.direction}`}>{t.change}</div>
                <button className="btn-ghost trend-cta">Investigate →</button>
              </div>
            ))}
          </div>
        </div>
      </section>

      <section className="heatmap-section">
        <div className="heatmap-inner">
          <div className="section-eyebrow">Sentiment heatmap</div>
          <h2 className="section-title">Carrier mood, by category, this quarter.</h2>
          <div className="heatmap-grid">
            <div className="heatmap-col-h"></div>
            {["Small Pkg", "LTL", "FTL", "Courier", "Intl"].map(c => (
              <div key={c} className="heatmap-col-h">{c}</div>
            ))}
            {[
              { name: "UPS", row: [82, 76, 70, 65, 78] },
              { name: "FedEx", row: [74, 68, 71, 60, 79] },
              { name: "USPS", row: [38, null, null, 42, 45] },
              { name: "Amazon", row: [62, null, null, 70, null] },
              { name: "Old Dominion", row: [null, 88, 76, null, null] },
              { name: "Saia", row: [null, 81, 72, null, null] },
              { name: "OnTrac", row: [71, null, null, 68, null] },
              { name: "DHL", row: [56, null, null, null, 84] },
            ].map(r => (
              <React.Fragment key={r.name}>
                <div className="heatmap-row-h">{r.name}</div>
                {r.row.map((v, j) => {
                  if (v === null) return <div key={j} className="heatmap-cell heatmap-cell-na">—</div>;
                  let bg = "var(--ink)";
                  if (v >= 75) bg = "var(--green)";
                  else if (v >= 60) bg = "oklch(0.7 0.10 145)";
                  else if (v >= 50) bg = "var(--amber)";
                  else bg = "var(--red)";
                  return <div key={j} className="heatmap-cell" style={{ background: bg, color: v >= 60 ? "white" : v >= 50 ? "var(--ink)" : "white" }}>{v}</div>;
                })}
              </React.Fragment>
            ))}
          </div>
        </div>
      </section>
    </>
  );
}

// =============================================================
// GUIDES TAB
// =============================================================
function GuidesTab({ guides }) {
  return (
    <section className="guides-section">
      <div className="guides-inner">
        <div className="section-eyebrow">Buyer's guides · Plain English, no fluff</div>
        <h2 className="section-title">Learn shipping like an operator.</h2>
        <p className="guides-p">Long-form, practical guides from people who've actually negotiated the contracts and run the routes. Read end-to-end or jump to a chapter.</p>
        <div className="guides-grid">
          {guides.map((g, i) => (
            <article key={i} className="guide-card">
              <div className="guide-num">G·{String(i+1).padStart(2,"0")}</div>
              <h3 className="guide-title">{g.title}</h3>
              <p className="guide-desc">{g.desc}</p>
              <div className="guide-meta">
                <span><strong>{g.chapters}</strong> chapters</span>
                <span className="dot-sep">·</span>
                <span>{g.time}</span>
                <span className="dot-sep">·</span>
                <span className="guide-level">{g.level}</span>
              </div>
              <button className="btn-ghost guide-cta">Start reading →</button>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

// =============================================================
// DATA TAB
// =============================================================
function DataTab() {
  const datasets = [
    { name: "Q1 2026 Carrier Performance Dataset", desc: "47 metros, 128 carriers, 8 metrics. The complete underlying dataset for this quarter's report cards.", size: "2.4MB CSV", access: "Verified" },
    { name: "5-year LTL pricing index", desc: "Quarterly LTL pricing data across the top 10 carriers, normalized by lane and weight class.", size: "1.1MB CSV", access: "Spotlight" },
    { name: "Operator-community sentiment archive", desc: "12 months of categorized operator-community shipping discussions, anonymized and tagged.", size: "8.2MB JSON", access: "Spotlight" },
    { name: "Damage & claims rate by category", desc: "Reported damage and claim outcomes across all five shipping categories, last 8 quarters.", size: "640KB CSV", access: "Verified" },
    { name: "Driver-reported carrier conditions", desc: "Aggregated driver feedback on dispatchers, routing, pay, and equipment by carrier.", size: "1.8MB CSV", access: "Spotlight" },
  ];
  return (
    <section className="data-section">
      <div className="data-inner">
        <div className="section-eyebrow">Data center · For researchers, journalists, and ops teams</div>
        <h2 className="section-title">The underlying data, available.</h2>
        <p className="data-p">Verified and Spotlight members can access the raw datasets behind every grade and report. Methodology, schemas, and sample rows below.</p>
        <div className="data-list">
          {datasets.map((d, i) => (
            <div key={i} className="data-row">
              <div className="data-row-icon">DB</div>
              <div className="data-row-mid">
                <div className="data-row-name">{d.name}</div>
                <div className="data-row-desc">{d.desc}</div>
              </div>
              <div className="data-row-meta">
                <span className="data-size">{d.size}</span>
                <span className={`data-access data-access-${d.access.toLowerCase()}`}>{d.access}+</span>
              </div>
              <button className="btn-ghost">Request →</button>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// =============================================================
// SHARE BAR — X / LinkedIn / Copy Link / Email. Renders a row of
// share buttons under the article byline. Each button computes
// the share URL on click (so the URL is fresh against the current
// hash route).
// =============================================================
// Per-article OG/Twitter Card shims live at /i/<slug>. The shim file has
// the rich preview meta and a meta-refresh + JS redirect to the live hash
// route. List the slugs that have shims here so we only return /i/<slug>
// for those — anything else falls back to the hash URL until a shim ships.
const OG_SHIM_SLUGS = new Set([
  'hub-group-distress-three-weeks-early-2026',
  'when-a-ups-hub-goes-dark-2026',
  'ffe-discipline-in-refrigerated-2026',
  '86000-docks-geography-where-america-delivers-2026',
  'padd-iii-refining-tightness-diesel-surcharges-2026',
]);

function shareUrlFor(article) {
  if (typeof window === 'undefined') return 'https://shippingclarity.com';
  const base = window.location.origin || 'https://shippingclarity.com';
  const slug = article.slug || '';
  if (slug && OG_SHIM_SLUGS.has(slug)) {
    // Rich-preview path — social scrapers fetch this, humans get redirected.
    return `${base}/i/${slug}`;
  }
  return `${base}/#/insights/${slug}`;
}

function ShareBar({ article }) {
  const [copied, setCopied] = useStateI(false);
  const url = shareUrlFor(article);
  const title = article.title || 'Shipping Clarity';
  const xText = `${title} — via Shipping Clarity`;

  function open(href) {
    window.open(href, '_blank', 'noopener,noreferrer,width=640,height=720');
  }
  function shareX() {
    open(`https://twitter.com/intent/tweet?text=${encodeURIComponent(xText)}&url=${encodeURIComponent(url)}`);
  }
  function shareLinkedIn() {
    open(`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`);
  }
  function shareEmail() {
    const body = `${title}\n\n${article.dek || ''}\n\n${url}`;
    window.location.href = `mailto:?subject=${encodeURIComponent(title)}&body=${encodeURIComponent(body)}`;
  }
  async function copyLink() {
    try {
      await navigator.clipboard.writeText(url);
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    } catch (e) {
      // Fallback: select a temporary input.
      const t = document.createElement('input');
      t.value = url; document.body.appendChild(t); t.select();
      try { document.execCommand('copy'); setCopied(true); setTimeout(() => setCopied(false), 1800); } catch (_) {}
      document.body.removeChild(t);
    }
  }

  return (
    <div className="share-bar">
      <style>{`
        .share-bar {
          display: inline-flex; gap: 8px; flex-wrap: wrap;
          margin: 14px 0 0; padding: 8px;
          background: var(--paper-2, #f4f4f0);
          border: 1px solid var(--rule-soft, #e5e5e0);
          border-radius: 8px;
        }
        .share-btn {
          display: inline-flex; align-items: center; gap: 6px;
          padding: 7px 12px; border-radius: 6px;
          font-family: var(--font-mono); font-size: 11px;
          letter-spacing: 0.1em; text-transform: uppercase;
          background: #fff; border: 1px solid var(--rule, #e0e0d8);
          color: var(--ink); cursor: pointer; transition: all 0.12s;
        }
        .share-btn:hover { background: var(--ink); color: var(--paper, #fff); border-color: var(--ink); }
        .share-btn.copied { background: oklch(0.55 0.14 145); color: #fff; border-color: oklch(0.55 0.14 145); }
        .share-label { font-family: var(--font-mono); font-size: 10px;
          letter-spacing: 0.18em; text-transform: uppercase;
          color: var(--ink-soft, #666); align-self: center;
          padding: 0 4px;
        }
      `}</style>
      <span className="share-label">Share</span>
      <button className="share-btn" onClick={shareX}        title="Share on X">𝕏  Post</button>
      <button className="share-btn" onClick={shareLinkedIn} title="Share on LinkedIn">in  LinkedIn</button>
      <button className="share-btn" onClick={shareEmail}    title="Share by email">✉  Email</button>
      <button className={`share-btn ${copied ? 'copied' : ''}`} onClick={copyLink} title="Copy link">
        {copied ? '✓ Copied' : '⎘  Copy link'}
      </button>
    </div>
  );
}

// =============================================================
// SOCIAL QUOTE BOX — pre-drafted X thread + LinkedIn post the
// reader can copy in one click. Helps the article spread by
// removing the "what would I even say?" friction.
// =============================================================
function SocialQuoteBox({ article }) {
  const posts = article.socialPosts;
  if (!posts) return null;
  const [copiedKey, setCopiedKey] = useStateI(null);

  async function copyText(text, key) {
    try {
      await navigator.clipboard.writeText(text);
      setCopiedKey(key);
      setTimeout(() => setCopiedKey(null), 1800);
    } catch (e) {
      const t = document.createElement('textarea');
      t.value = text; document.body.appendChild(t); t.select();
      try { document.execCommand('copy'); setCopiedKey(key); setTimeout(() => setCopiedKey(null), 1800); } catch (_) {}
      document.body.removeChild(t);
    }
  }

  return (
    <div className="social-quote-box">
      <style>{`
        .social-quote-box {
          margin: 32px 0 0; padding: 24px;
          background: var(--paper-2, #f4f4f0);
          border: 1px solid var(--rule-soft, #e5e5e0);
          border-radius: 10px;
        }
        .sqb-h {
          font-family: var(--font-mono); font-size: 11px;
          letter-spacing: 0.18em; text-transform: uppercase;
          color: var(--ink-soft, #666); margin: 0 0 6px;
        }
        .sqb-title {
          font-family: var(--font-serif); font-size: 22px;
          letter-spacing: -0.015em; line-height: 1.25;
          margin: 0 0 6px;
        }
        .sqb-sub { font-size: 14px; color: var(--ink-soft); margin: 0 0 18px; }
        .sqb-tabs { display: inline-flex; gap: 4px; padding: 3px;
          background: #fff; border: 1px solid var(--rule);
          border-radius: 999px; margin-bottom: 14px;
        }
        .sqb-tab {
          padding: 6px 14px; border-radius: 999px; border: none;
          background: transparent; cursor: pointer;
          font-family: var(--font-mono); font-size: 11px;
          letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-soft);
        }
        .sqb-tab.active { background: var(--ink); color: var(--paper, #fff); }
        .sqb-card {
          background: #fff; border: 1px solid var(--rule-soft, #e5e5e0);
          border-radius: 8px; padding: 16px; margin-bottom: 10px;
          position: relative;
        }
        .sqb-card-text {
          white-space: pre-wrap; font-size: 14px; line-height: 1.55;
          color: var(--ink); margin: 0 0 10px;
        }
        .sqb-card-meta {
          display: flex; justify-content: space-between; align-items: center;
          font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em;
          text-transform: uppercase; color: var(--ink-soft);
        }
        .sqb-copy {
          padding: 6px 10px; border-radius: 5px;
          background: var(--ink); color: var(--paper, #fff); border: none;
          font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em;
          text-transform: uppercase; cursor: pointer;
        }
        .sqb-copy.copied { background: oklch(0.55 0.14 145); }
      `}</style>
      <div className="sqb-h">Spread the read</div>
      <h3 className="sqb-title">Pre-drafted, copy-and-go.</h3>
      <p className="sqb-sub">
        We wrote a thread and a LinkedIn post for you. Edit before posting if you want — or click copy and paste straight in.
      </p>
      <SqbTabs posts={posts} copiedKey={copiedKey} copyText={copyText} />
    </div>
  );
}

function SqbTabs({ posts, copiedKey, copyText }) {
  const [tab, setTab] = useStateI(posts.linkedin ? 'linkedin' : 'x');
  const showX = Array.isArray(posts.xThread) && posts.xThread.length > 0;
  const showLI = !!posts.linkedin;
  return (
    <>
      <div className="sqb-tabs">
        {showLI && (
          <button className={`sqb-tab ${tab === 'linkedin' ? 'active' : ''}`} onClick={() => setTab('linkedin')}>
            LinkedIn
          </button>
        )}
        {showX && (
          <button className={`sqb-tab ${tab === 'x' ? 'active' : ''}`} onClick={() => setTab('x')}>
            X · {posts.xThread.length}-post thread
          </button>
        )}
      </div>
      {tab === 'linkedin' && showLI && (
        <div className="sqb-card">
          <p className="sqb-card-text">{posts.linkedin}</p>
          <div className="sqb-card-meta">
            <span>{posts.linkedin.length} chars</span>
            <button
              className={`sqb-copy ${copiedKey === 'li' ? 'copied' : ''}`}
              onClick={() => copyText(posts.linkedin, 'li')}>
              {copiedKey === 'li' ? '✓ Copied' : 'Copy LinkedIn post'}
            </button>
          </div>
        </div>
      )}
      {tab === 'x' && showX && posts.xThread.map((t, i) => (
        <div key={i} className="sqb-card">
          <p className="sqb-card-text">{t}</p>
          <div className="sqb-card-meta">
            <span>{i + 1} / {posts.xThread.length} · {t.length} chars</span>
            <button
              className={`sqb-copy ${copiedKey === `x${i}` ? 'copied' : ''}`}
              onClick={() => copyText(t, `x${i}`)}>
              {copiedKey === `x${i}` ? '✓ Copied' : `Copy post ${i + 1}`}
            </button>
          </div>
        </div>
      ))}
    </>
  );
}

// Article detail view — long-form reader. Used when a card is clicked.
// For articles without a `body` array we fall back to a "coming soon" stub.
function ArticleDetail({ article, onBack }) {
  const body = article.body || [];
  return (
    <div className="page-insights-v2 article-detail">
      <section className="article-detail-hero">
        <div className="article-detail-inner">
          <button className="article-back" onClick={onBack}>← Back to Insights</button>
          <div className="article-meta-row">
            <span className="insight-tag">{article.tag}</span>
            <span className="article-cat">{article.category}</span>
          </div>
          <h1 className="article-title-big">{article.title}</h1>
          {article.dek && <p className="article-dek">{article.dek}</p>}
          <div className="article-byline">
            <span className="author-dot" />
            <span><strong>{article.author}</strong>{article.authorRole ? ` · ${article.authorRole}` : ''}</span>
            <span className="dot-sep">·</span>
            <span>{article.date}</span>
            <span className="dot-sep">·</span>
            <span>{article.read || '5 min'} read</span>
          </div>
          <ShareBar article={article} />
          {article.stats && (
            <div className="article-stats-row">
              {article.stats.map((s, i) => (
                <div key={i} className="article-stat">
                  <div className="article-stat-v">{s.v}</div>
                  <div className="article-stat-l">{s.l}</div>
                </div>
              ))}
            </div>
          )}
        </div>
      </section>

      <section className="article-body">
        <div className="article-body-inner">
          {body.length === 0 ? (
            <div className="article-stub">
              <p>This piece is part of our launch slate. The full investigation publishes within 24 hours — subscribe to your metro's Pulse from the homepage to get it the moment it lands.</p>
              <button className="btn-primary" onClick={onBack}>Back to insights</button>
            </div>
          ) : (
            body.map((block, i) => {
              if (block.kind === "h2") return <h2 key={i} className="article-h2">{block.text}</h2>;
              if (block.kind === "h3") return <h3 key={i} className="article-h3">{block.text}</h3>;
              if (block.kind === "lede") return <p key={i} className="article-lede">{block.text}</p>;
              if (block.kind === "pull") return <blockquote key={i} className="article-pull">{block.text}</blockquote>;
              if (block.kind === "list") return (
                <ul key={i} className="article-list" style={{
                  margin: "0 0 1.4em", paddingLeft: 22, listStyle: "disc",
                  fontSize: 17, lineHeight: 1.7, color: "var(--ink)",
                }}>
                  {(block.items || []).map((it, j) => (
                    <li key={j} style={{ marginBottom: 8 }}>{it}</li>
                  ))}
                </ul>
              );
              return <p key={i} className="article-p">{block.text}</p>;
            })
          )}

          <SocialQuoteBox article={article} />

          <div className="article-footer">
            <ArticleFooterCta article={article} onBack={onBack} />
          </div>
        </div>
      </section>
    </div>
  );
}

// Article-specific CTA. Carrier investigations like Hub Group set
// `article.footerCta` to surface the $500 Deep-Dive Report — the natural
// conversion from a "we caught it three weeks early" piece. Articles
// without their own CTA fall back to the generic Pulse subscription pitch.
function ArticleFooterCta({ article, onBack }) {
  const f = article.footerCta;
  function handle(target) {
    if (!target) return;
    if (target.startsWith('mailto:')) { window.location.href = target; return; }
    window.location.hash = `#/${target}`;
  }
  if (!f) {
    return (
      <div className="article-cta">
        <h3>Want this kind of analysis daily, by metro?</h3>
        <p>Subscribe to your city's Pulse from the homepage. Free, no paywall.</p>
        <button className="btn-primary" onClick={onBack}>← More from Shipping Clarity</button>
      </div>
    );
  }
  return (
    <div className="article-cta">
      <h3>{f.h3}</h3>
      <p>{f.p}</p>
      <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginTop: 12 }}>
        <button className="btn-primary" onClick={() => handle(f.primaryTarget)}>
          {f.primaryCta}
        </button>
        {f.secondaryCta && (
          <button className="btn-ghost" onClick={() => handle(f.secondaryTarget)}>
            {f.secondaryCta}
          </button>
        )}
      </div>
    </div>
  );
}

window.InsightsPage = InsightsPage;
