/* ===========================================================
   SAGD Atlas — token system
   Subject: SAGD/CSS thermal recovery, night satellite operations,
   Dominion Land Survey coordinate notation, regulatory filings.
   Palette = thermal instrument panel: cold blue-black chrome,
   ember heat-glow accent (these ARE literally steam operations).
   =========================================================== */

@import url('vendor/fonts.css');

:root{
  /* 2026-09-17 PALETTE (Phil: "I really dont like our web color scheme. the orange, the dark
     blue, etc. lets switch to a dark red and then use baby blue or turquoise-ish in place of
     the orange"): ground = oxblood family, accent = turquoise. --ember keeps its NAME (86 CSS
     sites, every chip/toggle/rank/warning reads it) but is now the turquoise accent. The
     bitumen chart series gets its own token (--bitumen, amber) so the data colour no longer
     rides the UI accent -- turquoise bitumen next to steam-blue would not separate. */
  /* 2026-09-28 (Phil: "I like Navy, if its allowed. dont like purple."): the ground moves off
     oxblood to navy. Allowed on both tests that decided the shortlist -- Cenovus's slate holds
     2.18:1 against the card (it dissolves below ~1.6) and CNRL's white box 16.8:1. Navy also
     clears every operator hue, so nothing on the ground can collide with a data colour. */
  --ink:      #0b1224;
  /* ROUND 2 #3 (Foster Creek review): the four AREA tones -- tints of the Cenovus slate (#365860, toward #dde5e8 by 0 / .28
     / .57 / .85), no new hue. Defined here only: app.js areaTone() reads them for the map's pad fills, the areas row, the
     chart's bands and the trail's area circle. */
  --area-west:    #365860;
  --area-north:   #657f86;
  --area-east:    #95a8ae;
  --area-central: #c4d0d4;
  --steel:    #121c37;
  --steel-2:  #182444;
  --hair:     #26355e;
  /* 2026-09-28 (Phil): the accent moves from turquoise to neon green. Turquoise sat 11 degrees of hue
     from Cardinal and 8 from Cenovus, so the Atlas's own voice kept colliding with an operator's
     colour; the green at hue 93 is in the one empty wedge and clears every operator by 29 degrees.
     This is the accent everywhere -- wordmark, Map/Board pill, chips, and the frame edge. */
  /* THE BAR (2026-09-30, Phil picked white from three mockup rounds): the accent is FROST WHITE everywhere; the neon green is
     retired. Same token name (every accent job reads it); the lower joins' grey is --ember-2. */
  --ember:    #e7eef3;
  /* COLOUR brief (2026-09-29): ONE accent hue, two tones, each pinned to its ground. --ember is for DARK grounds only;
     on a light surface (the wordmark pill, any white box) the accent is --ember-ink: the same hue (93°), darkened to
     5.45:1 on white and 4.58:1 on the pill over dark imagery (#ebebeb). Text ON a neon fill is --ink, never white. */
  --ember-ink: #0b1224; /* THE BAR: on a light surface the accent is ink */
  /* washes come from the accent by token, never a literal: hover / selected / pressed */
  --ember-wash-1: rgba(231,238,243,.06);
  --ember-wash-2: rgba(231,238,243,.14);
  --ember-wash-3: rgba(231,238,243,.22);
  --ember-2: #8fa6b3; /* THE BAR: the lower joins are light grey (--core), the top join white */
  --ember-dim:#b3c2cb;
  --ember-glow: rgba(231,238,243,.5);
  --bitumen:  #f2b134;
  --bitumen-wash: rgba(242,177,52,.12);
  /* steam: the palette's other literal element -- cold chrome-blue against
     ember's heat-glow. Validated vs ember (scripts/validate_palette.js
     --mode dark): CVD sep. + normal-vision + contrast all PASS with wide
     margin (>=ΔE 22, target is 8). The one FAIL is "lightness band", which
     flags ember itself (L 0.725, above the categorical 0.48-0.67 ceiling)
     -- ember is this app's pre-existing single-identity accent, not a
     fresh categorical pick, so that check doesn't apply to it here; the
     checks that actually protect legibility (can you tell the two series
     apart) pass clean. */
  --steam:    #4fa8e0;
  /* netpay: sea-green, the literal NETPAY_HUE app.js paints the computed
     net-pay + operator paymap bands with (rgb(46,139,87) == #2e8b57 --
     same constant, not a separate pick) -- added Batch B2 to fix
     .about-map-swatch-wash, which had been reusing --steam (the AGS
     gross-thickness geology layer's OWN blue) even though the row's own
     text calls it "Blue wash" describing a layer that actually renders
     sea-green on the map -- a real color-name mismatch in the one
     surviving always-visible legend surface (SPEC-v27 E2b removed the
     old #netpay-legend drawer widget; this About-map row is what a user
     actually sees today). */
  --netpay:   #2e8b57;
  --frost:    #e7eef3;
  /* cSOR: a fresh hue since iSOR already uses frost (the app's neutral
     ink tone, deliberate -- reads as "the reported/baseline metric").
     Validated vs frost: CVD sep. + normal-vision + contrast all PASS,
     wide margin (ΔE 29-31, target 8); same lightness-band exception as
     steam applies (frost's own lightness sits outside the categorical
     band, same pre-existing-accent logic). */
  --csor:     #a878d8;
  --core:     #8fa6b3;
  --core-dim: #5c7280;
  --good:     #3ddc97;
  /* Market layer (Leg D, 2026-07-23): WTI/WCS on the board's "Market"
     section. Validated as a fresh categorical pair (scripts/
     validate_palette.js --mode dark): lightness band, chroma floor, CVD
     separation, normal-vision floor, and contrast-vs-surface all PASS
     (worst-case ΔE 17.4 protan / 22.3 tritan / 21.7 normal, well above
     the ΔE 8 target) -- unlike reusing frost/csor here, which the
     validator correctly fails as a FRESH categorical pick (that pair's
     existing pass is a grandfathered exception for the SOR strip only,
     documented above; a new context needs its own check). Amber/gold for
     WTI (the world benchmark), cool teal-blue for WCS (Alberta's
     discounted price) -- warm/cool split, distinct from ember/steam.  */
  --wti:      #bd8330;
  --wcs:      #1f9ab5;

  /* Pipelines layer (ROADMAP #1, UI leg, 2026-07-24): substance-class line
     colors on the map -- oil/steam/water/gas/other. Validated as a FRESH
     categorical 5-set (scripts/validate_palette.js --mode dark --surface
     "#0a0f16" --pairs all -- "all", not "adjacent", since these render as
     overlapping lines on a map, the validator's own scatter/map guidance):
       node validate_palette.js "#bd0c45,#9137a3,#31a8ac,#9a9900,#7580ff" \
         --mode dark --surface "#0a0f16" --pairs all
       -> ALL CHECKS PASS: lightness band all 5 inside L 0.48-0.67; chroma
          floor all 5 >=0.10; CVD separation worst all-pairs ΔE 15.9
          (protan, steam<->oil) -- well clear of the ΔE 8 target, no WARN;
          normal-vision floor worst ΔE 16.9 (>=15 floor); contrast vs
          #0a0f16 all >=3:1. Hues chosen distinct from --steam/--ember on
          purpose -- both already claimed by the production chart's own
          series, reusing them here would blur "this is a pipeline
          substance" with "this is a chart series" across two different
          views of the same app. */
  --pipe-oil:   #bd0c45;
  --pipe-steam: #9137a3;
  --pipe-water: #31a8ac;
  --pipe-gas:   #9a9900;
  --pipe-other: #7580ff;

  /* SPEC-v19 (Run 49, flow map): the basin-zoom flow layer's own 2-color
     commodity family set -- crude/dilbit (outbound) vs diluent/NGL
     (inbound), see app.js's FLOW_COLOR_MATCH (the literal-hex source of
     truth maplibre paint expressions need; these vars exist so the
     drawer's legend swatches + hub markers below can match it exactly).
     Deliberately its own muted/low-chroma pair, NOT the vivid --pipe-oil
     above (that's the project-zoom 5-class substance palette, a different
     question) and NOT any OPERATOR_COLORS hue -- SPEC-v19 B1/B2: operator
     circles must stay the loudest thing on the map, so this pair is
     picked quiet and warm(crude)/cool(diluent) on purpose. Hand-picked,
     NOT re-run through validate_palette.js (not present in this
     environment) -- said plainly here rather than claiming an unrun check. */
  --flow-crude:   #7a3f1d; /* 2026-09-19 palette: pipelines off the river blue */
  --flow-diluent: #5b4bc4;
  --flow-liquids: #8c8378;
  /* 2026-09-28 FUEL GAS PROOF: the gas data-series token (app.js GAS_COLOR is the literal the map
     paint needs). Hue 127 in the green wedge: 34 deg from the accent (93), 31 deg from Strathcona (158);
     Appendix 1 hue test run 2026-09-28 and recomputed in regression.js. Not --pipe-gas (a pipe substance). */
  --gas: #4cc85a; /* FUEL GAS (2026-09-28): natural gas -- NGTL, the fuel-gas feed lines, the steam-plant squares, the fuel KPI; hue-tested >= 20° from every operator and the accent */

  /* Run 30-B (SPEC-v11 B1): one clean humanist sans everywhere -- Phil:
     "i hate the fonts. hate hate hate. i use barlow, aptos, fonts like
     that. use some standard default fonts and not this garbage." Barlow
     self-hosted (vendor/fonts/, SIL OFL, CSP/offline-safe) replaced Big
     Shoulders Display / Source Serif 4 / IBM Plex Mono entirely -- all
     three tokens point at the same stack (kept as 3 tokens, not
     collapsed to 1, only so every existing var(--display)/var(--serif)/
     var(--mono) call site across styles.css keeps working unchanged).

     SPEC-v32 Batch B (2026-07-30): Barlow -> Inter, Phil: "i hate the
     fonts we picked. lets switch them all up. stay sans serif." Same
     self-hosted/CSP-safe discipline, same 3-token indirection. Inter's
     tabular figures are the actual reason it was picked over Barlow --
     see font-variant-numeric:tabular-nums on every stat/KPI/table
     surface (.stat-value, .popup-kpi-value, .board-hero-value, board/
     compare/entity/pad/picker tables, etc). If Phil vetoes on sight:
     staged alternates are IBM Plex Sans and Figtree, single-var swap. */
  --display: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --serif:   'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono:    'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
}

*{ box-sizing:border-box; }
html,body{ height:100%; margin:0; }
body{
  background:var(--ink); color:var(--frost);
  font-family:var(--serif); font-size:15px; line-height:1.5;
  overflow:hidden;
}
::selection{ background:var(--ember); color:var(--ink); }
:focus-visible{ outline:2px solid var(--ember); outline-offset:2px; }

/* ---- app shell ---- */
/* HARDENING (2026-07-24, Run 7 Leg 2c): `overflow-x:hidden` here, not on
   any inner scroll container -- #panel's own established slide-in
   mechanic (`transform:translateX(100%)` when closed, see #panel below)
   sits its CLOSED box fully outside #app's visible bounds by design, but
   several engines still count a transformed element's geometry toward an
   unclipped ancestor's scrollable overflow -- caught live at 375px
   (documentElement.scrollWidth 750 = exactly double the viewport, i.e.
   the closed panel's own width added on) while checking this leg's
   required "no horizontal overflow at 375px" bar, on the Board view
   specifically (panel exists in the DOM, closed, behind the board table).
   Every inner scrollable region (#board-scroll, #panel-scroll,
   #compare-scroll, the modal body) keeps its OWN overflow:auto/overflow-y
   untouched -- this only clips at the outermost boundary, the standard
   fix for this exact off-screen-transform class of bug. */
#app{ position:relative; width:100vw; height:100vh; overflow-x:hidden; }
#map{ position:absolute; inset:0; }
/* SPEC-v17 B1: top padding cleared 112px, not the old masthead-tuned 78px
   -- #nav-cluster (wordmark chip + bubble row) floats at top:16px and
   stands ~86px tall, same on every viewport width (it's a fixed-size
   cluster, not text that wraps), so one value now works at both desktop
   and mobile -- no separate mobile override needed. */
#board{ position:absolute; inset:0; background:var(--ink); overflow:auto; -webkit-overflow-scrolling:touch; padding:112px 22px 90px; }

/* ---- SPEC-v17 B1/B2: floating nav -- wordmark chip + 3 bubbles ----
   Replaces #masthead/#view-toggle/#filterbar entirely. This is the chrome
   that FLOATS on the map (A3's own rule), so it's the opposite register
   from the app's dark panels/cards: white/light chip, dark icon+text,
   subtle shadow -- reads cleanly on the new light-gray canvas AND still
   reads fine over the Board/Compare views' dark background (it's always
   present, not map-only). */
#nav-cluster{
  position:absolute; top:16px; left:16px; z-index:20;
  display:flex; flex-direction:column; align-items:flex-start; gap:10px;
}
/* Run 48 verify catch (2026-07-27): on mobile the panel is a full-screen
   takeover, and the floating nav cluster was painting ON TOP of the open
   card's header (bubbles over the operator logo). SPEC-v27 C (Run 71):
   the panel is now a bottom SHEET with PEEK/HALF/FULL detents -- nav stays
   reachable (search/menu) at PEEK/HALF, since the map is meant to read as
   live underneath the sheet at those heights (B1's own reveal
   choreography). Only FULL (the old near-full-screen behavior) still
   yields the nav -- the sheet's own ✕ is the exit there. */
@media (max-width: 720px){
  body:has(#panel[data-detent="full"].open) #nav-cluster{ display:none; }
}
#wordmark-chip{
  display:inline-flex; align-items:center;
  background:rgba(255,255,255,.92); border:1px solid rgba(30,10,14,.1);
  border-radius:14px; padding:7px 13px; text-decoration:none;
  box-shadow:0 2px 10px rgba(30,10,14,.18);
  backdrop-filter:blur(6px);
}
.wordmark-text{
  font-family:var(--display); font-weight:800; font-size:12.5px;
  letter-spacing:.12em; text-transform:uppercase; color:#1f0b0f;
}
.wordmark-text span{ color:var(--ember-ink); } /* COLOUR: the pill is a light surface */
#bubble-row{ display:flex; gap:8px; }
/* hidden attr must win over the flex display (H2 retired bubbles) */
.bubble[hidden]{ display:none !important; }
.bubble{
  position:relative; width:44px; height:44px; border-radius:50%;
  background:rgba(255,255,255,.92); border:1px solid rgba(30,10,14,.1);
  box-shadow:0 2px 10px rgba(30,10,14,.18);
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  padding:0; backdrop-filter:blur(6px);
  transition:transform .12s ease, box-shadow .12s ease;
}
.bubble:hover{ transform:translateY(-1px); box-shadow:0 4px 14px rgba(30,10,14,.24); }
.bubble svg{
  width:20px; height:20px; fill:none; stroke:#1f0b0f; stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round;
}
.bubble.active svg{ stroke:var(--ember-dim); }
.bubble.active{ border-color:var(--ember-dim); }
/* Map/Board bubble carries two stacked icons, CSS-swapped by which
   destination a tap leads to (applyView toggles .show-board-icon). */



/* THE BAR (2026-09-30): the way back to the map from every non-map view -- a drag handle, top centre */
.view-handle{ position:fixed; top:10px; left:50%; transform:translateX(-50%); z-index:95; width:72px; height:28px; border:none;
  background:transparent; display:flex; align-items:center; justify-content:center; cursor:pointer; padding:0; }
.view-handle span{ display:block; width:44px; height:5px; border-radius:3px; background:var(--core); }
.view-handle:hover span, .view-handle:focus-visible span{ background:var(--ember); }
.view-handle[hidden]{ display:none; }

/* ---- board view: the leaderboard ---- */
#board-scroll{ max-width:1100px; margin:0 auto; }

/* ---- "+ compare" toggle -- SPEC-v11 Run B, B3: well+pad-scoped only now
   (pad rows, well-drilldown rows). No longer used on board rows or the
   scheme panel header. ---- */
.compare-toggle-btn{
  background:transparent; border:1px solid var(--hair); color:var(--core-dim);
  font-family:var(--mono); font-size:9.5px; text-transform:uppercase; letter-spacing:.03em;
  padding:4px 8px; border-radius:2px; cursor:pointer; white-space:nowrap;
}
.compare-toggle-btn:hover{ color:var(--frost); border-color:var(--core-dim); }
.compare-toggle-btn.active{ color:var(--ember); border-color:var(--ember-dim); background:var(--ember-wash-2); }
/* RUN 19 (2026-07-24, full logo system): the one shared chip both real
   logos and the one remaining monogram fallback render through (app.js's
   logoChip()). Phil's directive verbatim: "the background is gone and it
   layers nicely" -- every sourced mark this leg is transparent AND already
   dark-UI-legible on its own (verified per-operator, see app.js's own
   OPERATOR_LOGO comment for the sourcing/dark-treatment table), so the
   light backing box Run 11/13 used as a blanket crutch is gone. A real
   <img> sits directly on whatever surface it's placed on -- no border, no
   fill, no radius, just a sized box so layout doesn't jump between a wide
   wordmark and a square icon mark. The ONE remaining monogram (Northern
   Hawk) still needs a self-contained color+radius, since unlike a real
   logo it has no art of its own to layer -- kept as its own override. */
.logo-chip{
  display:inline-flex; align-items:center; justify-content:center;
  flex-shrink:0; vertical-align:middle; overflow:hidden;
}
/* Real logos: fixed HEIGHT only (set inline per call site), width flows
   from the mark's own aspect ratio up to the span's own max-width (also
   inline) -- object-fit:contain on top so a mark that WOULD overflow either
   bound shrinks proportionally instead of clipping or distorting. */
.logo-chip img{ max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain; display:block; }
.logo-chip.monogram{
  border-radius:6px; background:var(--mono-bg, #8fa6b3);
  color:#fff; font-family:var(--mono); font-weight:700; font-size:9px;
  letter-spacing:.01em;
}

/* ---- compare view ---- */
/* SPEC-v17 B1: same 112px top-clear as #board above, one value at every
   width -- see that rule's own comment. */
#compare{ position:absolute; inset:0; background:var(--ink); overflow:auto; -webkit-overflow-scrolling:touch; padding:112px 22px 90px; }
#compare-scroll{ max-width:1100px; margin:0 auto; }
#compare-empty{
  font-family:var(--mono); font-size:12px; color:var(--core-dim); text-align:center;
  padding:60px 20px; line-height:1.7;
}
/* SPEC-v17 B4: 3 entry cards replace the old paragraph-of-instructions
   empty state -- each one tap into the existing picker (wireCompareIntroCards,
   app.js). Dark cards, same register as the rest of Compare's own chrome
   (A3: panels/cards may stay dark). */
.compare-intro-lead{
  font-family:var(--display); font-weight:700; font-size:17px;
  letter-spacing:.01em; color:var(--frost); margin-bottom:22px;
}
.compare-intro-cards{
  display:grid; grid-template-columns:repeat(3, minmax(150px, 1fr)); gap:12px;
  max-width:640px; margin:0 auto 22px;
}
.compare-intro-card{
  background:var(--steel-2); border:1px solid var(--hair); border-radius:6px;
  padding:18px 14px; cursor:pointer; text-align:left;
  transition:border-color .15s ease, transform .15s ease;
}
.compare-intro-card:hover{ border-color:var(--ember-dim); transform:translateY(-2px); }
.cic-title{
  font-family:var(--display); font-weight:700; font-size:14px; line-height:1.25;
  color:var(--frost); margin-bottom:6px;
}
.cic-sub{ font-family:var(--mono); font-size:10.5px; color:var(--core-dim); line-height:1.4; }
@media (max-width:640px){
  .compare-intro-cards{ grid-template-columns:1fr; max-width:320px; }
}
#compare-toolbar{ display:flex; align-items:center; gap:10px 14px; margin-bottom:14px; flex-wrap:wrap; }
#compare-view-toggle, #compare-metric-toggle, #compare-time-toggle, .benchmark-metric-toggle{ display:flex; gap:6px; flex-wrap:wrap; }
/* SPEC-v7 D2: same trap this codebase has hit before (#legend, #panel-empty)
   -- an ID selector's unconditional `display:flex` above beats the UA
   `[hidden]{display:none}` rule's lower specificity, so setting .hidden=true
   on the metric/time toggles (done when switching to the Table sub-view,
   which has neither) silently failed to actually hide them. Caught live via
   a 375px screenshot, not by reading the code. */
#compare-metric-toggle[hidden], #compare-time-toggle[hidden]{ display:none; }
/* PLAN 4 item A6: one row of small pills (it scrolls sideways inside itself before it ever wraps), the axis row under it
   only on a metric chart, Add / Download as two small buttons at the end of the legend */
#compare-toolbar{ flex-direction:column; align-items:stretch; gap:8px; margin-bottom:10px; }
#compare-toolbar .cmp-pills{ display:flex; gap:4px; flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; -webkit-overflow-scrolling:touch; }
#compare-toolbar .cmp-pills::-webkit-scrollbar{ display:none; }
#compare-toolbar #compare-metric-toggle, #compare-toolbar #compare-view-toggle{ flex-wrap:nowrap; gap:4px; flex:none; }
#compare-toolbar #compare-view-toggle{ padding-left:6px; margin-left:2px; border-left:1px solid var(--hair); }
#compare-toolbar .chart-toggle, #compare-chart-wrap .benchmark-metric-toggle .chart-toggle{ min-height:30px; min-width:0; padding:5px 8px; font-size:10.5px; white-space:nowrap; display:inline-flex; align-items:center; }
.cmp-tools{ display:inline-flex; gap:4px; margin-left:auto; flex:none; }
#compare-toolbar > .cmp-tools{ display:none; } /* parked between renders */
.cmp-tool{ background:transparent; border:1px solid var(--hair); color:var(--core); border-radius:999px; font:600 10.5px/1 var(--display, system-ui);
  padding:6px 9px; min-height:26px; cursor:pointer; white-space:nowrap; }
.cmp-tool:hover, .cmp-tool:focus-visible{ color:var(--frost); border-color:var(--frost); outline:none; }
.compare-legend .cmp-tools, .benchmark-legend .cmp-tools{ margin-left:auto; }
.entity-table-toolbar .cmp-tools{ margin-left:8px; }
#compare-chart-wrap > .cmp-tools{ display:flex; justify-content:flex-end; margin:0 0 8px; }
/* ---- v6 S4(b): benchmark scatter ---- */
.benchmark-dot{ fill:var(--core-dim); opacity:.5; cursor:pointer; }
.benchmark-dot:hover{ opacity:.9; }
.benchmark-dot.in-basket{ opacity:1; stroke:var(--ink); stroke-width:1.5; }
.compare-overflow-note{ font-family:var(--mono); font-size:9.5px; color:var(--core-dim); margin:6px 0; }
#compare-chart-wrap{ margin-bottom:22px; }
#compare-hitarea{ cursor:crosshair; touch-action:none; }
.compare-dot-cell{ width:14px; }
.compare-dot{ display:inline-block; width:8px; height:8px; border-radius:50%; }
.compare-label{ color:var(--frost); font-weight:500; }
/* ROADMAP #4 (day run 2026-07-24): compare -> map linkage. Styled to read
   as the same plain label text it replaced (not an obvious button) --
   the hover/focus underline is the only affordance, consistent with how
   little this app decorates in-place text triggers elsewhere. */
.compare-flyto{
  background:none; border:none; padding:0; margin:0; cursor:pointer;
  color:inherit; font:inherit; font-weight:500; text-align:left;
}
.compare-flyto:hover, .compare-flyto:focus-visible{ color:var(--ember); text-decoration:underline; }
.compare-kind{ display:inline-block; margin-left:8px; font-size:9px; text-transform:uppercase; color:var(--core-dim); font-weight:400; letter-spacing:.04em; }
.compare-remove-cell{ width:30px; }
.compare-remove{
  background:transparent; border:1px solid var(--hair); color:var(--core-dim);
  width:22px; height:22px; border-radius:2px; cursor:pointer; font-size:12px;
}
.compare-remove:hover{ color:var(--ember); border-color:var(--ember-dim); }
.compare-legend{ margin-bottom:6px; }
/* PLAN 4 item A4: the legend is a dot + the shortest name; the anchor key behind an (i), a row's anchor on its tap */
.compare-legend{ align-items:center; }
.compare-legend .cmp-leg-tap{ cursor:pointer; }
.compare-legend .cmp-leg-tap:focus-visible{ outline:1px solid var(--frost); outline-offset:2px; }
.cmp-i{ flex:none; width:20px; height:20px; border-radius:50%; border:1px solid var(--line, var(--hair)); background:transparent; color:var(--core);
  font:italic 700 11px/1 var(--serif, Georgia, serif); padding:0; cursor:pointer; }
.cmp-i[aria-expanded="true"], .cmp-i:hover, .cmp-i:focus-visible{ color:var(--frost); border-color:var(--frost); outline:none; }
.cmp-note{ font-size:11px; line-height:1.45; color:var(--core); margin:0 0 8px; max-width:62ch; }

/* ---- SPEC-v7 D2: entity table (Compare's third sub-view) -- columns are
   basket entities, rows grouped Identity/KPI/Facility/Network/Hazards.
   Sticky left row-label column + its own overflow-x wrapper is ALWAYS on
   (not just <=640px) -- a 5-entity table routinely exceeds even a desktop
   viewport, and the mobile acceptance check is the same mechanism, just a
   narrower one. ---- */
#compare-entity-table-wrap{ margin-bottom:18px; }
.entity-table-toolbar{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; flex-wrap:wrap; }
.entity-table-meta{ font-family:var(--mono); font-size:9.5px; color:var(--core-dim); }
.entity-cell.empty{ color:var(--core-dim); font-style:italic; }
.entity-cell.na{ color:var(--core-dim); }
.entity-cell-note{ font-size:9.5px; }
.entity-cell.has-evidence{ cursor:pointer; }
.entity-cell.has-evidence:hover{ background:var(--ember-wash-1); }
/* Run 9: all-pad/all-well basket (no scheme column) -- Facility/Network
   collapse to this one spanning note instead of 17 "-- (scheme-level)"
   dash rows (see logic.js buildEntityTableModel, facilityNetworkNote). */
.entity-note-cell{ text-align:center; color:var(--core-dim); font-style:italic; padding:9px 12px; }

/* SPEC-v28 item 6: the evidence tray (.evidence-tray/.tray-*, SPEC-v7 D3
   fact cards) is killed along with fact-token support in Compare. */

/* SPEC-v11 Run B, B3: the old "little box beside any data" collect
   affordance (SPEC-v7 D4) is gone entirely -- compare/collect is
   well+pad-scoped only now (.compare-toggle-btn, pad rows + well-
   drilldown rows only). */
.coverage-hazard-list{ margin-bottom:10px; }
.coverage-hazard-row{
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:5px 0; border-bottom:1px solid var(--hair); font-family:var(--mono);
}
.coverage-hazard-row:last-child{ border-bottom:none; }
.coverage-hazard-type{ font-size:10.5px; color:var(--core); }

/* ---- transient bottom-center note (e.g. the compare-cap "remove one
   first" block) -- a blocked action must never look like a silent no-op. */
.app-note{
  position:fixed; left:50%; bottom:24px; transform:translate(-50%, 12px);
  background:var(--steel); border:1px solid var(--ember-dim); color:var(--frost);
  font-family:var(--mono); font-size:11.5px; padding:9px 16px; border-radius:3px;
  box-shadow:0 8px 24px rgba(0,0,0,.5); z-index:90; max-width:min(90vw, 420px);
  text-align:center; opacity:0; pointer-events:none; transition:opacity .2s ease, transform .2s ease;
}
.app-note.show{ opacity:1; transform:translate(-50%, 0); }

/* ---- SPEC-v7 D4: every basket add pulses the header chip. ---- */

/* ---- SPEC-v17 A2/B2: basemap switch (bottom-right, icon-sized) + the ☰
   drawer. The old #legend box (Brighten/Geology toggles + commodity/counts
   legend) is GONE entirely -- see app.js's own comment where refreshPipelinesUI
   drops the legend render call. #about-link now lives inside the drawer
   (still the exact same element/id, About page checks are unaffected). ---- */
#basemap-switch{
  position:absolute; right:16px; bottom:96px; z-index:6;
  width:40px; height:40px; border-radius:50%;
  background:rgba(255,255,255,.92); border:1px solid rgba(30,10,14,.1);
  box-shadow:0 2px 10px rgba(30,10,14,.18); backdrop-filter:blur(6px);
  display:flex; align-items:center; justify-content:center; cursor:pointer; padding:0;
}
#basemap-switch svg{ width:19px; height:19px; fill:none; stroke:#1f0b0f; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
#basemap-switch[hidden]{ display:none; }
/* Two icons stacked, CSS-swapped by mode: default shows "switch to
   imagery" (a grid/photo glyph); once imagery is live, shows "switch back
   to canvas" (a stacked-layers glyph) so the icon always previews the tap. */
#basemap-switch .bs-icon-canvas{ display:none; }
#basemap-switch.is-imagery .bs-icon-sat{ display:none; }
#basemap-switch.is-imagery .bs-icon-canvas{ display:block; }

/* SPEC-v24 A2 (Run 58): the paymap attribution chip -- bottom-left, the
   corner SPEC-v23 D freed up when the timeline chip/slider were deleted
   (confirmed bare on every retina screenshot since). Floats directly on
   the map canvas (not tucked in the ☰ drawer like the geology/flow
   legends) because A1's own render trigger is "card open / popup step" --
   on the touch tap-1 preview step the map is still the majority of the
   screen (the full #panel only covers it once the card itself opens), so
   this is the one place the chip and the dashed outline are legible
   together, same reasoning the retina gate's own mobile check relies on.
   Per-scheme conditional (refreshPaymapUI toggles [hidden]) -- NOT a
   basin-wide always-on box, so this doesn't reintroduce the old always-on
   #legend SPEC-v17 A2 removed. */
#paymap-chip{
  position:absolute; left:16px; bottom:16px; z-index:6;
  max-width:min(260px, calc(100vw - 32px));
  background:rgba(255,255,255,.94); border:1px solid rgba(30,10,14,.12);
  border-radius:8px; padding:8px 10px;
  box-shadow:0 2px 10px rgba(30,10,14,.16); backdrop-filter:blur(6px);
  font-family:var(--serif); color:#1f0b0f;
}
#paymap-chip[hidden]{ display:none; }
/* SPEC-v31 (Run 72): recolored from goldenrod rgb(138,100,8) to the same
   dark sea-green (NETPAY_LINE_HUE in app.js) the map's paymap-line/-contour
   layers now use -- style unification isn't just the map canvas, this DOM
   chip is the same "operator-filed" identity, same hue everywhere. */
.paymap-chip-cutoff{
  font-family:var(--mono); font-weight:700; font-size:11px; letter-spacing:.01em;
  color:rgb(25,84,52); margin-bottom:3px;
}
.paymap-chip-attribution{ font-size:10px; line-height:1.4; color:#425364; }
.paymap-chip-attribution a{ color:rgb(25,84,52); }

#drawer-overlay{
  position:fixed; inset:0; z-index:79; background:rgba(11,18,36,.45); /* LENS stage 4: above the landing sheet (60) */
  opacity:0; transition:opacity .2s ease;
}
#drawer-overlay[hidden]{ display:none; }
/* app.js clears [hidden] on both the drawer and the overlay in the same
   tick, then adds .open a frame later so the transform+opacity animate
   together. */
#drawer-overlay:not([hidden]){ opacity:1; }
#drawer{
  position:fixed; top:0; left:0; bottom:0; z-index:80;
  width:min(340px, 88vw); background:var(--steel); border-right:1px solid var(--hair);
  box-shadow:24px 0 48px rgba(0,0,0,.4);
  transform:translateX(-100%); transition:transform .24s cubic-bezier(.2,.8,.2,1);
  display:flex; flex-direction:column;
}
#drawer.open{ transform:translateX(0); }
#drawer[hidden]{ display:none; }
#drawer-header{
  display:flex; align-items:center; justify-content:space-between;
  padding:16px 16px 12px; border-bottom:1px solid var(--hair); flex-shrink:0;
}
.drawer-title{
  font-family:var(--display); font-weight:700; font-size:13px;
  letter-spacing:.08em; text-transform:uppercase; color:var(--frost);
}
#drawer-close{
  width:28px; height:28px; border-radius:2px; background:transparent;
  border:1px solid var(--hair); color:var(--core); cursor:pointer; font-size:14px;
}
#drawer-close:hover{ border-color:var(--ember); color:var(--ember); }
#drawer-scroll{ overflow-y:auto; -webkit-overflow-scrolling:touch; padding:16px; }
.drawer-section{ margin-bottom:18px; }
.drawer-section:last-of-type{ margin-bottom:10px; }
.drawer-label{
  font-family:var(--mono); font-size:10px; color:var(--core-dim);
  text-transform:uppercase; letter-spacing:.07em; margin-bottom:8px;
}
.drawer-credit{
  font-family:var(--mono); font-size:9.5px; color:var(--core-dim);
  padding-top:10px; border-top:1px solid var(--hair);
}
/* SPEC-v27 E2c: "About this map" -- one clean static section, plain words,
   <=1 screen, replacing the killed layer-toggle section. Small swatch dots
   before each line so the words map visually to what's actually on the
   canvas, without needing a second interactive legend anywhere. */
.about-map-body p{
  font-size:11.5px; line-height:1.5; color:var(--core); margin:0 0 9px;
  display:flex; align-items:flex-start; gap:6px;
}
.about-map-body p:last-child{ margin-bottom:0; }
.about-map-swatch{
  display:inline-block; width:10px; height:10px; border-radius:50%;
  flex-shrink:0; margin-top:3px; background:var(--core-dim);
}
.about-map-swatch-circle{ background:var(--ember); border-radius:50%; }
.about-map-swatch-wash{ background:var(--netpay); border-radius:3px; opacity:.7; }
/* Run 75 added .about-map-swatch-sk-wash (violet/plum) for the SK Mannville
   GROUP-thickness wash; WITHDRAWN Run 77 along with the layer itself
   (misread-as-net-pay risk, Phil's call) -- rule removed, resurrection copy
   in ~/brain/projects/deck-mining.md, Run 77 log entry. */
/* SPEC-v32 A1: matches the map's own money-shot drainage-box paint --
   darker --ember-dim border, solid-feel fill, not the old near-invisible
   background:none/faint-border swatch. */
.about-map-swatch-box{ background:var(--ember-wash-2); border:1.5px solid var(--ember-dim); border-radius:2px; }
/* Batch I: First Nations reserve lands -- same warm-tan wash + hairline
   boundary the map's own reserves-fill/reserves-boundary layers paint. */
.about-map-swatch-reserve{ background:rgba(183,156,116,.35); border:1px solid rgba(160,132,92,.6); border-radius:3px; }
.about-map-swatch-line{ background:var(--ember); height:2px; width:12px; border-radius:1px; margin-top:7px; }
.about-map-note{ font-style:italic; color:var(--core-dim); }
.about-map-note a{ color:var(--core-dim); }
/* the drawer's own #province-toggle/#pipelines-row/#cer-row reuse
   .chart-toggle-group/.full-toggle's existing dark-theme styling as-is. */
.row{ display:flex; align-items:center; gap:8px; }
.row[hidden]{ display:none; }
#drawer .chart-toggle-group{ margin-top:10px; }
/* SPEC-v32 Batch D: the unit toggle's one-line honesty note -- AER files
   m3, bbl is computed; quiet, recessive, linked to the FAQ's full entry. */
#drawer .unit-note{ margin-top:8px; font-size:10.5px; line-height:1.5; color:var(--core-dim); }
#drawer .unit-note a{ color:var(--core); }
#drawer .row + .row{ margin-top:6px; }
/* LEG 2f: Google Maps deep-link -- a small ember-accent link, same visual
   register as .compare-toggle-btn's understated affordance, used in the
   marker popup, the pad identity card, and pad table rows. */
.gmaps-link{
  color:var(--ember); font-family:var(--mono); font-size:10px;
  text-decoration:none; white-space:nowrap;
}
.gmaps-link:hover{ text-decoration:underline; }
.ctt-gmaps{ display:inline-block; margin-top:4px; }
/* SPEC-v21 B1 (Run 53): the old per-scheme geomap picker/accuracy-note
   CSS (#panel-geology/#geomap-picker/#geology-note/.geomap-low-conf) is
   REMOVED -- the new basin-wide geology layer's own drawer legend
   (#geology-legend, below) replaces it entirely, same quiet register
   .flow-legend above already established. */
.geology-legend{
  margin-top:8px; padding-top:8px; border-top:1px solid var(--hair);
  font-size:10.5px; color:var(--core); line-height:1.5;
}
.geology-legend[hidden]{ display:none; }
/* Run 54 GAP 3: gross-vs-net must be unmissable in the legend itself, not
   just buried in the trailing caveat sentence -- an explicit title + a
   dedicated sub-line, both ahead of the band ramp. */
.geology-legend-title{ font-weight:700; color:var(--core); font-size:11px; letter-spacing:.01em; }
.geology-legend-subtitle{
  font-family:var(--serif); font-style:italic; font-size:10px;
  color:var(--core-dim); margin-bottom:6px;
}
.geology-ramp{ display:flex; flex-wrap:wrap; gap:5px 10px; }
.geology-legend-item{ display:inline-flex; align-items:center; gap:5px; white-space:nowrap; }
.geology-swatch{
  display:inline-block; width:9px; height:9px; border-radius:2px; flex-shrink:0;
  border:1px solid rgba(79,168,224,.5);
}
.geology-legend-caveat{
  font-family:var(--serif); font-style:italic; font-size:9.5px;
  color:var(--core-dim); margin-top:5px; line-height:1.35;
}
.geology-legend-caveat a{ color:var(--core-dim); }
/* SPEC-v23 C1 (Run 57): the geology on/off checkbox becomes a PICKER --
   one unit active at a time. Small pill buttons, same dark-chrome
   register as the rest of the drawer (--steel-2 resting state,
   --ember-dim accent on the active pick -- same accent color the app
   already uses for "this is the selected thing" elsewhere, e.g. active
   sort headers/tabs). */
/* #geology-row is a .row (display:flex, align-items:center per the shared
   rule above) -- override to a column stack here, since a label + 6 wrapping
   picker buttons reads far better stacked than squeezed onto one line in
   the drawer's ~340px width. */
#geology-row{ display:block; }
.geology-picker-label{ font-size:10.5px; color:var(--core-dim); margin-bottom:6px; }
.geology-picker{ display:flex; flex-wrap:wrap; gap:6px; }
.geology-picker-btn{
  background:var(--steel-2); border:1px solid var(--hair); color:var(--core-dim);
  font-family:var(--mono); font-size:10.5px; padding:6px 10px; border-radius:12px;
  cursor:pointer; min-height:28px;
}
.geology-picker-btn:hover{ border-color:var(--ember-dim); color:var(--frost); }
.geology-picker-btn.active{
  background:var(--ember-wash-2); border-color:var(--ember-dim); color:var(--frost);
  font-weight:600;
}
.geology-picker-loading{ font-family:var(--serif); font-style:italic; font-size:10px; color:var(--core-dim); margin-top:6px; }
/* SPEC-v17 B3: #pipelines-legend (commodity/counts breakdown + the
   Trunk-capacity reference block) is deleted entirely, per spec -- the
   layers/data behind it are untouched (main-tier-always-on, gathering
   detail on selection, the Trunk points layer itself), only that always-
   floating readout box is gone. #pipelines-reveal-row/#cer-row now live in
   the ☰ drawer (index.html), reusing .row/.full-toggle's existing styling.
   .pipe-caveat stays -- it also styles the flow-hub caption popup. */
.pipe-caveat{
  font-family:var(--serif); font-style:italic; font-size:10px;
  color:var(--core-dim); margin-top:5px; max-width:220px; line-height:1.35;
}
/* SPEC-v27 D4 (Run 71): the ONE fixed pipeline-popup card layout --
   WHAT (bold) / WHO / SPECS / CONNECTIONS chips / a single plain source
   note. Superseded: .pipe-feeders/.pipe-trunk-hint (free-form layout,
   Trunk-points pointer -- that layer is gone) and the "Ø/MOP only Ⓘ"
   jargon-chip caveat pattern (plain-words rule, D4). */
.pipe-what{ font-size:12.5px; color:var(--frost); margin-bottom:2px; }
.pipe-who{ font-size:11px; color:var(--core); margin-bottom:4px; display:flex; align-items:center; gap:7px; }
.pipe-who-logo{ height:18px; max-width:96px; object-fit:contain; } /* 2026-09-19: pipeline company mark in the hover card */
.pipe-specs{
  font-family:var(--mono); font-size:10.5px; color:var(--core-dim);
  margin-bottom:6px;
}
.pipe-connections{ display:flex; flex-wrap:wrap; align-items:center; gap:5px; max-width:230px; }
.pipe-connections-label{ font-size:10px; color:var(--core-dim); margin-right:2px; }
.pipe-scheme-chip{
  display:inline-flex; align-items:center; gap:4px;
  background:var(--steel-2); border:1px solid var(--hair); color:var(--frost);
  font-family:var(--mono); font-size:10px; padding:3px 8px 3px 6px;
  border-radius:10px; cursor:pointer; line-height:1.3;
}
.pipe-scheme-chip:hover{ border-color:var(--ember-dim); color:var(--ember); }
.pipe-scheme-chip-dot{ display:inline-block; width:6px; height:6px; border-radius:50%; flex-shrink:0; }
.pipe-source-note{
  font-family:var(--serif); font-style:italic; font-size:9.5px;
  color:var(--core-dim); margin-top:6px;
}
/* SPEC-v29 (Run 73): the ribbon card's own source note is a REAL link to
   the CER Pipeline Profile page each capacity was verified against --
   every other .pipe-source-note stays plain text, so this only styles the
   anchor case. */
.pipe-source-note a{ color:var(--core); text-decoration:underline; }
.pipe-source-note a:hover{ color:var(--ember); }

/* SPEC-v28 item 4: the CER trunk-capacity marker rules that used to live
   here (.cer-marker, a plain rotated-square DOM diamond) are killed along
   with the Trunk points layer itself. */

/* SPEC-v19 A2 (Run 49, flow map): 2-3 hub dots (Edmonton/Hardisty/
   Cheecham) -- small labeled dot + pill, same light-chip register as
   #nav-cluster (this app's light-canvas chrome idiom) so it reads as a
   quiet reference point, not a scheme marker. Plain neutral ink dot, NOT
   any operator/commodity color -- a hub is neither crude nor diluent, and
   per VERDICT.md #3 it isn't derived from held pipeline data at all, so it
   deliberately looks like a different kind of thing on the map. */
.flow-hub-marker{
  display:flex; align-items:center; gap:5px; cursor:pointer;
  transform:translateY(-1px);
}
.flow-hub-dot{
  display:block; width:8px; height:8px; border-radius:50%;
  background:#2c3a48; border:1.5px solid rgba(255,255,255,.85);
  box-shadow:0 1px 3px rgba(30,10,14,.4);
}
.flow-hub-label{
  font-family:var(--display); font-weight:700; font-size:10px;
  letter-spacing:.03em; color:#1f0b0f; white-space:nowrap;
  background:rgba(255,255,255,.88); border:1px solid rgba(30,10,14,.1);
  border-radius:8px; padding:2px 7px; box-shadow:0 1px 4px rgba(30,10,14,.15);
}
.flow-hub-marker:hover .flow-hub-dot{ background:var(--ember); }
/* 2026-09-24 (Phil: "lets just do a black square on both of them"): Edmonton + Hardisty, the two
   export doors -- a black square, not a dot, so they read as places the barrels go rather than as
   another scheme marker. Tap opens the pipeline-shaped card (flowHubPopupHtml). */
.flow-hub-marker-major .flow-hub-dot{
  width:11px; height:11px; border-radius:2px; background:#12080a;
  border:1.5px solid rgba(255,255,255,.92); box-shadow:0 1px 4px rgba(30,10,14,.5);
}
.flow-hub-marker-major:hover .flow-hub-dot{ background:var(--ember); }
.hub-corridors{ margin-top:6px; }
/* 2026-09-24 (Phil: "the bbl/d of every pipeline more pronounced and focused. this little cutout is not
   doing that for me"): the capacity is the figure, not a footnote -- big tabular number, small unit,
   right-aligned in its own column so a hub's lines read as a table of barrels. */
.hub-line{ display:flex; align-items:baseline; justify-content:space-between; gap:10px;
  font-family:var(--mono); font-size:10.5px; line-height:1.5; color:var(--frost); padding:3px 0; border-top:1px solid rgba(255,255,255,.08); }
.hub-line:first-child{ border-top:0; }
.hub-line b{ color:var(--frost); }
.hub-line-name{ display:flex; flex-direction:column; min-width:0; }
.hub-line-dest{ color:var(--core-dim); font-size:9.5px; }
.hub-cap{ display:flex; align-items:baseline; gap:3px; flex-shrink:0; }
.hub-cap-val{ font-size:17px; font-weight:700; color:var(--frost); font-variant-numeric:tabular-nums; letter-spacing:-.01em; }
.hub-cap-unit{ font-size:9px; color:var(--core-dim); }
.pipe-capacity{ display:flex; align-items:baseline; gap:5px; margin:4px 0 2px; }
.pipe-capacity-val{ font-family:var(--mono); font-size:24px; font-weight:700; line-height:1; color:var(--frost); font-variant-numeric:tabular-nums; letter-spacing:-.01em; }
.pipe-capacity-unit{ font-family:var(--mono); font-size:9.5px; color:var(--core-dim); }
.pipe-capacity-dia .pipe-capacity-val{ font-size:19px; }

/* SPEC-v27 D5 (Phil 2026-07-29: "'Cheecham' is very prominent in the
   screen... maybe just that one we can reduce its importance"). Edmonton
   + Hardisty keep the full named-anchor pill above (they're the
   destinations); Cheecham -- a real gathering junction, stays in the flow
   story, just must never compete with scheme labels -- demotes to a small
   muted dot + a barely-there label: no pill background, thin low-contrast
   type, ~60% the size. Readable when looked for (hover restores full
   contrast), invisible when scanning for scheme names. */
.flow-hub-marker-minor .flow-hub-dot{
  width:5px; height:5px; background:#7c8a96; border-width:1px;
  box-shadow:none;
}
.flow-hub-marker-minor .flow-hub-label{
  font-weight:500; font-size:9px; letter-spacing:.01em; color:#6b7680;
  background:none; border:none; box-shadow:none; padding:1px 3px 1px 0;
}
.flow-hub-marker-minor:hover .flow-hub-dot{ background:var(--ember); }
.flow-hub-marker-minor:hover .flow-hub-label{ color:#1f0b0f; }

/* Drawer legend words (SPEC-v19 B3/B4) -- carries the in/out story since
   no direction arrow is drawn on the map. Same quiet register as
   .pipe-caveat below it. */
.flow-legend{
  margin-top:8px; padding-top:8px; border-top:1px solid var(--hair);
  font-size:10.5px; color:var(--core); line-height:1.5;
}
.flow-legend[hidden]{ display:none; }
.flow-legend-item{ display:inline-flex; align-items:center; gap:5px; }
.flow-legend-sep{ margin:0 6px; color:var(--core-dim); }
.flow-swatch{
  display:inline-block; width:9px; height:9px; border-radius:2px; flex-shrink:0;
}
.flow-swatch-crude{ background:var(--flow-crude); }
.flow-swatch-diluent{ background:var(--flow-diluent); }
.flow-swatch-liquids{ background:var(--flow-liquids); }
.flow-swatch-dashed{ background:repeating-linear-gradient(90deg, var(--flow-crude) 0 5px, transparent 5px 9px); }
.flow-legend-caveat{
  font-family:var(--serif); font-style:italic; font-size:9.5px;
  color:var(--core-dim); margin-top:5px; line-height:1.35;
}
.flow-legend-caveat a{ color:var(--core-dim); }

/* ---- map markers ----
   v2.1: markers are native GeoJSON circle layers (scheme-glow + scheme-core
   in app.js), not DOM elements -- painted in the map's own WebGL frame so
   there is no scroll-lag. No marker CSS needed here. */
.maplibregl-popup-content{
  background:var(--steel) !important; color:var(--frost) !important;
  border:1px solid var(--hair) !important; border-radius:2px !important;
  font-family:var(--mono) !important; font-size:11px !important;
  padding:8px 10px !important; box-shadow:0 8px 24px rgba(0,0,0,.5) !important;
}
.maplibregl-popup-tip{ display:none !important; }
/* RUN 19: logo-first hover popup -- the operator's mark sits left of the
   scheme name/operator text, same "logo + name" pattern as the panel
   header, sized to the popup's own tight padding. */
.map-popup-row{ display:flex; align-items:center; gap:8px; }
.map-popup-row .logo-chip{ flex-shrink:0; }

/* SPEC-v15 A1/A4 (2026-07-27): the popup's compact copy of the card's 3
   hero KPIs (see popupKpiHtml in app.js -- same value/rank functions the
   card's own stat block uses, never a second computation). A4: this must
   stay a PREVIEW, not a mini-card -- tight single-column stack, no grid,
   no chart, capped by the popup's own maxWidth (190px, set in app.js) so
   on a 390px viewport it never reads as more than about half the screen. */
.map-popup-kpis{
  margin:7px 0; padding:6px 0; border-top:1px solid var(--hair); border-bottom:1px solid var(--hair);
  display:flex; flex-direction:column; gap:3px;
}
/* SPEC-v28 item 11 RANK ALIGNMENT FIX: same 2-column-grid discipline as
   .stat-top above -- .popup-kpi-vu (value+unit) is the flexible left
   column, .popup-kpi-rank owns a fixed-width right column of its own. */
.popup-kpi-row{ display:grid; grid-template-columns:1fr auto; align-items:baseline; column-gap:6px; }
.popup-kpi-vu{ display:flex; align-items:baseline; gap:6px; min-width:0; overflow:hidden; }
.popup-kpi-value{
  font-family:var(--mono); font-size:12px; font-weight:600; color:var(--frost);
  font-variant-numeric:tabular-nums; white-space:nowrap; flex-shrink:0;
}
/* SPEC-v32 A2: ellipsis removed, same no-truncation rule as .stat-value
   above -- .fit-text (app.js's fitTextEls) shrinks instead of clipping. */
.popup-kpi-unit{
  font-family:var(--mono); font-size:9px; color:var(--core-dim);
  text-transform:uppercase; letter-spacing:.04em; overflow:hidden; white-space:nowrap;
}
.popup-kpi-rank{
  font-family:var(--mono); font-size:9.5px; font-weight:600; color:var(--ember);
  padding:0 4px; border-radius:6px; border:1px solid var(--ember-dim);
  background:var(--ember-wash-2); flex-shrink:0; justify-self:end;
  min-width:24px; text-align:center; box-sizing:border-box;
}
.popup-footer-row{ display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap; }
/* SPEC-v27 B1/D4 (Run 71): popup content commonly carries a real tap
   target now (D4's pipeline CONNECTIONS chips; the scheme bubble's own
   rank chips) -- cursor:pointer is a no-op on touch but keeps this honest
   on a trackpad/hybrid device. Superseded: .popup-open-hint (the "second
   tap opens the card" hint), dead now that one tap already does
   everything (B1). */
.maplibregl-popup-content{ cursor:pointer; }
.maplibregl-popup-content a.gmaps-link{ cursor:pointer; }
/* Close button (touch popup only -- desktop hover popup has closeButton:
   false): restyle maplibre's default white square to the app's own
   steel/hair/frost language instead of the jarring default. */
.maplibregl-popup-close-button{
  color:var(--core-dim) !important; font-size:16px !important; padding:2px 6px !important;
}
.maplibregl-popup-close-button:hover{ color:var(--ember) !important; background:transparent !important; }

.maplibregl-ctrl-attrib{ font-size:9px !important; }
/* ROADMAP cartography leg: the default ScaleControl ships as a bright white
   box with a black border -- jarring against the ember/night-ops map. Restyle
   to the same steel/hair/frost language as the popup above. */
.maplibregl-ctrl-scale{
  background:rgba(20,29,40,.72) !important; border:1px solid var(--hair) !important;
  border-top:1px solid var(--hair) !important; color:var(--core) !important;
  font-family:var(--mono) !important; font-size:10px !important;
}

/* ---- detail panel ---- */
#panel{
  position:absolute; top:0; right:0; bottom:0; z-index:10;
  width:min(460px, 100vw);
  background:var(--steel); border-left:1px solid var(--hair);
  transform:translateX(100%); transition:transform .32s cubic-bezier(.2,.8,.2,1);
  display:flex; flex-direction:column;
  box-shadow:-24px 0 48px rgba(0,0,0,.45);
}
#panel.open{ transform:translateX(0); }

/* SPEC-v27 C: the mobile bottom-sheet drag handle -- desktop keeps the
   side panel (C2, no handle, no detents); the 640px media query below
   turns this into a real 44px drag target. */
#panel-handle{ display:none; }
/* 2026-09-10: the phone PEEK bar's KPI row (the retired tap bubble's three
   ranked KPIs). Base = hidden; the mobile block shows it at PEEK only. */
.peek-kpis{ display:none; }

#panel-scroll{ overflow-y:auto; -webkit-overflow-scrolling:touch; height:100%; padding:26px 24px 60px; }
#panel-scroll::-webkit-scrollbar{ width:8px; }
#panel-scroll::-webkit-scrollbar-thumb{ background:var(--hair); border-radius:4px; }

/* SPEC-v11 Run B, B2: the old "APPR 11763 SAGD" eyebrow row is gone
   entirely -- replaced by .scheme-header-top (big logo + name) below.
   .scheme-badges is what's left of the eyebrow: the 3 real info chips
   (SK/EOR/Geology) it used to carry, re-homed under the name. Class
   names on the chips themselves (.eyebrow-sk-chip etc.) kept as-is to
   avoid a pointless rename churn -- only their wrapping container moved. */
.scheme-approval-folds{ font-family:var(--mono); font-size:10px; color:var(--core-dim); margin:2px 0 6px; }
.scheme-badges{
  display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:0 0 14px;
}
/* SPEC-v8 Leg 3: SK province + EOR note chips, small and quiet -- info,
   not alarm (no red/warning language; EOR is the operator's own wording,
   not a data-quality flag). */
.eyebrow-sk-chip, .eyebrow-eor-chip, .eyebrow-geo-chip, .eyebrow-status-chip{
  font-family:var(--mono); font-size:9.5px; letter-spacing:.06em; text-transform:uppercase;
  padding:1px 6px; border-radius:8px; border:1px solid var(--hair); color:var(--core-dim);
}
.eyebrow-sk-chip{ color:var(--frost); border-color:rgba(231,238,243,.25); }
.eyebrow-status-chip.status-decommissioned{ color:#e08a80; border-color:rgba(224,138,128,.45); }
.eyebrow-status-chip.status-suspended{ color:#d9b35c; border-color:rgba(217,179,92,.45); }
.eyebrow-eor-chip{ color:var(--ember); border-color:var(--ember-dim); }
/* SPEC-v23 B1: quiet formation line -- card (under the badges row) and
   popup (under the operator name) share this class. Plain quote-backed
   text, no chip/border chrome (this isn't a caveat or a warning, just a
   fact); the "formation not stated" case dims slightly further so it
   reads as an honest absence, not an error. */
.scheme-formation-line{
  font-family:var(--mono); font-size:10px; color:var(--core-dim); margin:2px 0 10px;
}
.scheme-formation-line-unstated{ opacity:.7; font-style:italic; font-family:var(--serif); }
/* SPEC-v32 A4: the 3 deposit-region-basis schemes (e.g. Firebag) read as a
   normal fact, full opacity -- the "(deposit region)" wording in the label
   itself already carries the honesty signal; cursor:help + the title
   attribute (app.js) surface the one-line basis note on hover, same quiet
   register as every other caveat in this app. */
.scheme-formation-line-deposit-region{ cursor:help; }
.map-popup-row .scheme-formation-line{ margin:1px 0 0; font-size:9.5px; }
/* POST-SHIP FIX (Batch A gate 2, orchestrator finding): the always-
   reachable card hazard line -- SPEC-v28 item 1's standing rule ("no
   hazard may become unreachable") applies regardless of where the map
   camera happens to be pointed, which a pad map-card tap alone can't
   guarantee. Warning register (--ember, matches .pad-card-hazard's own
   color), never rendered for the ~34 schemes with no hazard rows. */
.scheme-hazard-line{
  display:flex; align-items:center; flex-wrap:wrap; gap:5px;
  font-family:var(--mono); font-size:10px; color:var(--ember); margin:2px 0 10px;
}
.scheme-hazard-flag{ font-size:9px; line-height:1; flex-shrink:0; }
.scheme-hazard-chip{
  display:inline-flex; align-items:center; padding:1px 6px; border-radius:8px;
  border:1px solid var(--ember-dim); color:var(--ember); cursor:pointer; white-space:nowrap;
}
.scheme-hazard-chip:hover, .scheme-hazard-chip:focus-visible{ background:var(--ember-wash-2); }
/* SPEC-v24 A3: the paymap card one-liner -- 12 schemes only, same quiet
   register as the formation line right above it (fact, not a caveat). */
.scheme-paymap-line{
  font-family:var(--mono); font-size:10px; color:var(--core-dim); margin:-6px 0 10px;
}
/* Run 62 LEG 1: contour-levels sub-line, right under the paymap line for
   the 11 of 17 built schemes that carry interior contours. */
.scheme-paymap-contour-line{
  font-family:var(--mono); font-size:10px; color:var(--core-dim); opacity:.85; margin:-8px 0 10px;
}
/* SPEC-v25 B: drainage card one-liner -- same quiet register, sits right
   after the paymap line (both can show at once, 7 of 16 schemes overlap). */
.scheme-drainage-line{
  font-family:var(--mono); font-size:10px; color:var(--core-dim); margin:-6px 0 10px;
}
.scheme-drainage-line a{ color:inherit; text-decoration:underline; opacity:.8; }
/* Run 65 LEG 1: net-pay TIER line -- every scheme, always rendered (never
   blank, unlike the paymap/drainage/formation lines above it), same quiet
   mono register. The "retired"/"none" tiers dim further (mirrors
   .scheme-formation-line-unstated) so an honest absence reads as absence,
   not an error. */
.scheme-netpay-line{
  font-family:var(--mono); font-size:10px; color:var(--core-dim); margin:-6px 0 10px;
}
.scheme-netpay-line a{ color:inherit; text-decoration:underline; opacity:.8; }
.scheme-netpay-line-unstated{ opacity:.7; font-style:italic; font-family:var(--serif); }
/* GAP 6 (Run 29): affirmative-only badge (9/45 schemes) -- teal/core accent,
   distinct from the ember EOR chip and the plain SK chip. */
.eyebrow-geo-chip{ color:var(--good); border-color:rgba(61,220,151,.35); }
/* Run 32 (Phil 4, caveat sweep): the short-label+tooltip replacement for
   every long italic caveat sentence that used to render inline. Same
   quiet/info register as the eyebrow chips above, not a warning color --
   these are honest-data notes, not alerts. Full text lives in `title`
   (native tooltip on hover; also reachable via tap-and-hold/VoiceOver on
   touch, same as every other title= chip in this file). */
.caveat-chip{
  display:inline-flex; align-items:center; gap:2px; font-family:var(--mono);
  font-size:9.5px; letter-spacing:.04em; text-transform:uppercase;
  padding:1px 6px; border-radius:8px; border:1px solid var(--hair);
  color:var(--core-dim); cursor:help; white-space:nowrap;
}
.caveat-chip-i{ opacity:.7; font-size:10px; }
.caveat-chip:hover{ color:var(--frost); border-color:var(--core); }
.schematic-empty-note.sk-note{ color:var(--frost); opacity:.75; }

/* SPEC-v11 Run B, B2: the panel's new header -- big operator logo
   top-left, site name large to its right (2.2), replacing the old
   eyebrow + h1 + separate "<operator> · N wells · filed" line (2.1/2.3).
   The logo carries operator identity now, so the name alone can be
   bigger without repeating the operator in text right below it. */
.scheme-header-top{
  display:flex; align-items:center; gap:14px; margin:0 0 4px;
}
.scheme-header-top .logo-chip{ flex-shrink:0; }
/* SPEC-v33 K3 (Phil: "'Hangingstone' has 'ne' showing on the next line"):
   overflow-wrap:break-word let the browser hyphenlessly SPLIT a single
   long word mid-character the moment it didn't fit one line -- "Hanging"/
   "stone" at 390px, an ugly break, not a real bug in the text itself.
   Same no-truncation idiom as every stat/KPI value (.fit-text/fitTextEls,
   see .stat-value above): single line, shrink the font instead of
   wrapping OR clipping. app.js marks this element .fit-text and
   fitTextEls() shrinks it post-render until "Hangingstone McKay River" (24
   chars, the longest scheme name in the corpus) fits at FIT_TEXT_MIN_PX or
   above -- overflow:hidden is the defensive floor only, never the
   mechanism, same discipline as .stat-value. */
h1.scheme-name{
  font-family:var(--display); font-weight:700; font-size:32px;
  line-height:1.1; margin:0; color:var(--frost);
  min-width:0; white-space:nowrap; overflow:hidden;
}
.operator-history{ font-family:var(--mono); font-size:10px; color:var(--core-dim); margin-bottom:18px; }

/* SPEC-v14 A1: folded sub-project intel card(s) -- Foster Creek's ESI pilot,
   Hangingstone's Expansion filing. Force-open by default (see renderSection
   call, opts.forceOpen) since this is a structural fact about the scheme,
   not a buried footnote -- distinct ember-accented card, never blended into
   the parent's own stat block. */
.folded-scheme-card{
  border:1px solid var(--ember-dim); border-radius:8px; padding:10px 12px;
  margin-bottom:8px; background:var(--ember-wash-1);
}
.folded-scheme-card:last-child{ margin-bottom:0; }
.folded-scheme-head{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:4px; }
.folded-scheme-tag{
  font-family:var(--mono); font-size:9px; text-transform:uppercase; letter-spacing:.08em;
  color:var(--ember); border:1px solid var(--ember-dim); border-radius:6px; padding:1px 6px;
}
.folded-scheme-name{ font-weight:600; color:var(--frost); }
.folded-scheme-approval{ font-family:var(--mono); font-size:10px; color:var(--core-dim); margin-left:auto; }
.folded-scheme-stats{ font-family:var(--mono); font-size:11px; color:var(--core); margin-bottom:4px; }
.folded-scheme-note{ font-size:12px; color:var(--core); line-height:1.4; }

.section-label{
  font-family:var(--mono); font-size:10px; color:var(--core);
  text-transform:uppercase; letter-spacing:.1em;
  margin:26px 0 10px; padding-top:16px; border-top:1px solid var(--hair);
  display:flex; justify-content:space-between; align-items:center;
}

/* ---- v4: scouting-card declutter -- one-line pad summary + collapsed
   accordion sections (Pads/Attributes/Timeline), closed by default ---- */

.collapse-section{ margin-top:16px; }
.collapse-header{
  width:100%; display:flex; justify-content:space-between; align-items:center;
  background:transparent; border:none; border-top:1px solid var(--hair);
  padding:14px 0 8px; cursor:pointer; text-align:left;
  font:inherit; appearance:none; color:inherit;
}
.collapse-header:hover .collapse-title{ color:var(--frost); }
.collapse-title{
  font-family:var(--mono); font-size:10px; color:var(--core);
  text-transform:uppercase; letter-spacing:.1em;
}
.collapse-chev{
  display:inline-block; margin-right:6px; font-size:9px; color:var(--core-dim);
  transition:transform .15s ease;
}
.collapse-section.open .collapse-chev{ transform:rotate(90deg); }
.collapse-meta{ font-family:var(--mono); font-size:10px; color:var(--core-dim); }
.collapse-body{ display:none; }
.collapse-section.open .collapse-body{ display:block; }

.tl-show-all{
  display:block; width:100%; margin:10px 0 0; padding:7px 10px;
  background:transparent; border:1px dashed var(--hair); color:var(--core);
  font-family:var(--mono); font-size:10.5px; border-radius:2px; cursor:pointer;
}
.tl-show-all:hover{ border-color:var(--ember-dim); color:var(--ember); }

/* Leg C: "N superseded plans -> Superseded tab" jump link on the Planned
   tab -- same visual weight/pattern as .tl-show-all, kept as its own
   class so it can't collide with the single-target
   querySelector('.tl-show-all') timeline-cap handler elsewhere. */
.tab-jump-superseded{
  display:block; width:100%; margin:0 0 10px; padding:7px 10px; min-height:44px;
  background:transparent; border:1px dashed var(--hair); color:var(--core);
  font-family:var(--mono); font-size:10.5px; border-radius:2px; cursor:pointer;
}
.tab-jump-superseded:hover{ border-color:var(--ember-dim); color:var(--ember); }

/* ---- SPEC-v12 B2 (2026-07-26): the card STAT BLOCK -- three hero KPIs
   (production / cSOR / active pairs), each with its rank across all 45
   schemes as a `#N` chip inline with the value. KPIs first, chart second
   (the SPEC-v11 order stands). On desktop three columns; on mobile they
   stack, each still one clean row with the rank chip INLINE (B2), not a
   second column. Replaces the old six-cell tap-to-reveal KPI header --
   rank is shown up front now, not earned by a tap. ---- */
.scheme-stat-block{
  display:grid; grid-template-columns:repeat(3,1fr); gap:1px;
  background:var(--hair); border:1px solid var(--hair);
  margin:16px 0 6px; border-radius:3px; overflow:hidden;
}
.stat-cell{
  background:var(--steel-2); padding:12px 14px; min-height:44px;
  display:flex; flex-direction:column; justify-content:center; gap:5px;
}
.stat-cell-tap{ cursor:pointer; }
.stat-cell-tap:hover{ background:var(--steel); }
/* SPEC-v28 item 11 RANK ALIGNMENT FIX (Phil 2026-07-29: "the little #20
   ranking boxes... the text gets pushed sometimes and it looks bad"): a
   real 2-column GRID, not a wrapping flex row -- column 1 (1fr) is the
   value, left/decimal-aligned (tabular-nums) and free to ellipsize in the
   genuinely-impossible case rather than wrap; column 2 (.stat-chips) is a
   fixed-width right column for the rank chip (+ any ramping/boundary/
   recon-flag chip riding beside it) -- it can NEVER push or wrap the
   value again, at any viewport, with any digit count (#1 through #45). */
.stat-top{
  display:grid; grid-template-columns:1fr auto; align-items:baseline;
  column-gap:6px; min-width:0;
}
/* SPEC-v32 A2 (Phil verbatim, "no-truncation rule" -- fixture: Firebag's
   "104.5 kbpd" must render in full at 390px): text-overflow:ellipsis used
   to silently HIDE characters here -- removed. .fit-text (this class,
   marked on every stat/KPI/rank value cell app-wide -- see app.js's
   fitTextEls) instead shrinks its own font-size after render until it
   fits its box, never clipping or wrapping. overflow:hidden stays as a
   defensive floor only (the shrink loop has a hard minimum size), never
   the primary mechanism. */
.stat-value{
  font-family:var(--mono); font-size:19px; line-height:1.05; color:var(--frost);
  font-weight:600; font-variant-numeric:tabular-nums;
  min-width:0; overflow:hidden; white-space:nowrap;
}
.stat-chips{
  display:flex; align-items:baseline; gap:5px; justify-self:end; flex-shrink:0;
}
.stat-rank{
  font-family:var(--mono); font-size:11px; font-weight:600; color:var(--ember);
  font-variant-numeric:tabular-nums; letter-spacing:.02em;
  padding:1px 5px; border-radius:6px; border:1px solid var(--ember-dim);
  background:var(--ember-wash-2); white-space:nowrap;
  min-width:28px; text-align:center; box-sizing:border-box; flex-shrink:0;
}
/* SPEC-v28 item 12: card + econ rank chips are real links now (the KPI
   popup's own .popup-kpi-rank stays inert this run, no cursor change --
   see wireRankChipLinks' own comment for the sequencing reason). */
.stat-rank{ cursor:pointer; }
.stat-rank:hover{ background:var(--ember-wash-3); border-color:var(--ember); }
.stat-label{
  font-family:var(--mono); font-size:9px; color:var(--core-dim);
  text-transform:uppercase; letter-spacing:.06em;
}
.stat-cell-tap .stat-label{ color:var(--core); }
.stat-hint{ color:var(--ember); font-weight:700; }
/* SPEC-v13 A3 (2026-07-26): the well-name-parsed pair count demotes from
   KPI3 to a quiet corroboration line under the stat block once the filed
   count becomes the headline (A1) -- "we independently resolve N pair
   geometries" -- honest phrasing, never implying it's the total. */
.stat-corroboration{
  font-family:var(--mono); font-size:10.5px; color:var(--core-dim);
  margin:0 0 14px; padding:0 2px;
}
/* 2026-10-26: the freshness + operator-benchmark lines under the KPIs. Fresh = a miss, so it is
   NOT quiet; bench keeps the corroboration register but wraps its milestones as prose. */
.stat-fresh{ color:var(--warn, #c9742a); font-weight:600; }
.stat-bench{ white-space:normal; line-height:1.5; }
.stat-bench a{ color:var(--core); border-bottom:1px solid var(--hair); }
.stat-bench .bench-milestone{ display:inline-block; margin:2px 6px 0 0; padding:1px 6px; border:1px solid var(--hair); border-radius:3px; }
/* SPEC-v16 A2: quiet Methodology link, panel footer -- same register as
   .stat-corroboration/.caveat-chip, deliberately unobtrusive. */
.panel-methodology-foot{
  margin-top:22px; padding-top:12px; border-top:1px solid var(--hair);
  font-family:var(--mono); font-size:11px;
}
.panel-methodology-foot a{ color:var(--core); border-bottom-color:var(--hair); }
.panel-methodology-foot a:hover{ color:var(--frost); border-bottom-color:var(--core); }
/* Mobile: cells stack; the rank chip stays inline with the value (B2),
   never a second column. */
@media (max-width:520px){
  .scheme-stat-block{ grid-template-columns:1fr; }
  .stat-cell{ min-height:40px; padding:11px 14px; }
}

/* SPEC-v18 B1: the economics row -- opex/netback/carbon, directly under
   the 3-KPI stat block, same visual register (reuses .stat-value/.stat-
   label/.stat-rank) but one notch quieter (smaller value, tighter cells)
   so it reads as secondary to the KPI headline above it, not competing
   with it. Always 3 cells, even on a fully gated-out card (B2 -- uniform
   chrome, honest "--" coverage, never an omitted row). */
.econ-row{
  display:grid; grid-template-columns:repeat(3,1fr); gap:1px;
  background:var(--hair); border:1px solid var(--hair); border-top:none;
  margin:0 0 6px; border-radius:0 0 3px 3px; overflow:hidden;
}
.econ-cell{
  background:var(--steel); padding:9px 14px; min-height:36px;
  display:flex; flex-direction:column; justify-content:center; gap:4px;
}
.econ-value{ font-size:15px; }
/* B2: the carbon boundary marker -- a small dot, never a bare number.
   Color differentiates the 4 boundary states so a scan of several cards
   can spot "this one includes cogen" without reading every tooltip;
   plant_only (the clean, expected case) stays neutral ink so it doesn't
   read as a warning. */
.carbon-boundary-flag{
  font-size:8px; cursor:help; line-height:1; vertical-align:middle;
  color:var(--core-dim);
}
.carbon-boundary-flag.carbon-boundary-includes_cogen{ color:var(--ember); }
.carbon-boundary-flag.carbon-boundary-cogen_separate_nearby{ color:var(--csor); }
.carbon-boundary-flag.carbon-boundary-unknown{ color:var(--core); }
/* Run 62 LEG 2: the econ reconciliation ⚠ -- opex/netback that failed the
   clean <=5% barrel-reconciliation gate but still show a real (sanity-
   bound) number. Ember (the same warm warning hue the boundary flag uses
   for its own "not the clean case" states), always paired with a real
   tooltip (econ.flagReason) -- never a bare warning glyph. */
.econ-recon-flag{
  font-size:9px; cursor:help; line-height:1; vertical-align:middle;
  color:var(--ember); margin-left:2px;
}
@media (max-width:520px){
  .econ-row{ grid-template-columns:1fr; }
  .econ-cell{ min-height:32px; padding:8px 14px; }
}

/* SPEC-v18 A: the development strip -- "when they got bigger and how much
   bigger" (Phil). Replaces the old .schematic-phase-tier chip list with
   ONE quiet line: year ticks (+kbpd where a filing states one) arrow-
   chained to the current rate, plus an optional trailing "approved, not
   built" fact. Deliberately plain text, not chips -- it's meant to read
   in one glance, not be tapped through. */
.dev-strip{
  margin:0 0 14px; padding:10px 14px; background:var(--steel-2);
  border:1px solid var(--hair); border-radius:3px;
}
.dev-strip-line{
  font-family:var(--mono); font-size:12.5px; color:var(--frost);
  font-variant-numeric:tabular-nums; line-height:1.6;
}
.dev-strip-arrow{ color:var(--core-dim); margin:0 1px; }
.dev-strip-trailing{
  font-family:var(--mono); font-size:10.5px; color:var(--core);
  margin-top:5px;
}

/* SPEC-v12 B1: the tapped marker's operator color as a thin accent on the
   card header, so the card visually belongs to the dot you tapped. */
.scheme-header-top{ position:relative; }
.scheme-header-accent{
  position:absolute; left:-16px; top:2px; bottom:2px; width:3px; border-radius:2px;
  background:var(--accent, var(--ember));
}
.scheme-header-id{ min-width:0; }
.scheme-header-op{
  font-family:var(--mono); font-size:11px; color:var(--core); margin-top:2px;
}
@media (max-width:520px){
  /* SPEC-v33 R: the acquisition-rename marker produces genuinely longer
     names than the corpus carried when K3 was validated ("MEG Christina
     Lake (formerly MEG)" / "Algar / Great Divide (formerly Connacher)" --
     34/43 chars, past the 24-char "Hangingstone McKay River" K3's own
     comment cites as the prior longest). Cenovus's real wordmark logo
     renders ~200px wide at the header's 48px height (its own aspect
     ratio, well under the 220px cap so the cap was never the binding
     constraint there) -- confirmed live that this left too little of a
     390px sheet for fitTextEls to find ANY working size: it hit
     FIT_TEXT_MIN_PX (8px) and STILL overflowed. Capping the header logo's
     rendered width here (mobile only -- desktop has the room, and this
     leaves the general-purpose logoChip default/every other call site
     alone) reclaims enough of the row that both new names fit within
     FIT_TEXT_MIN_PX, reverified live via Playwright after this change. */
  .scheme-header-top .logo-chip{ max-width:120px !important; }
}

/* SPEC-v12 B2: transient toast (placeholder for the future well-pair map
   layer's tap-in). Quiet, bottom-centered, auto-dismissed. */
#dm-toast{
  position:fixed; left:50%; bottom:28px; transform:translate(-50%,12px);
  background:var(--steel-2); color:var(--frost); border:1px solid var(--hair);
  font-family:var(--mono); font-size:12px; padding:10px 16px; border-radius:8px;
  box-shadow:0 6px 24px rgba(0,0,0,.5); z-index:9000; max-width:88vw; text-align:center;
  opacity:0; pointer-events:none; transition:opacity .18s ease, transform .18s ease;
}
#dm-toast.show{ opacity:1; transform:translate(-50%,0); }

/* ---- SPEC-v28 item 1/2 KILLED the v6 asset schematic (plant -> phases ->
   pads) and item 2 KILLED the Facility reference block -- both their
   container/tier/pad-node/facility-ref rules are gone. .schematic-chips/
   .schematic-chip/-k/-v and .schematic-attr-group/-label SURVIVE below:
   the Compliance drawer (renderComplianceDrawer, not in the kill list)
   reuses this exact chip/group chrome for its own compliance/geomech/
   co-injection/CPF/throughput facts. .schematic-empty-note also survives
   (the SK "no public filings" note in the Filings feed uses it). ---- */
.schematic-empty-note{ font-family:var(--serif); font-style:italic; font-size:12px; color:var(--core-dim); }
.schematic-chips{ display:flex; flex-wrap:wrap; gap:6px; }
.schematic-chip{
  display:flex; flex-direction:column; align-items:flex-start; gap:2px;
  background:var(--steel); border:1px solid var(--hair); border-radius:2px;
  padding:6px 9px; cursor:pointer; text-align:left; font:inherit; color:inherit;
  max-width:170px; min-height:44px; justify-content:center;
}
.schematic-chip:hover{ border-color:var(--core-dim); }
.schematic-chip-k{ font-family:var(--mono); font-size:8.5px; color:var(--core-dim); text-transform:uppercase; letter-spacing:.04em; }
.schematic-chip-v{ font-family:var(--serif); font-size:12.5px; color:var(--frost); line-height:1.3; }
/* SPEC-v10 C2: facility panel groups (Capacity/Reservoir/Steam & water/
   Processing/Wells) -- value-first chip order (v/then k, see app.js) plus a
   small review dot on rows the spec/activity classifier stayed unsure of. */
.schematic-attr-group{ margin-bottom:10px; }
.schematic-attr-group:last-child{ margin-bottom:0; }
.schematic-attr-group-label{
  font-family:var(--mono); font-size:8px; color:var(--core-dim); text-transform:uppercase;
  letter-spacing:.08em; margin-bottom:5px; opacity:.75;
}
.pads-inline-label{ margin-top:14px; }

/* ---- SPEC-v34 P5: Figures section -- a thumbnail strip of the
   operator's own deck figures, same steel/hairline chip language as
   .schematic-chip above, sized for an image instead of a k/v pair. Tap
   opens the full-screen viewer (.figure-viewer-* below). ---- */
.figures-strip{ display:flex; flex-wrap:wrap; gap:8px; }
.figure-thumb{
  display:flex; flex-direction:column; width:172px;
  background:var(--steel); border:1px solid var(--hair); border-radius:2px;
  overflow:hidden; cursor:pointer; text-align:left; font:inherit; color:inherit; padding:0;
}
.figure-thumb:hover{ border-color:var(--core-dim); }
.figure-thumb-imgwrap{ display:block; width:100%; height:104px; overflow:hidden; background:#150709; }
.figure-thumb-imgwrap img{ width:100%; height:100%; object-fit:cover; display:block; }
/* SPEC-v34 P5: title/citation wrap normally, no truncation at any length
   (see renderFiguresStripHtml's own comment in app.js for why this is
   NOT .fit-text) -- word-break guards only the rare pathological single
   long token, real captions here wrap on natural word boundaries. */
.figure-thumb-cap{ display:flex; flex-direction:column; gap:3px; padding:7px 8px 9px; min-width:0; }
.figure-thumb-title{ font-family:var(--serif); font-size:11.5px; color:var(--frost); line-height:1.3; word-break:break-word; }
.figure-citation{ font-family:var(--mono); font-size:9px; color:var(--core-dim); line-height:1.4; word-break:break-word; }

/* ===========================================================
   SPEC-v32 BATCH E: the in-card pad picker -- below the production
   chart, chips in the card's own idiom (Inter, tabular-nums). A
   selected chip wears its comparison line's exact color (--pad-color,
   inlined per chip from the compare palette -- same position-keyed
   color the chart line, legend dot, and map laterals use). Disabled
   chips stay visible WITH their reason -- honesty over tidiness.
   =========================================================== */
/* Status dots stay, but quiet -- 20 glowing ember dots would shout over
   the selection colors, which are the actual signal here. */
/* SPEC-v33 Batch N: the chip's own quiet swatch of THIS pad's stable map
   hue (--pad-hue is set inline per chip -- distinct from --pad-color
   above, which is a SELECTION-POSITION color, only present once picked).
   A small rounded square (not a circle, so it never reads as a second
   status dot) sits ahead of the status dot on every chip, selected or
   not, so the picker and the map cross-identify at a glance. */
.ppc-hue{ width:7px; height:7px; border-radius:2px; flex-shrink:0; }
/* Compact name: first alias/filed segment, budgeted to 16ch -- the FULL
   chain still lives in the title + identity hover card. SPEC-v32 BATCH J
   (no-truncation covenant): text-overflow:ellipsis used to silently HIDE
   characters here, same A2 bug the stat/KPI values were fixed for --
   removed. .fit-text (app.js's fitTextEls, already run over this whole
   panel after every render) shrinks the element's own font-size instead;
   overflow:hidden stays only as a defensive floor, never the primary
   fit mechanism, same discipline as .stat-value. */
.ppc-name{
  font-weight:600; white-space:nowrap; max-width:16ch;
  overflow:hidden;
}
.ppc-val{
  font-variant-numeric:tabular-nums; color:var(--core); font-size:9.5px;
  white-space:nowrap; display:inline-flex; align-items:baseline; gap:4px;
}
/* Run 51 staleness gate applied to the chip readout: a stale latest month
   is labeled with its as-of, never dressed up as current. */
.ppc-asof{ font-size:8.5px; color:var(--core-dim); }
.ppc-reason{ font-size:9px; color:var(--core-dim); font-style:italic; white-space:nowrap; }

/* SPEC-v7 D1: .well-chip is now a container (not itself a button -- it
   hosts two: the select button below AND the compare-toggle button, which
   can't nest inside one another). */
.well-chip{
  display:flex; align-items:center; gap:6px; width:100%; min-height:36px;
  padding:6px 8px; background:transparent; border-bottom:1px solid var(--hair);
  font-family:var(--mono); font-size:11px; color:var(--frost);
}
.well-chip:last-child{ border-bottom:none; }
.well-chip:hover{ background:var(--ember-wash-1); }
.well-chip.selected{ background:var(--ember-wash-2); }
.well-chip-select{
  display:flex; align-items:center; gap:7px; flex:1 1 auto; min-width:0;
  background:transparent; border:none; color:inherit; font:inherit; text-align:left; cursor:pointer; padding:0;
}
.well-chip .compare-toggle-btn{ font-size:9px; padding:3px 6px; flex-shrink:0; }
.well-name{ flex:1 1 auto; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.well-latest{ flex-shrink:0; color:var(--core-dim); font-size:10px; }
.well-dot{ flex-shrink:0; display:inline-block; width:7px; height:7px; border-radius:50%; background:var(--core-dim); }
.well-dot.producing{ background:var(--ember); box-shadow:0 0 4px 0 var(--ember-glow); }
.well-dot.injecting{ background:var(--good); }
.well-dot.pending{ background:var(--core); }
.well-dot.observation{ background:var(--core); opacity:.6; }
.well-dot.suspended{ background:var(--core-dim); }
.well-dot.abandoned{ background:var(--core-dim); opacity:.4; }
.chart-clear-well{
  background:transparent; border:none; color:var(--core-dim);
  font-family:var(--mono); font-size:10px; cursor:pointer;
}
.chart-clear-well:hover{ color:var(--ember); }

/* ---- v5: data coverage (reconciliation) section ---- */
.coverage-stats{ display:flex; flex-direction:column; gap:6px; margin-bottom:10px; }
.coverage-row{ display:flex; align-items:baseline; gap:8px; font-family:var(--mono); }
.coverage-row .v{ font-size:15px; color:var(--frost); font-weight:500; min-width:28px; text-align:right; }
.coverage-row .k{ font-size:10.5px; color:var(--core); }
.coverage-unmatched{ font-family:var(--mono); font-size:10px; color:var(--core-dim); line-height:1.7; margin-bottom:8px; }
.coverage-unmatched-label{ color:var(--core); text-transform:uppercase; font-size:9px; letter-spacing:.05em; }
.coverage-note{ font-family:var(--serif); font-style:italic; font-size:11.5px; color:var(--core); line-height:1.5; }

/* ---- Run 76 PRODUCTION SQUARING PHASE 1: the Reconciliation disclosure's
   classification line -- color varies by WHY sources diverge (or don't),
   same "always name the boundary/reason, never a bare flag" discipline as
   the carbon-boundary-flag colors just above. --good (aligned) is the only
   "everything checks out" case; single_source_sk is neutral (--core, a
   structural fact not a warning); the 3 real divergence classes escalate
   ember(boundary)->csor purple(timing)->steam blue(basis), unexplained
   gets the loudest treatment (ember, bold) per spec's "flagged loudly". */
.recon-classification{ font-family:var(--serif); font-size:12px; line-height:1.5; padding-top:4px; border-top:1px solid var(--hair); }
.recon-classification strong{ text-transform:uppercase; font-size:10px; letter-spacing:.04em; font-family:var(--mono); margin-right:4px; }
.recon-class-aligned strong{ color:var(--good); }
.recon-class-single_source_sk strong{ color:var(--core); }
.recon-class-boundary strong{ color:var(--ember); }
.recon-class-timing strong{ color:var(--csor); }
.recon-class-basis strong{ color:var(--steam); }
.recon-class-unexplained strong{ color:var(--ember); }
.recon-class-no_data strong{ color:var(--core-dim); }

/* ---- v4: production chart -- SAGD trio (bitumen + steam on one axis,
   SOR in an aligned strip below), one shared crosshair through both ---- */
/* flex-wrap, not overflow -- 4 legend items + CSV + an optional "clear
   pad" button don't reliably fit one row at phone panel widths (~320px
   content). Wrapping to a second line beats an overflow-x scrollbar on
   the whole panel or silently clipped buttons. */
.chart-toolbar{ display:flex; align-items:center; gap:8px 10px; margin-bottom:6px; flex-wrap:wrap; }
/* SPEC-v9 P2/P3: the pad-overlay toolbar's metric + Calendar/Months-on
   toggle groups sit side by side, wrapping together as one unit at
   narrow widths rather than interleaving with the CSV/clear buttons. */
.chart-toolbar-toggles{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.chart-legend{ display:flex; gap:8px 12px; flex-wrap:wrap; font-family:var(--mono); font-size:10.5px; color:var(--core); }
.chart-legend-item{ display:flex; align-items:center; gap:5px; }
.chart-legend-item .dot{ width:8px; height:8px; border-radius:50%; flex-shrink:0; }
.chart-legend-item .dot.bitumen{ background:var(--bitumen); }
.chart-legend-item .dot.steam{ background:var(--steam); }
.chart-legend-item .dot.isor{ background:var(--frost); }
.chart-legend-item .dot.csor{ background:var(--csor); }

/* SPEC-v10 C1: alignment anchor source badges + Custom mode's per-series
   stepper, both live in the legend row. F/D/C get distinct colors (never
   silently mixed -- the whole point is stating which resolution level
   fired); "no anchor" (—) stays neutral/dim, not alarming red -- it's an
   honest absence, not an error. */
.chart-legend-item .legend-label{ white-space:nowrap; }
/* Batch E: compared-pad legend entries budget to 15ch so a 5-pad legend
   still reads as a row (full label in the item's own title). SPEC-v32
   BATCH J (no-truncation covenant): text-overflow:ellipsis removed --
   .fit-text (app.js's fitTextEls, added to this element in the JS) shrinks
   font-size instead of silently clipping; overflow:hidden stays only as
   a defensive floor, same discipline as .ppc-name/.stat-value. */
.chart-legend-pad .legend-label{ max-width:15ch; overflow:hidden; display:inline-block; vertical-align:bottom; }
.anchor-badge{
  display:inline-flex; align-items:center; justify-content:center;
  width:13px; height:13px; border-radius:2px; font-size:8.5px; font-weight:600;
  cursor:help; flex-shrink:0;
}
.anchor-badge-filing{ background:var(--good, #2d9e83); color:#04140f; }
.anchor-badge-data{ background:var(--core-dim); color:var(--ink); }
.anchor-badge-censored{ background:transparent; color:var(--core); border:1px solid var(--core-dim); }
.compare-censored-note{ font-size:11px; color:var(--core); margin:4px 0 6px; line-height:1.4; }
/* PLAN 4 item A3: a series already running when the monthly record starts (no first month) is drawn lighter */
.chart-line.chart-line-censored{ stroke-width:1.25; stroke-opacity:.45; }
.chart-clip-mark{ opacity:.95; }
.chart-perpair{ margin-left:auto; }
.chart-perpair[disabled]{ opacity:.4; cursor:default; }
.anchor-badge-custom{ background:var(--ember); color:var(--ink); }
.anchor-badge-none{ background:transparent; border:1px solid var(--hair); color:var(--core-dim); }
.anchor-stepper{ display:inline-flex; align-items:center; gap:2px; margin-left:2px; }
.anchor-step{
  background:var(--steel); border:1px solid var(--hair); color:var(--frost);
  font-family:var(--mono); font-size:9px; line-height:1; width:14px; height:14px;
  border-radius:2px; cursor:pointer; padding:0;
}
.anchor-step:hover{ border-color:var(--core-dim); color:var(--ember); }
.anchor-offset{ font-family:var(--mono); font-size:9px; color:var(--core-dim); min-width:16px; text-align:center; }
/* GAP 8 (Run 29): always-visible one-line legend under the chart legend,
   spelling out what F/D/C/-- mean -- the per-badge `title` tooltip stays
   as-is (a hover reveal a user might never trigger), this is the always-
   readable companion the audit asked for. */
.anchor-legend-caption{
  font-family:var(--serif); font-style:italic; font-size:10px;
  color:var(--core-dim); margin:2px 0 6px 0; line-height:1.4;
}

/* metric-selector pill buttons -- reused by the compare view's Bitumen/
   Steam/iSOR/cSOR toggle (the single-scheme chart has no toggle per
   SPEC-v4, but comparing entities on one metric at a time needs one). */
.chart-toggle{
  background:transparent; border:1px solid var(--hair); color:var(--core);
  font-family:var(--mono); font-size:10px; padding:4px 9px; border-radius:12px; cursor:pointer;
}
.chart-toggle.active{ color:var(--ember); border-color:var(--ember-dim); background:var(--ember-wash-2); }

/* SPEC-v8 Leg 3: province filter chip group, same pill look, lives inline
   in the filter bar next to the type/operator facet buttons. */
.chart-toggle-group{ display:flex; gap:6px; align-items:center; }

/* ---- v4: CSV download buttons ---- */
.csv-btn{
  background:transparent; border:1px solid var(--hair); color:var(--core-dim);
  font-family:var(--mono); font-size:9.5px; text-transform:uppercase; letter-spacing:.04em;
  padding:4px 9px; border-radius:2px; cursor:pointer;
}
.csv-btn:hover{ color:var(--ember); border-color:var(--ember-dim); }

/* ---------------------------------------------------------------------
   SPEC-v18 C1: the basin leaderboard -- Board's new front page. Three
   quiet blocks (hero/share/top-10), same 1100px-centered width as the
   Market section and the full table below, so the whole column reads as
   one continuous page rather than a bolted-on header.
   --------------------------------------------------------------------- */
#board-leaderboard{ max-width:1100px; margin:0 auto 18px; display:flex; flex-direction:column; gap:14px; }

/* Box-internal headings for the 3 leaderboard blocks -- deliberately NOT
   .section-label (that class carries its own top border/26px margin, built
   for a mid-card divider between stacked sections; reused verbatim here it
   just adds a bare gap + duplicate rule at the top of a box that already
   has its own border, see the light redesign's card review). */
.leaderboard-box-label{
  font-family:var(--mono); font-size:10px; color:var(--core);
  text-transform:uppercase; letter-spacing:.1em; margin-bottom:2px;
}
#board-hero{ background:var(--steel-2); border:1px solid var(--hair); border-radius:3px; padding:18px 20px; }
.board-hero-top{ display:flex; align-items:center; justify-content:space-between; gap:24px; flex-wrap:wrap; }
.board-hero-value{
  font-family:var(--mono); font-size:36px; font-weight:700; line-height:1;
  color:var(--frost); font-variant-numeric:tabular-nums;
}
.board-hero-unit{ font-size:15px; font-weight:500; color:var(--core); margin-left:7px; }
.board-hero-label{ font-family:var(--mono); font-size:10.5px; color:var(--core-dim); margin-top:7px; max-width:340px; }
/* Board sparkline removed 2026-09-09 (Phil: "i hate this plot"). */

/* Operator share -- 2026-09-01 BOARD REDESIGN (Phil: donut). One card:
   donut with the hero number in the hole, direct-labeled legend ROWS
   (logo carries brand, dot carries slice color, kbpd + % tabular). */
.board-donut-card{ display:flex; align-items:center; gap:28px; flex-wrap:wrap; }
.board-donut-wrap{ position:relative; width:210px; height:210px; flex-shrink:0; }
.board-donut-wrap svg{ width:100%; height:100%; }
.board-donut-hole{
  position:absolute; inset:0; display:flex; flex-direction:column;
  align-items:center; justify-content:center; text-align:center; pointer-events:none;
}
/* 2026-09-20 (Phil: "the bar across the top with % inside the boxes... 2 bars"): two stacked
   share bars replace the donut; the share table gains rate + cSOR columns and square marks. */
.board-bars{ display:flex; flex-direction:column; gap:12px; margin:14px 0 6px; }
.board-bar{ display:flex; width:100%; height:26px; border-radius:3px; overflow:hidden; background:var(--steel); margin-top:5px; }
.board-bar-seg{ display:flex; align-items:center; justify-content:center; min-width:0; overflow:hidden; }
/* 2026-09-28 (Phil: "there are gaps in the boxes"): the 1px inset divider every segment used to carry
   read as a dark gap once the boxes sat inside a bright frame. The colour change between neighbouring
   operator boxes is the divider. */
.board-bar-seg-pct{ font-family:var(--mono); font-size:10.5px; font-weight:700; color:var(--ink); letter-spacing:.01em; white-space:nowrap; text-shadow:0 0 2px rgba(255,255,255,.35); }
.board-bar-seg-tight .board-bar-seg-pct{ font-size:8.5px; }
.board-bar-seg-dark .board-bar-seg-pct{ color:var(--frost); text-shadow:0 0 2px rgba(0,0,0,.5); }
.board-share-head .board-share-dot-none{ visibility:hidden; }
/* COLOUR rule 5: header text is ONE tone -- "SHARE" no longer reads as disabled */
.board-share-head > span{ color:var(--core); }
.board-bar-tall{ height:48px; margin-top:8px; }
.board-bar-tall .board-bar-seg{ position:relative; flex-direction:row; padding:0; box-sizing:border-box; } /* no padding: a padded box cannot draw below its padding, which inflated the smallest shares (Appendix 2, 2026-09-28) */ /* LENS stage 1: no min-width floor (D5/F); see fitBarSegs */
/* LENS stage 1 (2026-09-28, Phil: "put the number beside them to the left, centered vertically, beside the logo in
   the same small font, and then the logo like 2x bigger"): [ percent ][ mark ], one row, both centred on the box's
   middle; the mark is 28px (2x the old 14) and never touches the box edge (bars are >= 36px). */
.board-bar-seg-body{ display:flex; flex-direction:row; align-items:center; justify-content:center; gap:5px; flex-shrink:0; }
.board-bar-seg-top{ display:flex; align-items:center; justify-content:center; flex-shrink:0; }
/* fitBarSegs: measured at natural size; only a box that cannot hold [percent][mark] loses the percent, and only
   a box that cannot hold the mark alone lets it shrink */
.board-bar-seg-striped > .board-bar-seg-body{ position:relative; z-index:2; }
.board-bar-seg-top .board-mark{ height:28px; max-height:28px; width:auto; max-width:100%; object-fit:contain; display:block; }
.seg-noname .board-bar-seg-name{ display:none; }
/* LENS amendment 3 (Phil: "above everything its the rank and the percent, no decimal... for everything"): ONE box
   layout at every level. Line 1: rank (dim) + >= 4px gap + percent (bold). Line 2: the crest / mark, or the name in
   small type (8.5px), dropped when it does not fit -- never dotted. Narrow: drop the rank, then everything but colour. */
.board-bar-tall .board-bar-seg-body{ flex-direction:column; gap:2px; max-width:calc(100% - 4px); min-width:0; flex-shrink:1; }
.lens-nums{ display:flex; align-items:baseline; justify-content:center; gap:4px; white-space:nowrap; line-height:1.05; }
.lens-rank{ font-family:var(--mono); font-size:9px; font-weight:400; color:var(--ink); opacity:.62; font-variant-numeric:tabular-nums; }
.board-bar-seg-dark .lens-rank{ color:var(--frost); }
.lens-nums .board-bar-seg-pct{ font-variant-numeric:tabular-nums; }
.board-bar-tall .board-bar-seg-top{ max-width:100%; min-width:0; flex-shrink:1; }
.board-bar-tall .board-bar-seg-top .board-mark{ max-width:100%; }
.board-bar-tier2 .board-bar-seg-top .board-mark{ height:24px; max-height:24px; }
.board-bar-other .board-bar-seg-top .board-mark{ height:16px; max-height:16px; }
.lens-box .board-bar-seg-name.lens-name{ font-size:8.5px; overflow:visible; text-overflow:clip; }
.seg-norank .lens-rank{ display:none; }
.seg-colour .board-bar-seg-body{ display:none; }
.lens-other-n{ display:none; }
.seg-noname .lens-other-n{ display:inline; }
.lens-other-n{ font-family:var(--mono); font-size:9px; font-weight:700; color:var(--frost); background:rgba(10,4,6,.82); border-radius:3px; padding:1px 4px; }
.lens-box[data-lens-other]{ cursor:pointer; }
/* LENS stage 2: a link box under 28px wide keeps its true width; an invisible 28px hit area catches the tap */
.seg-hit::before{ content:''; position:absolute; top:0; bottom:0; width:28px; z-index:2; }
.seg-hit-start::before{ left:0; }
.seg-hit-mid::before{ left:50%; transform:translateX(-50%); }
.seg-hit-end::before{ right:0; }
/* 2026-09-24 (Phil, review 3: "the little images should also match - i like the ones in the list more
   than the ones in the boxes"): the in-box mark now wears the TABLE's bubble -- same rounded-rect, same
   hairline ring, same proportions as .board-share-dot in the rows below, instead of the old lozenge
   pill. The fill still flips with the box's own tone, because that is what keeps a white mark on a
   white box (CNRL) and a green mark on a green box (Strathcona) readable -- the geometry matches the
   list, the contrast rule stays. */
/* 2026-09-25 (Phil: "drop the background on the buttons in those boxes, except for CNRL and Conoco,
   which should have a black circle behind them") -- the plate is now the exception, and it is a circle. */
.board-hero-wordmark{ display:flex; justify-content:center; margin:0 0 4px; }
.board-hero-wordmark .wordmark-text{ font-size:15px; color:var(--frost); letter-spacing:.16em; }
.board-hero-wordmark .wordmark-text span{ color:var(--ember); } /* THE BAR: on navy the second word is the white accent (the pill's --ember-ink is for the light chip) */
.board-bar-seg-name{ font-family:var(--mono); font-size:7.5px; letter-spacing:0; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:clip; max-width:100%; padding:0; }
.board-bar-seg-dark .board-bar-seg-name{ color:var(--frost); }
/* 2026-09-24 (Phil, review 3: "there are some little line color and color errors"): the bar is
   border-radius + overflow:hidden, so its bottom edge antialiases against the panel behind it and left
   a 1px dark line between the Other box and the ribbon it pours into -- measured at rgb(45,53,57)
   against the teal's rgb(43,111,114). The ribbon rides 1px up over that seam; it only has fill under
   the Other box at its top, so nothing else is covered. The Other box also drops the inset divider
   every other segment carries on its right edge, which was a second dark line at the same corner. */
/* 2026-09-24 (Phil: "it looks like the grey part is all around it. so its contained" -> then "the grey
   ... doesnt actually exactly match... why do we have to use gray? we could do any color. maybe that
   teal color? that is distinct"). The ribbon pours into a frame that closes around bar 2 -- one
   continuous shape, no seam at the join (the ribbon's bottom edge IS the frame's top edge, both full
   width). The two used to be an SVG fill-opacity and a CSS alpha that merely happened to agree; they
   are ONE opaque token now, so they cannot drift and there is no 1px composite seam where they meet.
   Teal (the app accent) knocked back so the operator boxes still win the eye. The fine line runs
   around the OUTSIDE of the whole object: the ribbon's two outer curves (.board-bar-link-edge)
   continue into the wrap's own left/right/bottom border, nothing across either junction. */
:root{
  /* 2026-09-28 (Phil): the Other box, the ribbon and the frame are ONE fill -- the army green -- and
     the frame's edge is the ATLAS neon green, the same accent as the wordmark and the Map/Board pill.
     Previously the fill sat at hue 183, between Cardinal at 186 and Cenovus at 191, which is why the
     Other box read as another Cenovus box. */
  --other-flow:#346f2a; /* the Other box under its member stripes (lensBoxHtml) */
}
/* 2026-09-28: no fill any more -- two hairlines from the Other box's edges out to the bar below.
   Each line wears the frame colour of the box it LEAVES, so colour says where a line came from. */
/* 2026-09-28: .board-other-wrap (the green frame the ribbon poured into) is gone with the ribbon.
   The bars stack directly now, joined only by the hairlines. */
/* 2026-09-25 (Phil: "i want the numbers to be inside the color of the company, so that this bar is
   overall taller"): the rank strip above the bar is gone -- the rank sits at the top of the box, inside
   the operator's own colour, and the box grew by that much. Plain numbers, no medals. */
/* the three tiers: the leader's bar is the tall one, each tier below it a little shorter */
.board-bar-tall.board-bar-lead{ height:72px; }
.board-bar-tall.board-bar-tier2{ height:50px; }
/* 2026-09-28 (Phil: "change the bottom bar border color to be different (white?)"): each tier below
   the leader wears a ring in the SAME colour as the Other box it came from -- neon for tier 2, white
   for tier 3 -- so the frame colour is what carries the depth, all the way down. */
.board-bar-tall.board-bar-other{ height:36px; }
.board-bar-other .board-bar-seg-pct{ font-size:9px; }
/* The Other box's interior: one stripe per member at its true share of the box, and -- where the box
   holds the group that becomes the next bar down -- that group inside its own white frame. */
.board-bar-seg-striped{ position:relative; }
.board-bar-stripes{ position:absolute; inset:0; display:flex; z-index:0; }
.board-bar-substripe{ min-width:0; }
.board-bar-substack{ display:flex; min-width:0; position:relative; }
/* the frame has to paint OVER the stripes, and an inset shadow paints under an element's own
   children -- so every frame here is an overlay pseudo-element. Open at the bottom: that is the
   edge the group leaves from, on its way to becoming its own bar. */
.board-bar-seg-striped > .board-bar-seg-top,
.board-bar-seg-striped > .board-bar-seg-pct{ position:relative; z-index:2; }
/* 2026-09-28 (Phil: "we need to show all the other companies in the 'other' section... we just need
   the colors. and accurate."): the Other box is striped with every operator it holds, in rank order,
   at true proportional widths -- so its label can land on anything from Imperial yellow to Suncor
   black. Both lines ride a dark plate and stop inheriting the light/dark contrast rule. */
.board-bar-seg-striped .board-bar-seg-name,
.board-bar-seg-striped .board-bar-seg-pct{ color:var(--frost); text-shadow:none;
  background:rgba(10,4,6,.82); border-radius:3px; padding:1px 5px; }
.board-bar-seg-striped .board-bar-seg-top{ overflow:visible; }
/* 1.2: the Other box keeps its neon frame on left/top/right -- open at the bottom, because that
   is the edge the ribbon leaves from. Inset so it costs no layout width. */
/* 2026-09-21: the province bar -- Alberta blue / Saskatchewan green, shields, short */
.board-prov-crest{ height:22px; width:auto; flex-shrink:0; }
.board-hero-wordmark{ align-items:baseline; }
.formerly{ font-size:.5em; font-weight:400; color:var(--core); white-space:nowrap; } /* 2026-09-21 (Phil): half the parent size, everywhere */
/* 2026-09-21 SCOPE: the sheet per scope */
.board-hero-home{ cursor:pointer; }
.board-hero-home:hover span{ text-decoration:underline; }
.board-bar-seg[data-scope-op], .board-bar-seg[data-scheme], .board-bar-seg[data-scope-prov]{ cursor:pointer; }
.board-bar-seg[data-scope-op]:hover, .board-bar-seg[data-scheme]:hover{ filter:brightness(1.12); }
/* the compact company KPI row (Phil: "1/3 of the height") */
.company-kpi-row.company-kpi-row-compact{ display:flex; flex-wrap:wrap; gap:6px 16px; margin-top:10px; padding-top:8px; border-top:1px solid var(--hair); }
.company-kpi-row-compact .company-kpi{ flex:0 1 auto; min-width:0; flex-direction:row; align-items:baseline; gap:6px; }
.company-kpi-row-compact .company-kpi-value{ font-size:14px; }
.company-kpi-row-compact .company-kpi-value i{ font-style:normal; font-size:10px; color:var(--core-dim); }
.company-kpi-row-compact .company-kpi-label{ font-size:9px; }
.company-kpi-row-compact .company-kpi-rank{ margin-left:4px; }
/* the operator / province sheet hides the Board's own chrome it has no use for */
/* 2026-09-21 NET PAY, AS FILED: the operator's figure on the card */
.board-share-total{ margin-top:6px; padding-top:6px; border-top:1px solid var(--hair); color:var(--core); }
.board-share-total .board-share-total-value{ color:var(--frost); font-weight:700; }
.board-share-op-row{ cursor:pointer; }
.board-share-op-row:hover .board-donut-opname{ color:var(--ember); }
.off-view{ display:none !important; } /* 2026-09-20: the scheme card + pad sheet leave with the map view */
.board-share-head{ color:var(--core-dim); font-size:10px; letter-spacing:.08em; text-transform:uppercase; margin-top:12px; padding-bottom:4px; border-bottom:1px solid var(--hair); }
.board-share-dot-none{ box-shadow:none; background:transparent; }
.board-mark{ height:16px; width:auto; max-width:30px; flex-shrink:0; object-fit:contain; }
.board-mark-none{ display:inline-block; width:22px; height:16px; }
.board-share-csor{ color:var(--frost); font-variant-numeric:tabular-nums; width:44px; text-align:right; }
/* 2026-09-24 (Phil: "we can tighten up this list of operators, no need for the double spacing in the
   table. Unless we make each operator inside of its own bubble here so that the colors align?"): both.
   The row gap closes up, and the leading dot becomes a BUBBLE in the operator's own colour with its
   mark inside -- the same colour object as its box in the bar above, so the eye carries one colour
   system from the bars down into the table. 30px min-height stays: every row is still a tap target. */
.board-share-legend{ display:flex; flex-direction:column; gap:1px; margin-top:8px; }
.board-share-legend-item{
  display:flex; align-items:center; gap:9px; min-height:30px; /* 2026-09-21 SCOPE: every row a real tap target */
  font-family:var(--mono); font-size:11.5px; color:var(--frost);
}
/* 2026-09-24: the table's own rank column -- the same run of numbers as the strip above the bars. */
.board-share-rank{ width:20px; flex-shrink:0; text-align:right; font-family:var(--mono); font-size:10px;
  font-weight:700; color:var(--core-dim); font-variant-numeric:tabular-nums; }
.board-share-rank-medal{ font-size:13px; }
.board-share-head .board-share-rank, .board-share-total .board-share-rank{ color:transparent; }
.board-share-op-row .board-share-dot{
  width:26px; height:20px; border-radius:6px; display:flex; align-items:center; justify-content:center;
  box-shadow:0 0 0 1px var(--line, rgba(255,255,255,.22));
}
.board-share-op-row .board-share-dot .board-mark{ height:14px; max-width:22px; }
.board-share-dot{ width:9px; height:9px; border-radius:50%; flex-shrink:0; box-shadow:0 0 0 1px rgba(255,255,255,.35); } /* 2026-09-11 brand colours: white and black both read */
.board-share-other{ cursor:pointer; }
.board-share-other-n{ color:var(--core-dim); font-size:10px; }
.board-share-chev{ color:var(--core-dim); display:inline-block; transition:transform .15s; }
.board-share-other.open .board-share-chev{ transform:rotate(180deg); }
.board-share-other-list{ display:flex; flex-direction:column; gap:6px; margin:2px 0 4px 18px; padding-left:10px; border-left:1px solid var(--hair); }
.board-share-other-row{ cursor:pointer; }
.board-share-other-row:hover .board-donut-opname{ color:var(--ember); }
.board-hero-intro{ margin-bottom:14px; }
.board-hero-kicker{ font-family:var(--mono); font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--ember); }
.board-hero-title{ font-size:17px; font-weight:600; line-height:1.3; color:var(--frost); margin:4px 0 6px; max-width:640px; }
.board-hero-facts{ font-family:var(--mono); font-size:11px; color:var(--core); }
.board-hero-hint{ color:var(--core-dim); }
.flow-hub-hidden{ display:none; }
.board-donut-nologo{ width:56px; flex-shrink:0; }
.board-share-legend-item img, .board-share-legend-item .logo-chip{ width:56px; flex-shrink:0; }
.board-donut-opname{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.board-donut-kbpd{ color:var(--frost); font-variant-numeric:tabular-nums; white-space:nowrap; } /* 2026-09-13 (Phil #6): "140.7 kbpd" wrapped on the ConocoPhillips row */
.board-donut-unit{ color:var(--core-dim); font-size:10px; } /* 2026-09-09 (Phil, phone pass #3): the value states its unit */
.board-share-pct{ color:var(--core-dim); font-variant-numeric:tabular-nums; width:48px; text-align:right; }
.src-info{ color:var(--core-dim); text-decoration:none; font-size:11px; }
.src-info:hover{ color:var(--ember); }


/* THE BAR (2026-09-30): the Map|Board segmented switch (#view-seg) is retired; #view-handle is the way back to the map */





@media (max-width:640px){
  .board-hero-top{ flex-direction:column; align-items:flex-start; gap:14px; }
  .board-hero-value{ font-size:30px; }
  /* 2026-09-11 (Phil, 3.5 circles 5/6: dead space beside a centred donut): donut left,
     legend beside it, logos dropped -- one row, no empty band */
  .board-donut-card{ gap:12px; flex-wrap:nowrap; align-items:flex-start; }
  .board-donut-wrap{ margin:0; }
  /* 2026-09-13 (Phil #6: the rate wrapped) + 09-15 live retina (names then truncated): unit moves to
     the header, pct sizes to content, tighter gap, "7 operators" sub-label hidden -- measured on the
     live phone: every operator name incl. ConocoPhillips fits at 120px donut / 172px legend */
  .board-share-legend-item .board-donut-unit, .board-share-other-n{ display:none; }
  .board-donut-kbpd{ font-size:10.5px; }
  .board-share-legend-item{ gap:4px; }
  /* 2026-09-19 (Phil: "the list of sagd companies is ok, not great, maybe we can put the logos for
     the companies in there too?"): compact marks come back on the phone rows -- 14px tall, capped
     at 40px wide, sized to the row that no longer wraps (09-15) */
  .board-share-legend-item .logo-chip{ height:14px !important; width:auto !important; max-width:32px !important; flex-shrink:0; }
  .board-share-legend-item .logo-chip img{ height:14px !important; max-width:32px !important; }
  .board-donut-nologo{ width:32px; }
  .board-share-legend-item{ font-size:11px; gap:5px; }
  /* the phone row is dot + mark + name + share%: the kbpd moves to the Board table below (measured:
     every name incl. ConocoPhillips fits at donut 96 / legend 196) */
  .board-donut-wrap{ width:96px; height:96px; }
  /* 2026-09-20: the phone row is dot + mark + name + rate + cSOR + share% (Phil: "ensure bbl/d, sor,
     and % are shown") -- the donut that crowded them out is gone */
  .board-share-legend > .board-share-legend-item .board-share-pct{ color:var(--frost); }
  .board-share-csor{ width:38px; font-size:10.5px; }
  .board-mark{ height:14px; max-width:24px; }
  .board-mark-none{ width:18px; height:14px; }
  .board-bar{ height:22px; }
  .board-bar-tall{ height:44px; }
  .board-prov-crest{ height:20px; }
  .board-bar-seg-pct{ font-size:9.5px; }
  #board-hero .board-donut-hole .board-hero-value{ font-size:16px; }
  #board-hero .board-donut-hole .board-hero-unit{ font-size:11px; }
  .board-share-pct{ width:auto; min-width:32px; font-size:10.5px; padding-left:12px; } /* design standard D2: >= 12px gutter before a numeric column */
  /* nested Other rows: shallower indent, no pct (their shares are all <2%) so the operator name fits */
  .board-share-other-list{ margin-left:6px; padding-left:6px; }
  .board-share-other-list .board-share-csor{ display:none; } /* nested rows: name + rate + share% */
  .board-share-other-list .board-share-pct{ color:var(--frost); }
  .board-hero-title{ font-size:15px; }
}
@media (max-width:400px){
  .board-top10-kpi{ min-width:36px; }
}

/* ---------------------------------------------------------------------
   SPEC-v33 Q2: every logo chip / operator-name link app-wide. One shared
   affordance -- [data-op-slug] is the attribute logoChip() (JS) stamps on
   ALL ~9+ of its call sites for free, plus the handful of standalone
   operator-NAME text spans (.op-link) that carry the same attribute.
   wireOperatorLinks() (app.js) is the one delegated click handler. */
[data-op-slug]{ cursor:pointer; }
.op-link{ cursor:pointer; }
.op-link:hover{ color:var(--ember); text-decoration:underline; }
.logo-chip[data-op-slug]:hover{ filter:brightness(1.15); }
.logo-chip[data-op-slug]:focus-visible, .op-link:focus-visible{
  outline:1px solid var(--ember); outline-offset:2px; border-radius:2px;
}

/* the company KPI row (the lens's company and project levels use it; the old company page that first
   wore it is gone, PLAN 2 item 8 step 3) */
.company-kpi-row{ display:flex; flex-wrap:wrap; gap:14px; margin-top:16px; padding-top:14px; border-top:1px solid var(--hair); }
.company-kpi{ flex:1; min-width:120px; display:flex; flex-direction:column; gap:3px; }
.company-kpi-value{ font-family:var(--mono); font-size:22px; font-weight:700; color:var(--frost); font-variant-numeric:tabular-nums; }
.company-kpi-label{ font-family:var(--mono); font-size:10px; color:var(--core-dim); text-transform:uppercase; letter-spacing:.06em; }
.company-kpi-rank{ color:var(--ember); text-transform:none; letter-spacing:0; }



/* ---- modal shell (picker overlay) -- steel/hairline/mono language
   shared with the facet menus, scaled up to a centered modal. ---- */
.modal-overlay{
  position:fixed; inset:0; z-index:60; background:rgba(27,9,12,.72);
  backdrop-filter:blur(3px); display:flex; align-items:center; justify-content:center; padding:20px;
}
/* display:flex overrides the UA's [hidden]{display:none} -- without this
   the overlay renders OPEN on page load and blocks every click (same bug
   class as #panel-empty[hidden], fixed 2026-07-23; any element that pairs
   the hidden attribute with a display rule needs this override). */
.modal-overlay[hidden]{ display:none; }
.modal-panel{
  background:var(--steel); border:1px solid var(--hair); border-radius:2px;
  width:100%; max-width:920px; max-height:82vh; display:flex; flex-direction:column;
  box-shadow:0 24px 64px rgba(0,0,0,.55);
}
.modal-header{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px 12px;
  padding:14px 18px; border-bottom:1px solid var(--hair); flex-shrink:0;
}
.modal-header h2{
  font-family:var(--display); font-weight:700; font-size:16px; letter-spacing:.04em;
  text-transform:uppercase; color:var(--frost); margin:0;
}
.modal-header-actions{ display:flex; align-items:center; gap:8px; }
.modal-close{
  /* same 30x30 icon-button convention as the old #panel-close -- not the asymmetric
     44x30 an earlier draft of this rule accidentally produced by mixing
     width and min-width. */
  background:transparent; border:1px solid var(--hair); color:var(--core);
  width:30px; height:30px; border-radius:2px;
  cursor:pointer; font-size:15px; line-height:1;
  display:flex; align-items:center; justify-content:center;
}
.modal-close:hover{ color:var(--frost); border-color:var(--core-dim); }
.modal-body{ overflow:auto; -webkit-overflow-scrolling:touch; padding:12px 18px 18px; }
.modal-note{
  font-family:var(--serif); font-style:italic; font-size:12px; color:var(--core);
  line-height:1.5; margin:2px 0 14px;
}
/* ---- SPEC-v34 P5: the Figures full-screen viewer -- same modal-overlay/
   modal-panel/modal-close shell above, sized for an image instead of a
   table. Zoom is a plain click-to-scale toggle on the image itself (see
   wireFigureViewerZoom in app.js), not a modal-panel transform. ---- */
.figure-viewer-panel{ max-width:min(1400px, 96vw); max-height:94vh; }
.figure-viewer-body{ display:flex; flex-direction:column; gap:10px; align-items:center; }
.figure-viewer-imgwrap{
  width:100%; flex:1 1 auto; min-height:0; overflow:auto; display:flex;
  align-items:center; justify-content:center; background:#150709; border:1px solid var(--hair);
}
.figure-viewer-img{ max-width:100%; max-height:78vh; display:block; cursor:zoom-in; transition:transform .15s ease; touch-action:none; }
.figure-viewer-img.zoomed{ cursor:zoom-out; max-width:none; max-height:none; }
.figure-viewer-caption{ font-family:var(--serif); font-style:italic; font-size:12.5px; color:var(--core); text-align:center; }
.figure-viewer-nav{ display:flex; align-items:center; gap:14px; }
.figure-viewer-pos{ font-family:var(--mono); font-size:11px; color:var(--core-dim); }

/* ---- SPEC-v10 C3/C4: the cross-project pad/project picker -- same
   modal-overlay/modal-panel shell above, widened (more columns), plus a
   real filter/search/sort table. ---- */
.modal-panel-wide{ max-width:1180px; }
.picker-cap-note{
  font-family:var(--mono); font-size:10.5px; color:var(--core-dim);
  white-space:nowrap; padding:4px 8px; border:1px solid var(--hair); border-radius:2px;
}
#picker-tabs.tabs{ margin-top:0; padding-top:0; border-top:none; margin-bottom:10px; }
#picker-toolbar{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin-bottom:12px; }
#picker-search{
  flex:1 1 220px; min-width:180px; background:var(--steel-2); border:1px solid var(--hair); color:var(--frost);
  font-family:var(--mono); font-size:12px; padding:7px 10px; border-radius:2px;
}
.picker-filters{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; }
.picker-filters select, .picker-filters input[type="number"]{
  background:var(--steel-2); border:1px solid var(--hair); color:var(--frost);
  font-family:var(--mono); font-size:11px; padding:6px 8px; border-radius:2px;
}
.picker-filters input[type="number"]{ width:96px; }
.picker-filters select[multiple]{ min-width:130px; height:30px; }
#picker-table-wrap{ overflow:auto; max-height:52vh; }
#picker-table{ width:100%; border-collapse:collapse; font-family:var(--mono); font-size:11.5px; font-variant-numeric:tabular-nums; }
#picker-table th{
  position:sticky; top:0; background:var(--steel); color:var(--core-dim); z-index:1;
  text-align:left; padding:8px 10px; border-bottom:1px solid var(--hair);
  white-space:nowrap; font-weight:400; text-transform:uppercase; font-size:9.5px; letter-spacing:.05em;
}
#picker-table th.sortable{ cursor:pointer; }
#picker-table th.sortable:hover{ color:var(--frost); }
#picker-table th.sortable.active{ color:var(--ember); }
#picker-table th.num, #picker-table td.num{ text-align:right; }
#picker-table td{ padding:6px 10px; color:var(--frost); border-bottom:1px solid var(--hair); vertical-align:middle; white-space:nowrap; }
#picker-table tr.picker-row{ cursor:pointer; }
#picker-table tr.picker-row:hover{ background:var(--steel-2); }
#picker-table tr.picker-row.checked{ background:rgba(216,118,48,.08); }
#picker-table tr.picker-row-unqualified{ opacity:.7; }
.picker-check-cell{ width:26px; }
.picker-check-cell input{ cursor:pointer; }
.picker-op-name{ margin-left:6px; color:var(--core); font-size:10.5px; }
.picker-unqualified{ color:var(--core-dim); margin-left:3px; cursor:help; }
.picker-empty{ text-align:center; color:var(--core-dim); font-family:var(--serif); font-style:italic; padding:20px !important; white-space:normal !important; }
#compare-empty #picker-open-btn-empty{ margin-top:14px; }
.chart-wrap{ position:relative; }
#prod-chart-svg{ display:block; overflow:visible; }
.chart-axis-title{ font-family:var(--mono); font-size:8px; fill:var(--core-dim); }
/* Batch E papercut fix (found by a real hover probe): these 1px chrome
   strokes paint AFTER #chart-hitarea, so a cursor landing exactly on a
   year gridline swallowed the crosshair (readout flicker while
   scrubbing). Same pointer-events:none discipline as .chart-line above. */
.chart-gridline, .chart-gridline-year, .chart-panel-divider, .chart-xtick-minor, .chart-future-divider{ pointer-events:none; }
.chart-gridline{ stroke:var(--hair); stroke-width:1; }
.chart-gridline-year{ stroke:var(--hair); }
.chart-panel-divider{ stroke:var(--hair); stroke-width:1; }
.chart-ytick{ font-family:var(--mono); font-size:8px; fill:var(--core-dim); text-anchor:end; }
.chart-xtick{ font-family:var(--mono); font-size:8px; fill:var(--core-dim); text-anchor:middle; }
.chart-xtick-minor{ stroke:var(--hair); stroke-width:1; }
/* Batch D: data marks must never swallow the crosshair -- SVG hit-testing
   gives the topmost painted element the event, and the lines/area fills
   paint AFTER the hitarea, so hovering exactly on a line (or anywhere over
   the bitumen area fill) silently killed the readout on EVERY chart. The
   suspension bands keep their events (they have their own card). */
.chart-line, .chart-area, .chart-end-dot, .chart-end-label{ pointer-events:none; }
.chart-area{ stroke:none; }
.chart-area-bitumen{ fill:var(--bitumen-wash); }
.chart-line{ fill:none; stroke-width:2; stroke-linejoin:round; stroke-linecap:round; }
.chart-line-bitumen{ stroke:var(--bitumen); }
.chart-line-steam{ stroke:var(--steam); }
.chart-line-isor{ stroke:var(--frost); stroke-width:1.5; }
.chart-line-csor{ stroke:var(--csor); stroke-width:1.5; }
/* SPEC-v32 Batch E: compared-pad lines -- thinner than the scheme total's
   own 2px + area fill, so the visual hierarchy (scheme primary, pads
   secondary) holds at a glance; stroke color is inlined per pad from the
   compare palette. */
.chart-line-pad{ stroke-width:1.4; }
.chart-empty-inline{ font-family:var(--mono); font-size:9px; fill:var(--core-dim); text-anchor:middle; }

/* ---- v6 S3: events ON the chart -- suspension bands, point flags, the
   future-plans gutter. Colors reuse the same group tokens the app already
   assigns lifecycle/disruptions/technology/regulatory elsewhere. ---- */
.chart-suspend-band{ fill:var(--core-dim); opacity:.14; cursor:pointer; }
.chart-suspend-band:hover{ opacity:.24; }
/* ---- SPEC-v32 Batch D: charts overhaul. A quiet 45-degree hatch rides on
   top of the suspension wash (pattern defined in the chart's own <defs>)
   so an outage band reads as "outage" even where it's narrow --
   pointer-events:none so the wash underneath keeps its hover/tap card. ---- */
.chart-suspend-hatch{ fill:url(#chart-susp-hatch-p); pointer-events:none; }
.chart-susp-hatch-line{ stroke:var(--core-dim); stroke-width:1; opacity:.13; }
/* Latest-point end dots (ringed in the panel surface so they stay legible
   over their own line) + the latest value direct-labeled in the gutter. */
.chart-end-dot{ stroke:var(--steel); stroke-width:1.5; }
.chart-end-dot-bitumen{ fill:var(--bitumen); }
.chart-end-dot-steam{ fill:var(--steam); }
.chart-end-label{ font-family:var(--mono); font-size:9px; font-weight:600; fill:var(--bitumen); }
.chart-end-label-steam{ fill:var(--steam); font-weight:400; }
/* Pinch-zoom's visible escape hatch -- overlaid top-right of .chart-wrap
   (position:relative above), only rendered while a zoom window is live. */
.chart-zoom-reset{
  position:absolute; top:0; right:0; z-index:5;
  font-family:var(--mono); font-size:10px; color:var(--core);
  background:var(--steel); border:1px solid var(--hair); border-radius:2px;
  padding:4px 9px; cursor:pointer; line-height:1;
}
.chart-zoom-reset:hover{ color:var(--frost); border-color:var(--core-dim); }
.chart-flag{ cursor:pointer; }
.chart-flag-guide{ stroke:var(--hair); stroke-width:1; }
.chart-flag-lifecycle path{ fill:var(--ember); }
.chart-flag-disruptions path{ fill:var(--frost); }
.chart-flag-technology path{ fill:var(--good); }
.chart-flag-regulatory path{ fill:var(--core); }
.chart-flag:hover path{ transform:scale(1.3); transform-origin:0 4px; }
.chart-flag-overflow{ font-family:var(--mono); font-size:7.5px; fill:var(--core-dim); }
.chart-future-divider{ stroke:var(--hair); stroke-width:1; stroke-dasharray:2 2; }
.chart-future-flag{ cursor:pointer; }
.chart-future-flag circle{ fill:none; stroke:var(--core-dim); stroke-width:1.3; }
.chart-future-flag:hover circle{ stroke:var(--ember-dim); }

/* ---- ROADMAP #5: the chart's reservoir-hazard marker, on --ember-dim (existing token) ---- */
.chart-hazard-flag{ cursor:pointer; }
.chart-hazard-flag path{ fill:var(--ember-dim); }
.chart-hazard-flag:hover path{ transform:scale(1.3); transform-origin:0 12px; }
/* Batch D (found while judging retina shots, present on live too): SVG
   elements don't get the UA's [hidden]{display:none} the way HTML does, so
   the crosshair's parked circles ghosted a few pixels at their default
   (0,0) top-left corner. Make hidden actually mean hidden. */
/* Batch E papercut fix, same probe: the crosshair vline snaps to the
   nearest month -- when that lands exactly under the cursor, hovering
   your own crosshair fired the hitarea's mouseleave and killed the
   readout at rest. A crosshair is display-only chrome; never a hover
   target (applies to every chart sharing this class). */
.chart-crosshair{ pointer-events:none; }
.chart-crosshair[hidden]{ display:none; }
.chart-crosshair .ch-vline{ stroke:rgba(231,238,243,.5); stroke-width:1; stroke-dasharray:2 2; }
.chart-crosshair circle{ stroke:var(--ink); stroke-width:2; }
.ch-dot-bitumen{ fill:var(--bitumen); }
.ch-dot-steam{ fill:var(--steam); }
.ch-dot-sor{ fill:var(--frost); }
.ch-dot-csor{ fill:var(--csor); }
#chart-hitarea{ cursor:crosshair; touch-action:none; }
.chart-empty{ font-family:var(--mono); font-size:11px; color:var(--core-dim); padding:20px 0; }
.chart-tooltip{
  position:fixed; z-index:50; pointer-events:none;
  background:var(--steel); border:1px solid var(--hair); border-radius:2px;
  padding:7px 10px; box-shadow:0 8px 24px rgba(0,0,0,.5);
  font-family:var(--mono); max-width:240px;
}
.chart-tooltip .ctt-date{ font-size:9.5px; color:var(--core-dim); margin-bottom:4px; }
.chart-tooltip .ctt-row{ display:flex; align-items:center; gap:6px; margin-top:2px; }
.chart-tooltip .ctt-dot{ width:6px; height:6px; border-radius:50%; flex-shrink:0; }
.chart-tooltip .ctt-dot-bitumen{ background:var(--bitumen); }
.chart-tooltip .ctt-dot-steam{ background:var(--steam); }
.chart-tooltip .ctt-dot-sor{ background:var(--frost); }
.chart-tooltip .ctt-dot-csor{ background:var(--csor); }
.chart-tooltip .ctt-value{ font-size:12px; color:var(--frost); font-weight:500; }
/* RUN 19: benchmark scatter tooltip's operator+scheme row, logo-first same
   as everywhere else this leg touched. */
.chart-tooltip .ctt-name-row{ display:flex; align-items:center; gap:6px; }
.chart-tooltip .ctt-label{ font-size:9.5px; color:var(--core-dim); white-space:normal; }
.chart-tooltip .ctt-quote{ font-family:var(--serif); font-style:italic; font-size:11.5px; color:var(--core); margin-top:5px; line-height:1.4; white-space:normal; }
.chart-tooltip .ctt-cite{ font-family:var(--mono); font-size:9px; color:var(--core-dim); margin-top:3px; }
.chart-tooltip .ctt-diff{ margin-top:5px; padding-top:5px; border-top:1px solid var(--hair); font-size:10px; color:var(--core); }

/* ---- v3: History / Planned tabs ---- */
/* flex-wrap: three tabs (History/Planned/Superseded, Leg C) plus their
   count badges can exceed a narrow phone's panel width -- same overflow
   risk the chart toolbar hit earlier this project, same fix. Harmless on
   desktop where they already fit on one line. */
.tabs{ display:flex; flex-wrap:wrap; gap:2px; margin-top:26px; padding-top:16px; border-top:1px solid var(--hair); }
.tab-btn{
  background:transparent; border:1px solid var(--hair); border-bottom:none; color:var(--core);
  font-family:var(--mono); font-size:10.5px; text-transform:uppercase; letter-spacing:.06em;
  padding:7px 12px; cursor:pointer; border-radius:2px 2px 0 0;
}
.tab-btn.active{ color:var(--ember); background:var(--steel-2); border-color:var(--hair); }
.tab-count{ color:var(--core-dim); margin-left:4px; }
.tab-btn.active .tab-count{ color:var(--ember-dim); }
.tab-meta{ font-family:var(--mono); font-size:10px; color:var(--core-dim); padding:8px 0 4px; border-bottom:1px solid var(--hair); margin-bottom:10px; }

/* timeline */
.timeline{ position:relative; padding-left:18px; }
.timeline::before{
  content:''; position:absolute; left:4px; top:4px; bottom:4px; width:1px;
  background:linear-gradient(var(--hair), var(--hair) 90%, transparent);
}
.tl-item{ position:relative; margin-bottom:16px; }
.tl-item::before{
  content:''; position:absolute; left:-18px; top:4px;
  width:7px; height:7px; border-radius:50%;
  background:var(--core-dim); border:2px solid var(--steel);
}
.tl-item.event::before{ background:var(--ember); }
.tl-item.plan::before{ background:transparent; border:1.5px solid var(--core-dim); }
.tl-date{ font-family:var(--mono); font-size:10.5px; color:var(--core); letter-spacing:.03em; }
.tl-type{ font-family:var(--mono); font-size:10.5px; color:var(--ember); text-transform:uppercase; letter-spacing:.05em; margin-left:8px; }
.tl-type.plan-type{ color:var(--core); }
.tl-pad{ font-family:var(--mono); font-size:10px; color:var(--core-dim); }
.tl-quote{
  font-family:var(--serif); font-style:italic; font-size:14px; line-height:1.5;
  color:var(--frost); margin:5px 0 4px;
}
.tl-cite{ font-family:var(--mono); font-size:9.5px; color:var(--core-dim); }
.tl-cite a{ color:var(--core-dim); }
.confidence-low .tl-quote{ color:var(--core); }
.confidence-low .tl-cite::after{ content:' · low confidence'; color:var(--ember-dim); }

/* ---- v2: collapsed-by-default timeline rows (progressive disclosure) ---- */
.tl-row{ cursor:pointer; user-select:none; display:flex; align-items:baseline; gap:0; }
.tl-row:hover .tl-date{ color:var(--frost); }
.tl-row::before{
  content:'▸'; display:inline-block; width:12px; color:var(--core-dim);
  font-size:9px; transition:transform .15s ease;
}
.tl-item.expanded .tl-row::before{ transform:rotate(90deg); }
.tl-detail{
  font-family:var(--mono); font-size:11px; color:var(--core); margin:2px 0 0 12px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.tl-item.expanded .tl-detail{ display:none; }
.tl-expand-body{
  max-height:0; overflow:hidden; margin-left:12px;
  transition:max-height .25s ease;
}
.tl-item.expanded .tl-expand-body{ max-height:400px; }
.tl-item.expanded .tl-quote{ margin-top:6px; }
.tl-item mark{ background:var(--ember); color:var(--ink); padding:0 1px; border-radius:1px; }

/* ---- SPEC-v32 Batch G: templated annual scheme-year summaries ----
   The Filings feed's new lead surface (Annual tab / SK cards). One
   compact row per year (year + tabular-nums KPI strip), newest first,
   newest year open; the expanded body carries the full template with a
   cite on every line -- same tl-cite idiom as the raw rows. KPI strip is
   .fit-text (no-truncation covenant: fonts shrink, data never
   ellipsizes); body lines wrap, never clip. */
.annual{ margin-top:2px; }
.an-item{ border-bottom:1px solid var(--hair); padding:2px 0 8px; }
.an-item:last-child{ border-bottom:none; }
.an-row{ cursor:pointer; user-select:none; display:flex; align-items:baseline; gap:10px; padding:6px 0 2px; }
.an-row::before{
  content:'▸'; display:inline-block; width:12px; color:var(--core-dim);
  font-size:9px; transition:transform .15s ease; flex-shrink:0;
}
.an-item.expanded .an-row::before{ transform:rotate(90deg); }
.an-year{ font-family:var(--mono); font-size:12px; font-weight:700; color:var(--ember); letter-spacing:.03em; flex-shrink:0; }
.an-row:hover .an-year{ color:var(--frost); }
.an-kpis{
  font-family:var(--mono); font-size:11.5px; color:var(--frost);
  font-variant-numeric:tabular-nums; white-space:nowrap; overflow:hidden;
  min-width:0; /* let the fit-text pass measure a real overflow instead of the flex item refusing to shrink */
}
.an-body{ display:none; margin-left:12px; }
.an-item.expanded .an-body{ display:block; }
.an-sec{ margin:8px 0 0; }
.an-sec-label{
  font-family:var(--mono); font-size:9px; color:var(--core-dim); text-transform:uppercase;
  letter-spacing:.08em; margin-bottom:2px;
}
.an-line{ font-family:var(--mono); font-size:11.5px; color:var(--core); line-height:1.55; font-variant-numeric:tabular-nums; }
.an-line b{ color:var(--frost); font-weight:700; }
.an-note{ font-family:var(--mono); font-size:11px; color:var(--core); line-height:1.5; margin:2px 0 0 10px; }
.an-note::before{ content:'– '; color:var(--core-dim); }
.an-comp{ font-family:var(--mono); font-size:11px; color:var(--core); line-height:1.5; margin:3px 0 0; }
.an-comp-field{
  display:inline-block; font-size:9px; color:var(--ember-dim); text-transform:uppercase;
  letter-spacing:.06em; border:1px solid var(--hair); border-radius:2px; padding:0 4px; margin-right:4px;
}
.an-comp-stub{ font-style:italic; color:var(--core-dim); }
.an-cite{ display:inline; margin-left:2px; white-space:nowrap; }
.an-sec > .tl-cite{ display:block; margin-top:1px; }

/* ---- search / filters -- SPEC-v17 B2: re-housed inside the ☰ drawer
   (was a permanent top-of-screen filter bar). Same controls/ids/wiring,
   just full-width in the drawer's own narrower column now. ---- */
.filter-search{ position:relative; width:100%; }


.chip{
  background:var(--ember-wash-2); border:1px solid var(--ember-dim); color:var(--frost);
  font-family:var(--mono); font-size:10.5px; padding:4px 8px; border-radius:12px; cursor:pointer;
}
.chip:hover{ background:var(--ember-wash-3); }
.chip-clear{ background:transparent; border-color:var(--hair); color:var(--core-dim); }

/* ---- SPEC-v23 D1 (Run 57, ratified kill): the old #timebar/#rewind-chip/
   #timebar-controls/#play-btn/#year-slider chrome (SPEC-v17 B5, restyled
   SPEC-v18 C2) is REMOVED entirely -- "everything is NOW", no map-level
   year lever. Epitaph in the brain log; recoverable from git history for
   a demo day. */
.full-toggle{
  display:flex; align-items:center; gap:5px; font-family:var(--mono); font-size:10px;
  color:var(--core-dim); cursor:pointer; flex-shrink:0; white-space:nowrap;
}
.full-toggle input{ accent-color:var(--ember); }


.clear-filters-inline{
  display:block; width:100%; margin:8px 0 0; padding:6px 10px;
  background:transparent; border:1px dashed var(--ember-dim); color:var(--ember);
  font-family:var(--mono); font-size:10.5px; border-radius:2px; cursor:pointer;
}
.clear-filters-inline:hover{ background:var(--ember-wash-1); }
.loading{ font-family:var(--mono); color:var(--core); font-size:11px; }

.year-divider{
  font-family:var(--mono); font-size:11px; color:var(--core-dim);
  margin:18px 0 10px 0; padding-left:0;
  display:flex; align-items:center; gap:10px;
}
.year-divider::after{ content:''; flex:1; height:1px; background:var(--hair); }

#panel-empty{
  height:100%; display:flex; flex-direction:column; align-items:center; justify-content:center;
  color:var(--core-dim); font-family:var(--mono); font-size:12px; text-align:center; padding:40px;
}
/* the hidden attribute must actually win over display:flex */
#panel-empty[hidden]{ display:none; }

@media (max-width: 640px){
  /* SPEC-v27 C (Run 71): the 100vw full-screen takeover DIES -- the card
     becomes a draggable BOTTOM SHEET with three detents (Phil 2026-07-29:
     "the card tab comes up at the bottom, like peek, and you can swipe
     up"). Backdrop-free on purpose: the map stays fully interactive
     (pannable/tappable) at PEEK and HALF, per B1's own reveal choreography.
     #panel-drag (app.js) drives detent switching by setting
     data-detent + an inline --drag-h custom property while a touch drag
     is live; CSS handles the resting heights and the open/close slide. */
  #panel{
    left:0; right:0; top:auto; bottom:0; width:100%;
    height:var(--drag-h, 152px);
    max-height:92vh; min-height:100px;
    border-left:none; border-top:1px solid var(--hair);
    border-radius:16px 16px 0 0;
    transform:translateY(calc(100% + 20px));
    transition:transform .32s cubic-bezier(.2,.8,.2,1), height .28s cubic-bezier(.2,.8,.2,1);
    box-shadow:0 -14px 36px rgba(0,0,0,.4);
    padding-bottom:env(safe-area-inset-bottom, 0);
  }
  #panel.open{ transform:translateY(0); }
  #panel.dragging{ transition:none; }
  /* 2026-09-10 (Phil: "1/5 bottom project scope"): PEEK is a fifth of the
     screen, floor 168px -- app.js's sheetPeekPx() is the same number. */
  #panel[data-detent="peek"]{ height:var(--drag-h, max(20vh, 168px)); }
  #panel[data-detent="peek"] .peek-kpis{ display:block; margin:2px 0 0; }
  .peek-kpis .map-popup-kpis{ display:grid; grid-template-columns:repeat(3, 1fr); gap:6px 10px; padding:0; margin:0; border:none; }
  .peek-kpis .popup-kpi-row{ display:flex; flex-direction:column; align-items:flex-start; gap:2px; padding:0; border:none; }
  /* at PEEK the bar is identity + KPIs; badges/formation belong to the card */
  #panel[data-detent="peek"] .scheme-badges, #panel[data-detent="peek"] .scheme-formation-line, #panel[data-detent="peek"] .scheme-stat-block, #panel[data-detent="peek"] .econ-row, #panel[data-detent="peek"] .stat-corroboration, #panel[data-detent="peek"] .scheme-hazard-line, #panel[data-detent="peek"] .section{ display:none; } /* 2026-09-19 circles 7/8: the peek bar is name + 3 KPIs, nothing peeking out below */
  #panel[data-detent="peek"] #panel-scroll{ overflow:hidden; }
  #panel[data-detent="peek"] .peek-kpis{ margin-bottom:40vh; } /* nothing after the 3 KPIs shows inside the 20vh window (the rest stays in the DOM for the FULL detent) */
  #panel[data-detent="peek"] .scheme-header-top{ padding-bottom:2px; }
  #panel[data-detent="peek"] .scheme-header-top .logo-chip{ height:30px !important; max-width:110px !important; }
  #panel[data-detent="peek"] .scheme-name{ font-size:22px; }
  #panel[data-detent="half"]{ height:var(--drag-h, 48vh); }
  #panel[data-detent="full"]{ height:var(--drag-h, 90vh); }
  /* the drag handle IS the touch target (app.js's touchstart/move/end) --
     44px tall hit area, small visual pill centered inside it, same "tap
     target decouples from the visual mark" discipline A8's map hit-circles
     already established. SPEC-v33 K1 (Phil: "how does one make the card
     come up more" -- the handle's REAL hit height had drifted to 26px,
     silently contradicting this very comment, and its pill was painted
     var(--hair), the exact same color as an ordinary hairline border --
     an honestly invisible affordance, not a broken one). Restored to the
     documented 44px target with a brighter, unmistakably-a-handle pill. */
  #panel-handle{
    display:flex; align-items:center; justify-content:center;
    width:100%; height:44px; flex-shrink:0; touch-action:none; cursor:grab;
  }
  #panel-handle::before{
    content:''; width:44px; height:5px; border-radius:3px;
    background:var(--core);
  }
  #panel-scroll{ height:calc(100% - 44px); padding-top:2px; }
  /* SPEC-v33 K1: the visible sheet BODY is now a second, equally-real drag
     source (app.js's wireSheetDrag delegates the same physics onto
     .scheme-header-top, the always-on-top row of every open card) -- most
     users try to drag the CARD, not a hairline strip above it. touch-action
     none here for the same reason the handle needs it (else the browser's
     own scroll-gesture recognizer can beat wireSheetDrag's touchmove to the
     punch); cursor:grab is a desktop-pointer hint only, harmless on touch. */
  .scheme-header-top{ touch-action:none; cursor:grab; }

  /* SPEC-v17 B1: the old #legend/#masthead/#filterbar mobile-stacking
     arithmetic (a 3-row bar growing to 253px tall, clearing it with
     hand-measured padding) is GONE along with that chrome -- #nav-cluster
     is a small fixed-size cluster (wordmark chip + 44px bubble row) that
     doesn't grow at narrow widths, so #board/#compare's shared 112px
     top-clear (see the base rule) already works here with no override.
     The ☰ drawer is a full-height slide-in panel (own rules above), not a
     stacked bar, so it needs no mobile-specific repositioning either. */
  #compare-scroll{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  /* SPEC-v7 D2 mobile acceptance: the entity table keeps its natural
     column width and scrolls horizontally WITHIN its own wrapper (sticky
     row-label column stays put) -- .entity-table-scroll already does this
     unconditionally (see its own rule above), this just tightens sizing
     for a phone-width viewport, same pattern as #compare-table. */

  /* SPEC-v4: "lots of iphone users" -- bump tap targets closer to the
     44px iOS/Android minimum; desktop's tighter sizing stays for mouse. */
  .csv-btn{ padding:7px 12px; font-size:10.5px; }
  .tab-btn{ padding:10px 14px; }
  .collapse-header{ padding:16px 0 10px; }
  .chart-clear-well{ padding:6px 0; }
  .compare-toggle-btn{ padding:6px 10px; }
  .compare-remove{ width:30px; height:30px; }

  /* HARDENING (2026-07-24, Run 7 Leg 2c): the remaining three named
     surfaces' own tap targets, measured live (Playwright, 375px) and
     found under the ~40px bar -- `.chart-toggle` pills (Operators ticker
     picker + the "Operators" sub-toggle button + the geomap page-picker,
     all three reuse this one class) were ~23px tall; `.full-toggle`
     labels (Pipelines/Show non-operating checkboxes)
     measured 0 height because their native `<input>` is visually hidden
     and only the `<label>` wraps text+checkbox -- forcing a min-height on
     the label itself (not the input) is what actually grows the tap
     target. Desktop's tighter mouse sizing is untouched (scoped to this
     media query only, same convention as every other rule in this block). */
  .chart-toggle{ min-height:40px; min-width:40px; padding:10px 14px; box-sizing:border-box; display:inline-flex; align-items:center; justify-content:center; }
  .geology-picker-btn{ min-height:36px; padding:8px 12px; }
  /* `.full-toggle` labels (Pipelines/Trunk points checkboxes)
     measured 0 height because their native `<input>` is visually hidden
     and only the `<label>` wraps text+checkbox -- forcing a min-height on
     the label itself (not the input) is what actually grows the tap
     target. The drawer's own copies keep their text visible at every
     width (plenty of room in a 340px-wide slide-in panel). */
  .full-toggle{ min-height:40px; }
}

/* ===========================================================
   SPEC-v32 BATCH F: desktop card treatment (Phil: "desktop stops being
   a half-screen wall: map-dominant layout with a floating sheet-like
   card consistent with mobile's design language"). Below this width the
   pre-Batch-F "wall" rule above still applies unmodified (out of scope
   -- the mission scoped this to ~900px+; 641-899px is a cramped middle
   ground nobody asked to touch this round).

   #panel drops its top:0/right:0/bottom:0 full-height, square-cornered,
   glued-to-the-edge geometry entirely: a 16px air gap on EVERY side --
   the same 16px #nav-cluster already floats at, so the
   card reads as one more member of that floating-chrome family, not a
   wall -- full corner radius (16px, the same number the mobile bottom
   sheet rounds its top corners to) and an omnidirectional shadow instead
   of the old one-sided edge glow. Width caps at 42vw rather than a flat
   460px: at a real ~900-1000px laptop width, 460px flat WAS close to
   literally half the screen (the exact "wall" complaint); 42vw keeps it
   well clear of that at the narrow end of this range while still
   settling at a comfortable 460px ceiling once the viewport is wide
   enough that a percentage alone would balloon the card. */
@media (min-width:900px){
  #app{ --panel-w: min(460px, 42vw); }
  #panel{
    top:16px; right:16px; bottom:16px; left:auto;
    width:var(--panel-w);
    border:1px solid var(--hair);
    border-radius:16px;
    box-shadow:0 24px 60px rgba(0,0,0,.5), 0 2px 12px rgba(0,0,0,.3);
  }
  /* ORCHESTRATOR FIX (Batch F verification): the card used to be flush to
     the right edge AND full height, so maplibre's own right-side controls
     (zoom, scale, attribution) sat clear of it. Now that the card floats
     16px in, those controls render UNDERNEATH it whenever it's open --
     the zoom buttons were fully buried. Slide the right-hand control
     columns clear of the card while it's open; they return when it closes.
     Transition matches the card's own so nothing snaps. */
  .maplibregl-ctrl-top-right, .maplibregl-ctrl-bottom-right{
    transition:transform .28s cubic-bezier(.2,.8,.2,1);
  }
  #app:has(#panel.open) .maplibregl-ctrl-top-right,
  #app:has(#panel.open) .maplibregl-ctrl-bottom-right{
    transform:translateX(calc(-1 * (var(--panel-w) + 16px)));
  }
}

@media (prefers-reduced-motion: reduce){
  #panel, .tl-expand-body{ transition:none; animation:none; }
}

/* ---- Leg D (overnight run 2, 2026-07-24): ?selftest=1 smoke-test banner --
   above EVERYTHING (modal overlay is the previous highest at z-index:60),
   since this is a diagnostic that must be visible no matter what state the
   app is in when it finishes. Fixed position + max-height + its own scroll
   so a long error list never pushes content off a phone screen -- this is
   explicitly the "Phil loads one URL on his phone" surface. ---- */
#selftest-banner{
  position:fixed; left:10px; right:10px; bottom:10px; z-index:100;
  max-height:60vh; overflow:auto; -webkit-overflow-scrolling:touch;
  font-family:var(--mono); font-size:12px; line-height:1.6;
  padding:14px 16px; border-radius:4px; box-shadow:0 8px 28px rgba(0,0,0,.55);
  white-space:pre-wrap; word-break:break-word;
}
#selftest-banner.pass{ background:rgba(61,220,151,.16); border:1px solid var(--good); color:var(--good); }
#selftest-banner.fail{ background:rgba(255,90,90,.16); border:1px solid #ff5a5a; color:#ff9a9a; }

/* ---------------------------------------------------------------------
   BOOT RELIABILITY (Run 77): visible boot state (Phil's bug -- "often
   times when i load the page... i dont see any data and i have to
   refresh" -- was a silent empty app on a flaky schemes.json fetch, see
   app.js's bootApp() comment). #boot-status sits above the map (full
   inset), below only the diagnostic #selftest-banner (z-index:100) --
   nothing else can be open yet at this point in a real load, so its own
   stacking relative to the drawer/modal/popup tiers never actually
   matters in practice, kept high and deliberate rather than accidental.
   --------------------------------------------------------------------- */
#boot-status{
  position:absolute; inset:0; z-index:95;
  display:flex; align-items:center; justify-content:center;
  background:var(--ink);
}
#boot-status[hidden]{ display:none; }
#boot-status-inner{
  display:flex; flex-direction:column; align-items:center; gap:14px;
  padding:24px; text-align:center;
}
.boot-spinner{
  width:28px; height:28px; border-radius:50%;
  border:2.5px solid var(--hair); border-top-color:var(--ember);
  animation:boot-spin .8s linear infinite;
}
.boot-spinner[hidden]{ display:none; }
@keyframes boot-spin{ to{ transform:rotate(360deg); } }
#boot-status-text{
  font-family:var(--mono); font-size:12.5px; letter-spacing:.02em;
  color:var(--core-dim); max-width:280px; line-height:1.5;
}
/* Error state: same failure-red the selftest banner's own .fail class
   already uses, so a hard boot failure reads as unmistakably "wrong",
   not just quieter loading text. */
#boot-status.boot-status-error #boot-status-text{ color:#ff9a9a; }
#boot-retry-btn[hidden]{ display:none; }
@media (prefers-reduced-motion: reduce){
  .boot-spinner{ animation:none; border-top-color:var(--hair); }
}

/* BOOT RELIABILITY (Run 77), item 4: version self-check banner -- one
   quiet, tappable pill, same steel/hair/frost/ember chrome as the rest of
   this app's chips/buttons. Fixed above the safe-area bottom, centered,
   so it never collides with the panel's own drag handle at small widths. */
#version-banner{
  position:fixed; left:50%; bottom:16px; transform:translateX(-50%); z-index:80;
  background:var(--steel-2); border:1px solid var(--ember-dim); color:var(--frost);
  font-family:var(--mono); font-size:11.5px; letter-spacing:.02em;
  padding:8px 14px; border-radius:20px; cursor:pointer;
  box-shadow:0 6px 20px rgba(0,0,0,.4);
  max-width:90vw;
}
#version-banner:hover, #version-banner:focus-visible{ border-color:var(--ember); color:var(--ember); }
#version-banner[hidden]{ display:none; }


/* SPEC-v35 LANDING: Board rides the bottom half on desktop arrival. */
#board.landing{ position:fixed; left:0; right:0; bottom:0; top:50vh;
  z-index:60; border-radius:18px 18px 0 0; overflow:hidden;
  padding:0 22px; /* kill the full-view 112px top inset */
  box-shadow:0 -12px 40px rgba(10,18,28,.35); }
#board.landing #board-scroll{ height:calc(50vh - 44px); overflow-y:auto; }


/* ---------------------------------------------------------------------------------------------
   FUEL GAS PROOF (spec-fuelgas-2026-09-28)
   Card: one more KPI in .scheme-stat-block, on its own full-width row. Figure ladder D1: figure 22px/700
   --frost tabular (2.0x its 11px unit, 2.4x the 9px label); unit and ratio unit 400 --core-dim on the
   figure's baseline after a 4px gap.
   Board: "Steam plants" table, same register as the share table (D2: right-aligned tabular numerics,
   >= 12px gutters, 30px rows, no zebra, rules only under the head and above the total).
   --------------------------------------------------------------------------------------------- */
.stat-cell-fuel{ grid-column:1 / -1; }
.stat-top-fuel{ grid-template-columns:auto 1fr auto; column-gap:14px; }
.stat-fig{ display:inline-flex; align-items:baseline; gap:4px; min-width:0; white-space:nowrap; }
.stat-fig-v{ font-family:var(--mono); font-size:22px; line-height:1.05; font-weight:700; color:var(--frost); font-variant-numeric:tabular-nums; }
.stat-fig-u{ font-family:var(--mono); font-size:11px; font-weight:400; color:var(--core-dim); white-space:nowrap; }
.stat-fuel-ratio{ display:inline-flex; align-items:baseline; gap:4px; min-width:0; white-space:nowrap; }
.stat-fuel-ratio-v{ font-family:var(--mono); font-size:14px; font-weight:700; color:var(--frost); font-variant-numeric:tabular-nums; }
.stat-cogen{ color:var(--gas); border-color:var(--gas); }
.stat-fuel-note{ font-family:var(--mono); font-size:10px; color:var(--core-dim); }

#board-steam-plants{ margin-top:22px; }
.sp-head-title{ font-size:10px; letter-spacing:.08em; text-transform:uppercase; color:var(--core-dim); margin-bottom:4px; }
.sp-asof{ text-transform:none; letter-spacing:0; }



/* ---------------------------------------------------------------------------------------------
   THE LENS (spec-lens-2026-09-28). Three bars, a crumb line, the joins, the table.
   Joins: ONE stroke per join in ONE token and one width (C4) -- the lit box's frame, the two straight
   lines and the next bar's frame are one SVG path (drawLensConnectors). Outer join accent, inner white.
   The frames that used to be CSS box-shadows on the tiers and the striped Other box are deleted: the
   SVG is the only thing drawing a frame, so there is nothing to drift against.
   --------------------------------------------------------------------------------------------- */
.lens-crumb{ display:flex; align-items:baseline; justify-content:center; gap:10px; min-height:18px; margin:0 0 10px;
  font-family:var(--mono); font-size:11px; color:var(--core); flex-wrap:wrap; }
.lens-crumb-link{ color:var(--core); text-decoration:none; }
.lens-crumb-link:hover{ color:var(--ember); }
.lens-crumb-here{ color:var(--frost); font-weight:700; }
.lens-crumb-sep{ color:var(--core); } /* H11: >= 4.5:1 on the card */
.lens-crumb-basin{ color:var(--core); }
.lens-compare{ font-family:var(--mono); font-size:11px; font-weight:700; color:var(--ink); background:var(--ember);
  border:0; border-radius:999px; padding:3px 10px; cursor:pointer; }
.lens-bars{ position:relative; margin:4px 0 14px; }
.lens-bars .board-bar{ margin-top:0; }
.lens-gap{ height:22px; }
.lens-box{ cursor:default; }
.lens-box[role="link"]{ cursor:pointer; }
.lens-dim{ position:relative; }
/* COLOUR rule 4: dimming dims the FILL, not the label -- an ink veil mixes the operator colour toward the ground
   (~35% colour left); the percent and the mark draw at full strength above it, in the light tone the mixed
   (always dark) fill needs */
.lens-dim::after{ content:''; position:absolute; inset:0; background:var(--ink); opacity:.65; z-index:1; pointer-events:none; }
.lens-dim > .board-bar-seg-body{ position:relative; z-index:2; }
.lens-dim:hover::after{ opacity:.45; }
.lens-name{ font-family:var(--mono); font-size:10.5px; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:100%; }
.lens-box:not(.board-bar-seg-dark) .lens-name{ color:var(--ink); }
.board-bar-seg-dark .lens-name{ color:var(--frost); }
.lens-box .board-prov-crest{ height:24px; width:auto; }
.lens-row{ cursor:pointer; }
.lens-pending{ font-family:var(--mono); font-size:11px; color:var(--core-dim); padding:12px 0; }
/* desktop (> 900px): two windows side by side -- the map left, the lens right, both always visible */
@media (min-width:901px){
  #board.landing{ top:0; left:auto; right:0; bottom:0; width:clamp(480px, 42vw, 640px); border-radius:0;
    box-shadow:-12px 0 40px rgba(10,18,28,.35); }
  #board.landing #board-scroll{ height:100vh; padding-top:16px; box-sizing:border-box; }
}


/* ---- LENS stage 3 (2026-09-28): pads and wells, the chart panel ---- */
/* wells: an infill wears the map's dashed edge; a CSS well mid-steam-cycle is outlined (styled inline), idle dims */
.lens-infill{ outline:1.5px dashed rgba(255,255,255,.85); outline-offset:-3px; }
.lens-phase-idle{ opacity:.4; }
/* below the basin the bars condense (x 2/3) and a chart of the chain head joins them */
.lens-has-chart .board-bar-tall.board-bar-lead{ height:48px; }
.lens-has-chart .board-bar-tall.board-bar-tier2{ height:44px; } /* amendment 1: tall enough for a stacked [mark / %] */
.lens-has-chart .board-bar-tall.board-bar-other{ height:32px; }
.lens-has-chart .board-bar-tier2 .board-bar-seg-top .board-mark{ height:22px; max-height:22px; }
.lens-has-chart .board-bar-other .board-bar-seg-top .board-mark{ height:16px; max-height:16px; }
.lens-side{ margin:0 0 12px; }
.lens-kpis{ margin:0 0 8px; }
.lens-chart svg{ width:100%; height:auto; display:block; }
.lens-chart-toolbar{ display:flex; justify-content:space-between; align-items:center; gap:8px; flex-wrap:wrap; margin:0 0 4px; }
.lens-chart-tier{ font-family:var(--mono); font-size:9px; color:var(--core); margin-top:2px; }
.lens-chart-pending{ font-family:var(--mono); font-size:10px; color:var(--core); padding:24px 0; text-align:center; }
/* THE BAR 5: side by side only when the card leaves the chart panel >= 320px (2:1 split + 16px gap = 976px);
   the desktop card is ~560px wide, so there the chart stacks under the bars at full width, as on the phone */
.lens-has-chart{ container-type:inline-size; }
@container (min-width:976px){
  .lens-has-chart .lens-top{ display:flex; gap:16px; align-items:flex-start; }
  .lens-has-chart .lens-top > .lens-bars{ flex:2 1 0; min-width:0; }
  .lens-has-chart .lens-top > .lens-side{ flex:1 1 0; min-width:0; margin:4px 0 0; }
  .lens-side .company-kpi-row-compact{ flex-wrap:wrap; }
}
.lens-uwi{ font-size:8.5px; color:var(--core); }
.lens-well-infill .lens-name-main{ text-decoration:underline dashed rgba(255,255,255,.6); text-underline-offset:3px; }
/* PADS part 2: historical pads -- below a rule, dormant (--core), unranked; the note spans the figure columns */
/* BUGS 3: a lit member inside Other -- its own stripe at full strength, the Other's other stripes stepped back; the
   cup's apex attaches to this stripe (drawLensConnectors) */
.lens-box.lens-lit .board-bar-stripes:has(.lens-lit-stripe) .board-bar-substripe:not(.lens-lit-stripe){ opacity:.45; }
.board-bar-substripe.lens-lit-stripe{ opacity:1; }
/* THE BAR (2026-09-30): the flag tabs -- flags only, the share under a crest, the lit tab underlined in the accent */
.lens-flag-tabs{ display:flex; border-bottom:1px solid var(--hair); margin:2px 0 10px; }
.lens-flag-tab{ flex:1; display:flex; flex-direction:column; align-items:center; gap:3px; padding:6px 0 6px; background:none; border:none;
  border-bottom:2px solid transparent; margin-bottom:-1px; cursor:pointer; opacity:.6; }
.lens-flag-tab img{ height:26px; width:auto; display:block; }
.lens-flag-share{ font-size:10.5px; font-weight:700; font-variant-numeric:tabular-nums; color:var(--frost); line-height:1; min-height:10px; }
.lens-flag-tab.lit{ opacity:1; border-bottom-color:var(--ember); }
.lens-flag-tab:hover, .lens-flag-tab:focus-visible{ opacity:1; }
/* THE BAR: Cenovus carries its wordmark on a wide box, the CV monogram on a narrow one */
.lens-box:has(.lens-mark-pair){ container-type:inline-size; }
.lens-mark-pair{ display:contents; }
.lens-mark-pair .lens-mark-wide{ display:none; }
@container (min-width:112px){ .lens-mark-pair .lens-mark-wide{ display:block; max-width:88%; } .lens-mark-pair .lens-mark-narrow{ display:none; } }
/* THE BAR stage 2 -- the landing's hero bar: edge to edge of the card (the card's 20px padding bled back), the tallest
   bar in the app, 1px hairlines in the card ground between boxes, percents regular weight, the largest marks, every
   mark drawn even on a box too narrow for its percent (it shrinks with the box; Strathcona's 5% carries its mark) */
.lens-bar.lens-hero{ height:96px; margin-left:-20px; margin-right:-20px; width:auto; }
.lens-hero .lens-box{ box-shadow:inset -1px 0 0 var(--steel-2); }
.lens-hero .lens-box:last-child{ box-shadow:none; }
.lens-hero .board-bar-seg-pct{ font-weight:400; font-size:13px; }
.lens-hero .board-bar-seg-top .board-mark{ height:40px; max-height:40px; max-width:100%; }
.lens-hero .seg-colour .board-bar-seg-body{ display:flex; }
.lens-hero .seg-colour .lens-nums{ display:none; }
/* THE BAR stage 3 -- the company card: the whole card in the operator's colour ONE SHADE darker than its box (so the
   biggest box, at full strength, stands off it); a light card (CNRL's white) flips the card's OWN text tokens (the
   wordmark, trail, tabs, header, table, KPIs and chart), never the boxes'. ROUND 2 #5: the chart and KPIs sit on the card's
   own surface -- the navy panel behind them is gone */
#board-hero.lens-co{ background:var(--co); border-color:var(--co); }
#board-hero.lens-card-light .board-hero-wordmark, #board-hero.lens-card-light .lens-crumb, #board-hero.lens-card-light .lens-flag-tabs,
#board-hero.lens-card-light .lens-co-head, #board-hero.lens-card-light .atable-frame, #board-hero.lens-card-light .lens-data-row,
#board-hero.lens-card-light .lens-panel, #board-hero.lens-card-light .lens-section-title, #board-hero.lens-card-light #board-steam-plants{
  --frost:#0b1224; --core:var(--co-text2); --core-dim:var(--co-text2); --ember:#0b1224; color:#0b1224; } /* its lines: --line (Phil 2026-10-12 #1, end of file) */
#board-hero.lens-card-light .board-hero-wordmark .wordmark-text, #board-hero.lens-card-light .board-hero-wordmark .wordmark-text span{ color:#0b1224; } /* A2: on a light surface the accent is ink */
.lens-panel{ background:none; padding:0; color:var(--frost); }
.lens-co-head{ display:flex; align-items:center; gap:10px; margin:2px 0 12px; }
.lens-co-mark img{ height:34px; width:auto; display:block; }
.lens-co-name{ font-weight:800; font-size:16px; color:var(--frost); line-height:1.15; }
.lens-co-kpi{ font-size:11px; color:var(--core); font-variant-numeric:tabular-nums; }
/* the cup (ROUND 3 R7): its strokes and body draw UNDER the bars; the picked box's own border draws above */
.lens-bars .lens-bar{ position:relative; z-index:1; }
/* boxes (THE BAR): percents only, regular weight; 1px hairlines in the card ground between boxes; Other ALWAYS
   obvious -- a white border and "Other" / "+N" inside */
.lens-box .board-bar-seg-pct{ font-weight:400; }
.lens-bar:not(.lens-hero) .lens-box{ box-shadow:inset -1px 0 0 var(--co, var(--steel-2)); }
.lens-bar:not(.lens-hero) .lens-box:last-child{ box-shadow:none; }
/* Other is always the last box: out-rank the last-child hairline reset above, or the white border vanishes */
.lens-bar .lens-box.board-bar-seg-striped, .lens-bar:not(.lens-hero) .lens-box.board-bar-seg-striped:last-child{ box-shadow:inset 0 0 0 1.5px var(--ember); }
.lens-details-l{ color:var(--frost); font-weight:700; }

/* ---- LENS amendment 5 (2026-09-29): the well level ---- */
/* the pair strip: slim, equal boxes, role words only (membership, not share) */
.board-bar-tall.lens-pair-strip{ height:26px; }
.lens-has-chart .board-bar-tall.lens-pair-strip{ height:24px; }
.lens-pair-box .board-bar-seg-body{ flex-direction:row; }
.lens-pair-role{ font-size:9.5px; letter-spacing:.04em; text-transform:uppercase; font-weight:700; }
.lens-row-lit{ background:var(--steel-2); box-shadow:inset 3px 0 0 var(--ember); }
.lens-well-name{ font-family:var(--mono); font-size:11px; color:var(--frost); margin:0 0 6px; overflow-wrap:anywhere; }

/* ---- LENS stage 4 (2026-09-29): the options drawer ---- */
.options-section{ padding-bottom:14px; }
.opt-row{ display:flex; align-items:center; justify-content:space-between; min-height:36px; font-family:var(--mono); font-size:12px; color:var(--frost); }
.opt-switch{ width:40px; height:22px; border-radius:11px; border:1px solid var(--hair); background:var(--steel-2); position:relative; cursor:pointer; padding:0; flex-shrink:0; }
.opt-switch span{ position:absolute; top:2px; left:2px; width:16px; height:16px; border-radius:50%; background:var(--core); transition:left .12s, background .12s; }
.opt-switch[aria-checked="true"]{ background:var(--ember); border-color:var(--ember); }
.opt-switch[aria-checked="true"] span{ left:20px; background:var(--ink); }
@media (prefers-reduced-motion: reduce){ .opt-switch span{ transition:none; } }
/* the card's own filings search */
.scheme-search{ margin:0 0 8px; }
.scheme-search input{ width:100%; box-sizing:border-box; font-family:var(--mono); font-size:12px; color:var(--frost); background:var(--steel-2); border:1px solid var(--hair); border-radius:3px; padding:7px 9px; }
.scheme-search input:focus{ outline:none; border-color:var(--ember); }

/* ---- LENS stage 5: where the oil goes ---- */
.oil-route{ margin:14px 0; font-family:var(--mono); font-size:11.5px; color:var(--frost); }
.oil-route-line{ font-weight:700; margin:4px 0 6px; }
.oil-route-hub{ margin:4px 0; line-height:1.9; }
.oil-route-from{ color:var(--core); }
.oil-route-corridor{ font:inherit; color:var(--frost); background:var(--steel-2); border:1px solid var(--hair); border-radius:3px; padding:3px 7px; margin:2px 2px 2px 0; cursor:pointer; min-height:28px; }
.oil-route-corridor:hover{ border-color:var(--ember); }
.oil-route-corridor b{ font-variant-numeric:tabular-nums; }
.oil-route-reason{ color:var(--core); margin-top:4px; }
.oil-route-basis{ color:var(--core); font-weight:400; text-transform:none; letter-spacing:0; }
.pipe-reach{ font-family:var(--mono); font-size:11px; color:var(--frost); margin:3px 0; }
.pipe-reach-note{ color:var(--core); }

/* REVIEW #13 (2026-09-30, ROUND 3 R3/R12 sizes): on the company card every row is 40px (mockup 40/40/40, the 22px
   cup gap between), a box's percent 10.5px (narrow "tight" boxes keep their 8.5), and the engineering tables 12px */
#board-hero.lens-co .lens-bar.board-bar-tall{ height:40px; }
#board-hero.lens-co .lens-box:not(.board-bar-seg-tight) .board-bar-seg-pct{ font-size:10.5px; }

/* REVIEW #14 (H11 >= 4.5:1): on a company card the secondary greys are the card's own computed text tone
   (--co-text2, app.js lensTextTone) -- the chart and KPIs too, now that they sit on the card (ROUND 2 #5) */
#board-hero.lens-co{ --core:var(--co-text2); --core-dim:var(--co-text2); }
#board-hero.lens-co .lens-flag-tab:not(.lit){ opacity:1; }
#board-hero.lens-co .lens-flag-tab:not(.lit) img{ opacity:.6; }
#board-hero.lens-co .lens-flag-tab:not(.lit) .lens-flag-share{ color:var(--co-text2); }

/* REVIEW #16 (2026-09-30, the brief: no dots anywhere): on the card, names, sub-lines, the Details line, steam-plant
   names and the table headers WRAP instead of cutting to "…" (box names inside a bar are still dropped when they
   don't fit -- that is the brief's own rule for boxes) */

/* REVIEW #17: the lens chart's text at a real 9-10px whatever the chart's rendered width (--chart-k, app.js) */
#lens-chart-svg .chart-ytick, #lens-chart-svg .chart-xtick, #lens-chart-svg .chart-axis-title{ font-size:calc(8px * var(--chart-k, 1)); }
#lens-chart-svg .chart-end-label{ font-size:calc(9px * var(--chart-k, 1)); }
#lens-chart-svg .chart-flag-overflow, #lens-chart-svg .chart-empty-inline{ font-size:calc(8px * var(--chart-k, 1)); }
#lens-chart-svg{ overflow:visible; } /* the bigger end labels spill into the panel's own padding instead of clipping */

/* REVIEW #33: a mark only where the box can hold it -- at 5px (Athabasca) a 40px-tall mark squeezed to a 1.3px sliver;
   14px keeps Strathcona's (5%, ~18px on the phone: the brief says it MUST carry its mark) */
.lens-hero .lens-box{ container-type:inline-size; }
.lens-hero .board-bar-seg-top .board-mark:not(.lens-mark-wide):not(.lens-mark-narrow){ display:none; }
@container (min-width:14px){ .lens-hero .board-bar-seg-top .board-mark:not(.lens-mark-wide):not(.lens-mark-narrow){ display:block; } }

/* REVIEW #34: the picked box wears the cup's double border; its own right-hand hairline showed as a 1px seam inside it */
.lens-bar:not(.lens-hero) .lens-box.lens-lit:not(.board-bar-seg-striped){ box-shadow:none; }

/* REVIEW #38: the legend paragraphs were flex rows, so a paragraph with swatches mid-sentence (Arteries) split into
   flex items and wrapped one word per line; plain text flow with the swatches inline */
.about-map-body p{ display:block; }
.about-map-body p .about-map-swatch, .about-map-body p .flow-swatch{ display:inline-block; vertical-align:-1px; margin:0 4px 0 0; }

/* Phil 2026-09-30 ("ok sounds good"): the old scheme ranking table + its toolbar (# SCHEME BITUMEN... Show all N,
   Download CSV, Methodology) no longer render under the card -- the card already ranks everything */


/* ===================================================================== THE PYRAMID stage 1 (Phil 2026-09-30) */
/* the circles along the top of the screen; no SAGD ATLAS pill (the approved mockup m1); no slide-down handle */
#nav-cluster{ flex-direction:row; align-items:center; }
#wordmark-chip{ display:none; }
#bubble-row{ gap:10px; }
.bubble-drop{ position:fixed; top:68px; z-index:40; min-width:180px; background:rgba(255,255,255,.97); border-radius:14px;
  box-shadow:0 6px 24px rgba(11,18,36,.28); padding:6px; display:flex; flex-direction:column; }
.bubble-drop[hidden]{ display:none; }
.drop-item{ display:flex; align-items:center; gap:10px; padding:10px 12px; border:none; background:none; border-radius:10px;
  font:500 14px/1.2 var(--sans, system-ui); color:#0b1224; text-decoration:none; text-align:left; cursor:pointer; }
.drop-item:hover, .drop-item:focus-visible{ background:rgba(11,18,36,.07); }
.drop-dot{ width:12px; height:12px; border-radius:50%; border:1.5px solid #0b1224; flex-shrink:0; }
.drop-item.on .drop-dot{ background:#0b1224; }
.sr-only{ position:absolute !important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }

/* the tabs: the top of the card; flag with its figure to the right; the picked tab framed, its frame stepping out
   to frame the whole card below (img 2 -- the pyramid's top, a straight step) */
#board-hero.lens .lens-flag-tabs{ border-bottom:none; margin:0; gap:6px; position:relative; z-index:2; }
#board-hero.lens .lens-flag-tab{ flex-direction:row; justify-content:center; gap:8px; padding:9px 6px 10px; opacity:.85;
  border:1.5px solid transparent; border-bottom:none; border-radius:12px 12px 0 0; }
#board-hero.lens .lens-flag-tab img{ height:24px; }
#board-hero.lens .lens-flag-share{ font-size:13px; font-weight:600; min-height:0; }
#board-hero.lens .lens-flag-share i{ font-style:normal; font-weight:500; font-size:11px; opacity:.85; }
#board-hero.lens .lens-flag-tab.lit{ opacity:1; border-color:var(--ember); background:var(--steel); margin-bottom:-1.5px; padding-bottom:11.5px; }
#board-hero.lens .lens-frame{ border:1.5px solid var(--ember); border-radius:0 14px 14px 14px; padding:12px 10px 10px; position:relative; z-index:1; }
#board-hero.lens .lens-flag-tabs:has(.lens-flag-tab.lit:not(:first-child)) + .lens-frame{ border-radius:14px; }
.lens-cmp-row{ display:flex; justify-content:flex-end; margin:-4px 0 8px; }

/* the hero bar sits INSIDE the frame (Phil: "the bar that we widened stays inside of the window") */
.lens-bar.lens-hero{ margin-left:0; margin-right:0; }

/* #6: the Cenovus wordmark ~70% of its size */
.lens-mark-pair .lens-mark-wide{ transform:scale(.7); transform-origin:center; }
@container (min-width:112px){ .lens-mark-pair .lens-mark-wide{ max-width:88%; } }

/* stage 1 tightening (first look on the phone): the card's own padding small so the frame uses the width; the
   Canada total on one line; the table header on one line */
#board-hero.lens{ padding-left:8px; padding-right:8px; padding-top:10px; }
#board-hero.lens .lens-flag-share{ white-space:nowrap; }


/* ===================================================================== THE PYRAMID stage 3 (Phil 2026-09-30) */
/* the card stays the normal card; the company colour lives ONLY inside the pyramid frame */
#board-hero.lens.lens-co{ background:var(--steel-2); border-color:var(--hair); --core:#8fa6b3; --core-dim:#8fa6b3; }
#board-hero.lens.lens-co .lens-flag-tab:not(.lit) .lens-flag-share{ color:var(--frost); }
#board-hero.lens.lens-card-light .lens-flag-tabs{ --frost:#e7eef3; --core:#8fa6b3; --hair:rgba(231,238,243,.14); --ember:#e7eef3; color:#e7eef3; }
#board-hero.lens .lens-frame{ position:relative; }
.lens-strip{ display:flex; height:30px; border-radius:3px; overflow:hidden; position:relative; z-index:2; }
.lens-strip-box{ min-width:0; display:flex; align-items:center; justify-content:center; cursor:pointer; box-shadow:inset -1px 0 0 rgba(11,18,36,.55); }
.lens-strip-box:last-child{ box-shadow:none; }
.lens-strip-box .board-mark, .lens-strip-box img{ height:20px; width:auto; max-width:90%; object-fit:contain; display:block; }
.lens-strip-box.lens-lit{ box-shadow:inset 0 0 0 2px var(--co), inset 0 0 0 3px rgba(11,18,36,.35); }
.lens-coframe{ position:relative; z-index:2; margin-top:22px; background:var(--co); border:1.5px solid var(--co); border-radius:8px; padding:10px 8px 8px;
  --core:var(--co-text2); --core-dim:var(--co-text2); }
#board-hero.lens-card-light .lens-coframe{ --frost:#0b1224; --ember:#0b1224; color:#0b1224; }
.lens-coframe .lens-co-mark img{ height:24px; }


/* ===================================================================== THE PYRAMID stage 2 (Phil 2026-09-30) */
.lens-tailgroup{ display:flex; padding:0 !important; box-shadow:inset 0 0 0 1.5px var(--ember) !important; overflow:hidden; cursor:pointer; }
.lens-tail-stripe{ height:100%; min-width:0; box-shadow:inset -1px 0 0 rgba(11,18,36,.4); }
.lens-tail-stripe:last-child{ box-shadow:none; }
/* the top bar tucked when Other is open: colours kept, ~10% veil, a black frame */
.lens-bar.lens-hero.lens-tucked{ height:30px !important; position:relative; outline:1.5px solid #000; outline-offset:0; }
.lens-bar.lens-hero.lens-tucked::after{ content:''; position:absolute; inset:0; background:rgba(0,0,0,.10); pointer-events:none; }
.lens-bar.lens-hero.lens-tucked .board-bar-seg-body, .lens-bar.lens-hero.lens-tucked .board-bar-seg-pct{ display:none !important; }
/* LAUNCH A5 (Phil 10-13 12:40): the tucked hero keeps every box's mark, small */
.lens-bar.lens-hero.lens-tucked .board-mark{ height:18px !important; width:auto !important; max-width:85%; object-fit:contain; }
.lens-bar.lens-tailops{ height:72px !important; }


/* ===================================================================== THE PYRAMID stage 4 (Phil 2026-09-30) */
/* a crowded level: the pyramid's frame opens full width and holds circles, ~6 across, biggest first */
.lens-bar.lens-circlebar{ height:auto !important; display:block; padding:8px 4px; overflow:visible; }
.lens-circles{ display:grid; grid-template-columns:repeat(6, minmax(0, 1fr)); gap:8px 6px; }
.lens-circle{ aspect-ratio:1; border-radius:50%; border:1.5px solid rgba(11,18,36,.35); background:var(--c); cursor:pointer;
  display:flex; flex-direction:column; align-items:center; justify-content:center; padding:2px; min-width:0; color:#0b1224; }
.lens-circle-name{ font-weight:700; font-size:11px; line-height:1.05; max-width:100%; overflow-wrap:anywhere; text-align:center; }
.lens-circle-sub{ font-size:9px; opacity:.85; margin-top:1px; font-variant-numeric:tabular-nums; }
.lens-circle:focus-visible{ outline:2px solid var(--ember); outline-offset:2px; }
@media (min-width:641px){ .lens-circles{ grid-template-columns:repeat(8, minmax(0, 1fr)); } }
/* rolled up: the one picked member across the full width */
.lens-bar.lens-rolled .board-bar-seg{ flex:1 1 auto !important; }

/* Phil 2026-10-01 (first look at the pyramid): "the edges (dark blue) should be at max 10px and the next border in
   should be at max 5px (navy blue) and then the white line where it is" -- the sheet's own edge 8px, the navy card
   4px, then the tab frame; the handle's 44px is gone with the handle */
#board.landing{ padding-left:8px; padding-right:8px; }
#board.landing #board-scroll{ height:50vh; padding-top:8px; box-sizing:border-box; }
#board-hero.lens{ padding:4px; }
#board-hero.lens .lens-frame{ padding:10px 8px 8px; }


/* ===================================================================== THE PYRAMID 5 (Phil 2026-10-01) */
/* the trail as four filter circles (top left), the gear (top right) */
.trail-row{ gap:10px; }
.trail-btn{ overflow:hidden; color:#0b1224; }
.trail-btn img, .trail-btn .board-mark{ max-width:30px; max-height:26px; width:auto; height:auto; display:block; object-fit:contain; }
.trail-btn .trail-txt{ font:700 10px/1.05 var(--sans, system-ui); text-align:center; padding:0 3px; overflow-wrap:anywhere; }
.trail-btn .trail-empty{ font:600 9px/1 var(--sans, system-ui); color:rgba(11,18,36,.45); }
.trail-btn:disabled{ opacity:.45; cursor:default; }
.trail-btn.trail-set{ box-shadow:0 0 0 2px #0b1224, 0 2px 10px rgba(30,10,14,.18); }
/* PLAN 2 item 9 (2026-10-13, Phil: "the choices inside do nothing"): above the lens sheet (60) and the card over it (61) --
   at 45 every choice below the sheet's top edge sat UNDER the sheet, and a tap landed on the sheet instead */
.trail-drop{ position:fixed; left:8px; right:8px; top:70px; z-index:70; max-height:62vh; overflow:auto; background:rgba(255,255,255,.98);
  border-radius:16px; box-shadow:0 8px 28px rgba(11,18,36,.3); padding:10px; }
.trail-drop[hidden]{ display:none; }
.trail-drop-grid{ display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:10px 6px; }
.trail-choice{ display:flex; flex-direction:column; align-items:center; gap:3px; border:none; background:none; padding:4px 2px; border-radius:12px; cursor:pointer; color:#0b1224; min-width:0; }
.trail-choice:hover, .trail-choice:focus-visible{ background:rgba(11,18,36,.07); }
.trail-choice.here{ background:rgba(11,18,36,.1); }
.trail-choice-img{ width:52px; height:52px; border-radius:50%; background:#fff; box-shadow:inset 0 0 0 1px rgba(11,18,36,.15); display:flex; align-items:center; justify-content:center; overflow:hidden; }
.trail-choice-img img, .trail-choice-img .board-mark{ max-width:40px; max-height:34px; width:auto; height:auto; object-fit:contain; display:block; }
.trail-choice.here .trail-choice-img{ box-shadow:inset 0 0 0 2.5px #0b1224; }
.trail-choice-name{ font:600 11px/1.15 var(--sans, system-ui); text-align:center; overflow-wrap:anywhere; }
.trail-choice-sub{ font:500 10px/1 var(--sans, system-ui); color:rgba(11,18,36,.6); font-variant-numeric:tabular-nums; }
.trail-dot{ width:30px; height:30px; border-radius:50%; background:#8fa6b3; display:block; }
.trail-dot-pad{ background:#365860; }
.trail-loading{ padding:12px; font-size:12px; color:#33415c; }
/* the gear, top right; the map's zoom moves down under it */
#bubble-menu.gear-btn{ position:absolute; top:16px; right:16px; z-index:21; }
.maplibregl-ctrl-top-right{ top:66px !important; }
/* the gear's useful menu: compare + pages groups */
.drawer-btn{ display:block; width:100%; text-align:left; padding:10px 12px; margin:4px 0; border-radius:10px; border:1px solid var(--hair); background:transparent; color:var(--frost); font:500 13px/1.2 var(--sans, system-ui); cursor:pointer; }
.drawer-btn:hover{ border-color:var(--ember); }
.drawer-link{ display:block; padding:8px 2px; color:var(--frost); text-decoration:none; font-size:13px; border-bottom:1px solid var(--hair); }
.drawer-link:hover{ color:var(--ember); }
/* PLAN 4 item C: the gear's menu in the order a reader reaches for it -- map, units, compare, read (the DOM order) */
#drawer-scroll{ display:flex; flex-direction:column; }
.drawer-btn-row{ display:flex; gap:8px; }
.drawer-btn-row .drawer-btn{ flex:1; text-align:center; }
.opt-compare-n{ color:var(--core); }
#map-section #opt-maponly{ margin-top:10px; }


/* ===================================================================== THE PYRAMID 6 (Phil 2026-10-01) */
/* the region colours: Canada red, Alberta blue, Saskatchewan green -- the picked tab and the frame round the card wear
   it bold; the card inside takes a darkened version of it (the company frame inside keeps the company colour) */
#board-hero.lens{ --rg:#d52b1e; --rg-bg:#2a1a24; }
#board-hero.lens[data-region="AB"]{ --rg:#2f6fd6; --rg-bg:#122a52; }
#board-hero.lens[data-region="SK"]{ --rg:#18a35a; --rg-bg:#0f3a2a; }
#board-hero.lens[data-region="CA"]{ --rg-bg:var(--steel-2); }
#board-hero.lens .lens-frame{ border:2.5px solid var(--rg); background:var(--rg-bg); }
/* tabby tabs: each its own rounded-top tab with an edge; the picked one joined to the card */
#board-hero.lens .lens-flag-tabs{ gap:5px; align-items:flex-end; }
#board-hero.lens .lens-flag-tab{ flex-direction:column; align-items:center; gap:2px; padding:7px 4px 7px; opacity:1;
  border:1.5px solid rgba(231,238,243,.22); border-bottom:none; border-radius:12px 12px 0 0; background:rgba(255,255,255,.05); margin-bottom:0; }
#board-hero.lens .lens-flag-tab:hover{ background:rgba(255,255,255,.1); }
#board-hero.lens .lens-flag-tab.lit{ border:2.5px solid var(--rg); border-bottom:none; background:var(--rg-bg); margin-bottom:-2.5px; padding:9px 4px 11px; }
#board-hero.lens .lens-flag-tab img{ height:22px; }
#board-hero.lens .lens-flag-share{ display:flex; align-items:baseline; gap:3px; font-size:12px; color:var(--frost); }
#board-hero.lens .lens-flag-share b{ font-weight:700; }
#board-hero.lens .lens-flag-share i{ font-size:9.5px; }
#board-hero.lens .lens-flag-pct{ font-size:10px; color:var(--core); margin-left:3px; }
#board-hero.lens .lens-flag-tab:not(.lit){ opacity:.82; }
#board-hero.lens.lens-co .lens-flag-tab:not(.lit) .lens-flag-share{ color:var(--frost); }


/* ===================================================================== THE PYRAMID 7 (Phil 2026-10-01) */
/* the landing bar: shorter, the coloured tiles carry only the logos; under it a thin bar graph of the percents */
.lens-bar.lens-hero, .lens-bar.lens-herolike{ height:60px !important; }
.lens-hero .board-bar-seg-pct, .lens-herolike .board-bar-seg-pct, .lens-hero .lens-nums, .lens-herolike .lens-nums{ display:none !important; }
.lens-hero .board-bar-seg-top .board-mark, .lens-herolike .board-bar-seg-top .board-mark{ height:34px; max-height:34px; }
.lens-hero-scale{ display:flex; margin:4px 0 2px; height:22px; }
.lens-scale-cell{ display:flex; flex-direction:column; align-items:center; min-width:0; overflow:hidden; }
.lens-scale-cell i{ display:block; width:100%; height:4px; border-right:1px solid var(--steel-2); }
.lens-scale-cell b{ font:500 10px/1 var(--sans, system-ui); color:var(--core); margin-top:4px; font-variant-numeric:tabular-nums; white-space:nowrap; }
.lens-scale-cell.lens-scale-narrow b{ visibility:hidden; }
/* Others: the stripes boxed, labelled like a logo */
.lens-tailgroup, .lens-strip-tail{ position:relative; }
.lens-tail-label{ position:absolute; left:50%; top:50%; transform:translate(-50%, -50%); font:700 10px/1 var(--sans, system-ui); letter-spacing:.02em;
  color:#fff; background:rgba(11,18,36,.78); border:1px solid rgba(231,238,243,.7); border-radius:6px; padding:3px 5px; white-space:nowrap; pointer-events:none; }
.lens-strip-tail{ display:flex; box-shadow:inset 0 0 0 1.5px var(--ember) !important; overflow:hidden; }
.lens-strip-tail .lens-tail-label{ font-size:8.5px; padding:2px 4px; }
/* Others open: the first bar tightens to ~66% (40px), keeps its colours under a 10% veil and black frame; the Others
   bar below at full height (the squared frame and the cup carry the colour down) */
.lens-bar.lens-hero.lens-tucked{ height:40px !important; }
.lens-bar.lens-hero.lens-tucked .board-bar-seg-top .board-mark{ height:22px; max-height:22px; display:block !important; }
/* the pyramid through Others at a company: both bars tucked, the Others strip framed */
.lens-strip-2{ margin-top:14px; box-shadow:0 0 0 1.5px var(--ember); }
.lens-bar.lens-hero.lens-tucked .board-bar-seg-body{ display:flex !important; }
.lens-bar.lens-hero.lens-tucked .lens-tailgroup .lens-tail-label{ font-size:8.5px; padding:2px 4px; }

/* the crowded level: "TOP pads at the very top, the first 5, bigger", then the rest 8 across, smaller */
.lens-circles-head{ font:700 10px/1 var(--sans, system-ui); letter-spacing:.08em; text-transform:uppercase; color:var(--core); margin:2px 2px 8px; }
.lens-circles.lens-circles-top{ grid-template-columns:repeat(5, minmax(0, 1fr)); gap:8px; margin-bottom:12px; }
.lens-circles.lens-circles-top .lens-circle-name{ font-size:13px; }
.lens-circles.lens-circles-top .lens-circle-sub{ font-size:10.5px; }
.lens-circles.lens-circles-rest{ grid-template-columns:repeat(8, minmax(0, 1fr)); gap:6px 4px; }
.lens-circles.lens-circles-rest .lens-circle-name{ font-size:9px; }
.lens-circles.lens-circles-rest .lens-circle-sub{ font-size:7.5px; }
@media (min-width:641px){ .lens-circles.lens-circles-rest{ grid-template-columns:repeat(10, minmax(0, 1fr)); } }

/* the gear never sits on a card's close button: with a project card open on a wide screen it steps left of the card */
@media (min-width:721px){ body:has(#panel.open) #bubble-menu.gear-btn{ right:calc(min(460px, 100vw) + 16px); } }



/* ===================================================================== THE PYRAMID 8: TABS ALL THE WAY DOWN */
/* the company frame's top edge is the tab's shelf: drawn in the company colour, square-cornered where the neck meets it */
.lens-coframe{ border-top-left-radius:4px; border-top-right-radius:4px; }


/* ===================================================================== REVIEW-1 (Fable, 2026-10-01) */
/* (1) "Others" sits on the bar, right-aligned to its end -- never clipped by a narrow group or the card edge */
.lens-bar, .lens-strip{ position:relative; }
.lens-tail-label.lens-tail-label-bar{ left:auto; right:3px; top:50%; transform:translateY(-50%); z-index:3; }
.lens-tailgroup .lens-tail-label:not(.lens-tail-label-bar), .lens-strip-tail .lens-tail-label:not(.lens-tail-label-bar){ display:none; }
.lens-strip .lens-tail-label.lens-tail-label-bar{ font-size:8.5px; padding:2px 4px; }
/* (3) one mark per box when tucked: the small CV, never the wordmark beside it */
.lens-bar.lens-tucked .lens-mark-wide{ display:none !important; }
.lens-bar.lens-tucked .lens-mark-narrow{ display:block !important; }
/* (6) the gear's basket count */
.gear-count{ position:absolute; top:-3px; right:-3px; min-width:18px; height:18px; border-radius:9px; background:#d52b1e; color:#fff;
  font:700 11px/18px var(--sans, system-ui); text-align:center; padding:0 4px; box-shadow:0 0 0 2px #fff; }
.gear-count[hidden]{ display:none; }
/* (7) trail names wrap only at spaces */
.trail-choice-name{ overflow-wrap:normal; word-break:keep-all; font-size:10.5px; }
/* (10) the landing's dead space: the percent graph sits close on the table */
.lens-hero-scale{ margin-bottom:0; }
.lens-bar.lens-hero.lens-tucked .board-bar-seg-top .board-mark.lens-mark-wide{ display:none !important; }
.lens-bar.lens-hero.lens-tucked .board-bar-seg-top .board-mark.lens-mark-narrow{ display:block !important; }


/* ===================================================================== JUDGE-1 (Fable, 2026-10-01) */
/* (3) "Others" inside its own group: horizontal, or vertical when narrow, or hidden -- never over another box */
.lens-tail-label.lens-tail-in{ position:absolute; left:50%; top:50%; transform:translate(-50%, -50%); font-size:9px; padding:2px 4px; z-index:2; }
.lens-tail-label.lens-tail-in.lens-tail-v{ transform:translate(-50%, -50%) rotate(-90deg); }
.lens-tail-label.lens-tail-in.lens-tail-none{ display:none; }
.lens-tailgroup, .lens-strip-tail{ overflow:hidden; }
/* (2) the block's subject line */
.lens-subject{ font-size:12px; color:var(--frost); margin:0 0 8px; line-height:1.3; }
.lens-subject b{ font-weight:700; }
.lens-pair-title{ font-weight:700; font-size:14px; }
.lens-pair-legs{ font-size:10px; color:var(--core); margin:2px 0 8px; }
/* (6) the pair's tab neck needs a little room under the last row */
/* (9) the capped circles */
.lens-circles-capped .lens-circle-extra{ display:none; }
.lens-circles-more{ display:block; width:100%; margin:10px 0 2px; padding:9px; border-radius:10px; border:1px solid var(--hair); background:rgba(255,255,255,.06); color:var(--frost); font:600 12px/1 var(--sans, system-ui); cursor:pointer; }
/* (10) the landing: the percent row sits right on the table */
.lens-hero-scale{ height:16px; margin-top:3px; }
.lens-scale-cell b{ margin-top:2px; }
.lens-tailgroup .lens-tail-label.lens-tail-in, .lens-strip-tail .lens-tail-label.lens-tail-in{ display:block; }
.lens-tailgroup .lens-tail-label.lens-tail-in.lens-tail-none, .lens-strip-tail .lens-tail-label.lens-tail-in.lens-tail-none{ display:none; }
.lens-tucked .lens-tail-label.lens-tail-in, .lens-strip .lens-tail-label.lens-tail-in{ font-size:7px; line-height:8px; padding:1px 2px; letter-spacing:0; }
.lens-hero-scale{ margin-top:2px; } .lens-scale-cell b{ margin-top:1px; }
.lens-bar.lens-hero.lens-tucked .lens-tailgroup .lens-tail-label.lens-tail-in, .lens-strip .lens-strip-tail .lens-tail-label.lens-tail-in{ font-size:7px; line-height:8px; padding:1px 2px; letter-spacing:0; }
.lens-strip{ height:38px; }


/* ===================================================================== Phil 2026-10-01 10:15 */
/* (1, part) one text colour in every box: white, with a soft shadow that keeps it legible on a light box */
#board-hero .lens-box .board-bar-seg-pct, #board-hero .lens-box .board-bar-seg-name, #board-hero .lens-box.board-bar-seg-dark .board-bar-seg-pct,
#board-hero .lens-box.board-bar-seg-dark .board-bar-seg-name, #board-hero .lens-circle{ color:#fff !important; text-shadow:0 0 3px rgba(11,18,36,.75), 0 0 1px rgba(11,18,36,.9); }
/* (3) Others clearly distinct in the main bar: a white square round it */
.lens-hero .lens-tailgroup, .lens-strip .lens-strip-tail{ box-shadow:none !important; outline:2.5px solid #fff; outline-offset:-2.5px; }
/* (3) the little percent bar keeps every operator's percent: text 2pt smaller, shown down to a 14px cell */
.lens-scale-cell b{ font-size:8px; }
/* (narrow cells under 16px still hide their label: no collisions) */
/* (4) the title pill: the first bubble, same height, an oval -- the flag and SAGD Atlas; a tap goes home */
#trail-region.trail-btn{ width:auto; padding:0 14px 0 8px; border-radius:22px; gap:7px; display:flex; align-items:center; }
#trail-region .trail-title{ font:800 11.5px/1 var(--display, system-ui); letter-spacing:.1em; text-transform:uppercase; color:#1f0b0f; white-space:nowrap; }
#trail-region .trail-title b{ font-weight:800; }
/* (4) the options open from the RIGHT */
#drawer{ left:auto !important; right:0; border-right:none; border-left:1px solid var(--hair); box-shadow:-24px 0 48px rgba(0,0,0,.4); transform:translateX(100%); }
#drawer.open{ transform:translateX(0); }
/* (8) the functional set, right-hand column, rounded squares (the trail stays round): gear, zoom, map only */
#bubble-menu.gear-btn{ border-radius:12px; }
#bubble-menu.gear-btn svg{ fill:none; stroke:#1f0b0f; stroke-width:1.6; }
.fn-btn{ position:absolute; right:16px; top:154px; z-index:21; width:44px; height:44px; border-radius:12px; background:rgba(255,255,255,.95);
  border:1px solid rgba(30,10,14,.1); box-shadow:0 2px 10px rgba(30,10,14,.18); display:flex; align-items:center; justify-content:center; cursor:pointer; padding:0; }
.fn-btn svg{ width:22px; height:22px; fill:none; stroke:#1f0b0f; stroke-width:1.6; stroke-linejoin:round; }
.fn-btn[aria-pressed="true"]{ background:#0b1224; } .fn-btn[aria-pressed="true"] svg{ stroke:#fff; }
.maplibregl-ctrl-top-right .maplibregl-ctrl-group{ border-radius:12px !important; overflow:hidden; }


/* ===================================================================== Phil 2026-10-01 11:00: FOLDERS */
/* the card is gone: the sheet and the card are see-through, so the map shows between the tabs; each region's folder
   body carries its colour -- Canada a deep red now too (Phil A: "lets do a deep red as the background color") */
#board.landing{ background:transparent !important; box-shadow:none !important; }
#board-hero.lens{ background:transparent !important; border:none !important; padding:0 !important; }
#board-hero.lens[data-region="CA"]{ --rg-bg:#4a121b; }
#board-hero.lens .lens-flag-tabs{ gap:8px; padding:0 2px; }
#board-hero.lens .lens-flag-tab{ background:rgba(11,18,36,.88); border-color:rgba(231,238,243,.28); backdrop-filter:blur(4px); }
#board-hero.lens .lens-flag-tab.lit{ background:var(--rg-bg); }
#board-hero.lens .lens-frame{ border-radius:0 0 14px 14px; box-shadow:0 10px 30px rgba(0,0,0,.35); }
#board-hero.lens .lens-flag-tabs:has(.lens-flag-tab.lit:first-child) + .lens-frame{ border-top-left-radius:0; }
/* D/F: the pyramid-era gaps gone -- a section sits right on its title / tab */
.lens-coframe{ margin-top:14px; padding-top:8px; }
.lens-co-head{ margin:0 0 6px; }
#board-hero .lens-top{ margin-bottom:0; }
.lens-subject{ margin-bottom:4px; }
.lens-gap{ height:16px !important; }
/* the landing: the table sits right under the percent graph (bars' bottom margin and the header's top margin trimmed) */
#board-hero.lens .lens-frame .lens-bars{ margin-bottom:4px; }

/* Phil 10-01 11:40: the title pill stands alone, then FOUR filter circles; the row tightened to fit a phone */
#trail-region.trail-btn{ width:40px; padding:0; border-radius:50%; }
.trail-row{ gap:6px; }
.trail-row .bubble{ width:40px; height:40px; }
.trail-pill{ width:auto !important; padding:0 10px 0 6px; border-radius:20px !important; display:flex; align-items:center; gap:5px; }
.trail-pill img{ height:20px; width:auto; }
.trail-pill .trail-title{ font:800 10px/1 var(--display, system-ui); letter-spacing:.08em; text-transform:uppercase; color:#1f0b0f; white-space:nowrap; }
/* PHASE 3 stage 3 (Fable verify 2026-10-06): a project with areas makes FIVE circles -- the row tightens so the last one
   clears the gear (>= 8 px) at 390 px */
.trail-row.trail-five{ gap:4px; }
.trail-row.trail-five .bubble{ width:38px; height:38px; }
.trail-row.trail-five .trail-pill{ padding:0 7px 0 5px; }
.trail-row.trail-five .trail-pill .trail-title{ font-size:9px; letter-spacing:.04em; }
.trail-row.trail-five .trail-btn .trail-txt{ padding:0 1px; }
#nav-cluster{ left:10px; top:14px; }
#bubble-menu.gear-btn{ width:40px; height:40px; right:10px; top:14px; }
.fn-btn.fn-hidden{ display:none; }
/* the region colours never read as a company: dark folder bodies, muted borders no operator uses */
#board-hero.lens[data-region="CA"]{ --rg:#b0404c; }
#board-hero.lens[data-region="AB"]{ --rg:#6d86b3; }
#board-hero.lens[data-region="SK"]{ --rg:#5f9a7a; }


/* ===================================================================== Phil 11:55 (his two marked screenshots) */
/* the folder's left / right edges: the sheet's side gutter down to 3px */
#board.landing{ padding-left:3px !important; padding-right:3px !important; }
/* the dead space under the bar and before the table */
.lens-hero-scale{ margin-bottom:0 !important; }
#board-hero.lens .lens-frame{ padding-top:8px; }
/* the AB / SK tabs readable when not picked */
#board-hero.lens .lens-flag-tab:not(.lit){ opacity:1 !important; }
#board-hero.lens .lens-flag-tab:not(.lit) .lens-flag-share, #board-hero.lens .lens-flag-tab:not(.lit) .lens-flag-pct{ color:#e7eef3 !important; }
#board-hero.lens .lens-flag-tab:not(.lit) img{ opacity:1 !important; }
/* Cenovus: the strip sits close on the company frame; the projects row close on TOP PADS */
.lens-coframe{ margin-top:8px !important; padding-top:6px !important; }
.lens-gap{ height:10px !important; }
.lens-circles-head{ margin-top:0; }
.lens-bar.lens-circlebar{ padding-top:4px !important; }

.lens-bar.lens-projbar .board-bar-seg-name{ display:block; }


.lens-section-title{ font:700 10.5px/1 var(--display, system-ui); letter-spacing:.12em; text-transform:uppercase; color:var(--frost); margin:10px 2px 6px; }
.lens-section-title span{ font-weight:500; opacity:.75; }


/* ===================================================================== Fable verify of v=20261001f (folded into FOLDERS 1) */


/* ===================================================================== FOLDERS 2: the stacked chart */
.chart-stack-band{ opacity:1; stroke:rgba(231,238,243,.75); stroke-width:.75; vector-effect:non-scaling-stroke; }
.lens-stack-legend{ display:flex; flex-wrap:wrap; gap:4px 10px; margin:4px 0 0; font-size:10.5px; color:var(--frost); }
.lens-stack-legend .lens-stack-other{ font-style:italic; }
.lens-stack-note{ flex-basis:100%; font-size:9.5px; opacity:.7; }

.lens-stack-item{ display:inline-flex; align-items:center; gap:4px; }
.lens-stack-item .dot{ width:8px; height:8px; border-radius:50%; display:inline-block; }


/* ===================================================================== Fable verify of v=20261001i (folded into FOLDERS 3) */
/* (4) trail names break only at spaces */
.trail-btn .trail-txt{ overflow-wrap:normal !important; word-break:keep-all !important; hyphens:none; }


/* ===================================================================== Fable verify of v=20261001j (folded into FOLDERS 4) */
/* (b) dark text on light boxes, no shadow */
#board-hero .lens-on-light .board-bar-seg-pct, #board-hero .lens-on-light .board-bar-seg-name, #board-hero .lens-on-light.lens-circle,
#board-hero .lens-on-light .lens-circle-sub, #board-hero .lens-on-light .lens-name, #board-hero .lens-circle.lens-on-light *{ color:#14161a !important; text-shadow:none !important; }
/* (b) the rank chip in a KPI block reads in the block's own text colour, never the company ink */
#board-hero .company-kpi-rank{ color:var(--frost) !important; opacity:.8; }

/* ===================================================================== FOLDERS 4: no gaps -- every picked tab opens straight into its folder */
/* (Phil 10-01 D: "there should be no gap between the title and the section... probably a relic of our pyramids";
   his 11:55 marks: the space under the logo strip before the company frame, and between the projects row and TOP PADS) */
.lens-gap{ height:0 !important; }
.lens-coframe{ margin-top:0 !important; }


/* ===================================================================== JUDGE-2: the plants note */
#board-steam-plants .sp-note{ font-size:12px; color:var(--frost); opacity:.8; margin:4px 2px 10px; line-height:1.4; }

/* PHASE 3 stage 1 (2026-10-05): the record line -- the filed recovery, the expected ultimate, the year; source on tap */
.lens-record{ margin:0 0 8px; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.lens-record-line{ font-size:11px; color:var(--core); line-height:1.3; font-variant-numeric:tabular-nums; }
.lens-record-line b{ font-size:17px; font-weight:700; color:var(--frost); margin-left:2px; }
.lens-record-dot{ color:var(--core-dim); }
.lens-record-yr{ font-size:11px; color:var(--core); }
.lens-record-basis{ font-size:11px; font-weight:700; color:var(--frost); letter-spacing:.02em; } /* the basis the operator files: OBIP, EBIP, PBIP... */
.lens-record-spark{ display:block; margin-top:3px; max-width:100%; height:auto; }
.lens-record-path{ fill:none; stroke:var(--frost); stroke-width:1.4; stroke-linejoin:round; opacity:.85; }
.lens-record-spark circle{ fill:var(--frost); }
.lens-record-ax{ font-family:var(--mono); font-size:8px; fill:var(--core); }
.lens-record-src{ display:none; font-family:var(--mono); font-size:10px; color:var(--core); margin-top:2px; }
.lens-record.open .lens-record-src{ display:block; }

/* PHASE 3 stage 3: the area circle shows only where the project has areas */
.trail-btn[hidden]{ display:none !important; }
/* PLAN 3 item 1 (2026-10-13): the Details row is a button row in the folder's own tokens -- Project Data filled and
   bigger, Filings / Pipelines / Compliance as outline pills, "?" a circle. One row; wraps on a phone. --line is the
   folder hairline (plan 1 A); --hair until that lands. */
.lens-data-row{ display:flex; flex-wrap:wrap; align-items:center; gap:4px; margin:8px 0 10px; } /* one line at 390px with ~9px to spare: a 1px fit wrapped on the Pi's Chromium */
.lens-data-btn{ font:600 11px/1 var(--display, system-ui); letter-spacing:.02em; color:var(--frost); background:transparent;
  border:1px solid var(--line, var(--hair)); border-radius:999px; padding:7px 6px; cursor:pointer; white-space:nowrap; }
.lens-data-btn:hover, .lens-data-btn:focus-visible{ border-color:var(--frost); outline:none; }
.lens-data-main{ font-size:13px; font-weight:700; background:var(--ember); border-color:var(--ember); color:var(--ink); padding:8px 8px; }
.lens-data-main:hover, .lens-data-main:focus-visible{ border-color:var(--ember); filter:brightness(1.08); }
#board-hero.lens-card-light .lens-data-main{ color:#e7eef3; } /* a light company: the fill is ink, the text frost */
.lens-data-help{ width:28px; height:28px; padding:0; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; font-size:13px; font-weight:700; margin-left:auto; }

/* Phil 2026-10-06 ruling 1: recovery is data -- a pads-table column and a pad's closed details row, never a headline */
.lens-record-details{ border-top:1px solid var(--hair); margin:6px 0 8px; padding-top:6px; }
.lens-record-head{ display:flex; justify-content:space-between; align-items:baseline; font-size:11px; }
.lens-record-body{ display:none; margin-top:4px; }
.lens-record-details.open .lens-record-body{ display:block; }

/* PHASE 3 stage 5: a pad's status -- today (Petrinex) over the record (the filing's word, dated, source on tap) */
.lens-status{ margin:2px 0 6px; }
.lens-status-now{ font:500 12px/1.35 var(--sans, system-ui); color:inherit; opacity:.85; }
.lens-status-now b{ font-weight:700; opacity:1; }
.lens-status .lens-status-rec{ margin-top:1px; }


/* ===================================================================== ROUND 2 (Foster Creek review, 2026-10-07) */
/* #1 ONE table (app.js atableHtml) for every table on the site: this block is the whole of its style. The name column
   takes what is left; the figure columns are fixed (s / m / l), right-aligned in tabular numerals, each with a 12px
   gutter before it (D2); the rank a plain small number; headers wrap only at spaces. When the columns do not fit the card
   the table scrolls inside its own frame, never the page. (The board-share-* / lens-* names on its cells are hooks.) */
:root{ --at-rank:24px; --at-name:76px; --at-s:42px; --at-m:50px; --at-l:58px; --at-gut:12px; --at-edge:8px; }
.atable-frame{ overflow-x:auto; overflow-y:hidden; -webkit-overflow-scrolling:touch; overscroll-behavior-x:contain; margin:0 0 6px;
  border-radius:4px; box-shadow:inset 0 0 0 1px var(--hair); }
.atable{ width:100%; table-layout:fixed; border-collapse:separate; border-spacing:0; margin:0;
  min-width:calc(var(--at-nr) * var(--at-rank) + var(--at-name) + var(--at-ns) * var(--at-s) + var(--at-nm) * var(--at-m) + var(--at-nl) * var(--at-l) + var(--at-edge));
  font:400 12px/1.25 var(--display); color:var(--frost); }
.atable col.at-c-rank{ width:var(--at-rank); }
.atable col.at-w-s{ width:var(--at-s); } .atable col.at-w-m{ width:var(--at-m); } .atable col.at-w-l{ width:var(--at-l); }
.atable col.at-w-s:last-child{ width:calc(var(--at-s) + var(--at-edge)); } .atable col.at-w-m:last-child{ width:calc(var(--at-m) + var(--at-edge)); }
.atable col.at-w-l:last-child{ width:calc(var(--at-l) + var(--at-edge)); }
.atable thead, .atable tfoot{ display:table-header-group; }
.atable tfoot{ display:table-footer-group; }
.atable tbody{ display:table-row-group; margin:0; gap:0; }
.atable tr{ display:table-row; margin:0; padding:0; border:0; gap:0; min-height:0; font:inherit; color:inherit; letter-spacing:normal; text-transform:none; }
.atable th, .atable td{ box-sizing:border-box; width:auto; min-width:0; max-width:none; height:32px; margin:0; padding:0 0 0 var(--at-gut);
  vertical-align:middle; text-align:right; white-space:nowrap; overflow:hidden; text-overflow:clip; flex:none; opacity:1;
  font:inherit; font-variant-numeric:tabular-nums; letter-spacing:normal; text-transform:none; color:var(--frost);
  border:0; border-bottom:1px solid var(--hair); box-shadow:none; background:none; }
.atable th:last-child, .atable td:last-child{ padding-right:var(--at-edge); }
.atable .at-rank{ padding:0 0 0 4px; text-align:left; font-size:10px; color:var(--core); }
.atable .at-name{ padding-left:6px; text-align:left; white-space:normal; }
.atable .at-main{ display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.atable .at-sub{ display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:10px; line-height:1.2; color:var(--core); }
.atable .at-mark{ float:left; width:24px; height:18px; margin:0 6px 0 0; padding:0; border-radius:5px; display:flex; align-items:center; justify-content:center;
  box-shadow:0 0 0 1px var(--line, rgba(255,255,255,.22)); }
.atable .at-mark .board-mark{ height:12px; max-width:18px; }
/* PLAN 2 item 4: a steam-plant row wears the map's CPF mark (the 26 px map mark at the staging page's table scale) */
.atable .sp-cpf{ float:left; width:20px; height:20px; margin:0 6px 0 2px; }
.atable thead th{ height:auto; padding-top:6px; padding-bottom:5px; vertical-align:bottom; white-space:normal; overflow-wrap:normal; word-break:keep-all; hyphens:none;
  font-size:10.5px; font-weight:500; line-height:1.15; color:var(--core); }
.atable thead th.at-name, .atable thead th.at-rank{ text-align:left; }
.atable tr.at-total td{ font-weight:700; } /* Phil 01:20: the total leads the table; the row rule (--line via --hair) stays under it */
.atable tr.at-total td.at-name{ font-weight:500; color:var(--core); }
.atable tr.at-total b{ font-weight:700; color:var(--frost); }
.atable tr[role="link"]{ cursor:pointer; }
.atable tr[role="link"]:hover .at-main{ color:var(--ember); text-decoration:underline; text-underline-offset:2px; }
.atable tr.lens-row-lit td{ background:var(--ember-wash-2); }
.atable .at-span{ text-align:right; color:var(--core); }
.atable tr.at-rule td{ height:auto; padding:8px 0 3px 6px; text-align:left; font-size:10px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--core); }
.atable .lens-hist-row .at-main{ color:var(--core); }
.atable .sp-unreported{ white-space:normal; font-size:10px; line-height:1.2; color:var(--core); }
.atable .lens-pair-tag{ font-size:10px; color:var(--core); }
.atable .lens-uwi{ font-size:9px; color:var(--core); }
/* #2: the pads KPI names the record on tap */
.lens-kpi-tap{ cursor:pointer; }
.lens-kpi-rec{ display:none; }
.lens-kpi-tap.open .lens-kpi-rec{ display:inline; }
.atable td.at-lead{ padding-left:6px; text-align:left; white-space:normal; }
/* #3: the trail's area circle in its area's tone */
#trail-area.trail-toned{ background:var(--trail-tone); border-color:var(--trail-tone); }
#trail-area.trail-toned .trail-txt{ color:#ffffff; }
#trail-area.trail-toned.trail-toned-light .trail-txt{ color:#0b1224; }
/* #4: the company row -- every name INSIDE its box, one line or two broken at a space (app.js lensFitProjNames); Other
   reads its word above its percent, inside its white border */
.lens-coframe .lens-bar.lens-projbar .board-bar-seg-body{ flex-direction:column; align-items:center; justify-content:center; gap:1px; padding:0 2px; min-width:0; }
.lens-coframe .lens-bar.lens-projbar .board-bar-seg-name{ display:block; max-width:100%; white-space:normal; word-break:keep-all; overflow-wrap:normal; hyphens:none;
  overflow:visible; text-overflow:clip; text-align:center; line-height:1.1; font-size:10px; }
.lens-coframe .lens-bar.lens-projbar.board-bar-tall{ height:44px; }
.atable tr.at-total .board-donut-unit{ font-size:10px; font-weight:500; color:var(--core); }
/* PHASE 3 stage 6: the plant block -- under the steam plants, the same table; its filing and page on tap */
#board-steam-plants .lens-plant{ margin:14px 0 0; cursor:pointer; -webkit-tap-highlight-color:transparent; }
.lens-plant .lens-record-src{ display:none; font-family:var(--mono); font-size:10px; color:var(--core); margin-top:2px; }
.lens-plant.open .lens-record-src{ display:block; }
/* PHASE 3 stage 7: a pad's filed plots -- a row of thumbnails (scrolls in its own frame), the year under each; a tap
   opens the plot whole with its filing and page */
.lens-plots{ margin:10px 0 6px; }
.lens-plot-row{ display:flex; gap:8px; overflow-x:auto; overscroll-behavior-x:contain; padding:0 0 6px; -webkit-overflow-scrolling:touch; }
.lens-plot{ flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:3px; padding:0; border:0; background:none; cursor:zoom-in; color:var(--frost); }
.lens-plot img{ display:block; width:120px; height:auto; border-radius:3px; background:#fff; box-shadow:0 0 0 1px var(--hair); }
.lens-plot-yr{ font:500 11px/1 var(--display); font-variant-numeric:tabular-nums; color:var(--core); }
.lens-plot-view{ position:fixed; inset:0; z-index:200; background:rgba(5,9,18,.88); display:flex; align-items:center; justify-content:center; padding:16px; cursor:zoom-out; }
.lens-plot-view figure{ margin:0; max-width:100%; max-height:100%; display:flex; flex-direction:column; gap:8px; }
.lens-plot-view img{ max-width:100%; max-height:calc(100vh - 90px); object-fit:contain; background:#fff; border-radius:3px; }
.lens-plot-view figcaption{ font:400 12px/1.35 var(--display); color:#e7eef3; }

/* ===================================================================== Phil 2026-10-08 (global fixes, round 1) */
/* 1. the title: the level's name alone, at the top of the frame, in the old subject line's small font */
#board-hero.lens .lens-frame > .lens-title{ font-size:12px; line-height:1.3; margin:0 0 6px; color:var(--frost); }
/* 2. the tab corners meet the frame: the outer tabs flush with the frame's outer edges, one 12px radius on every tab,
   the frame square under the tab row, one 2px line for the open tab and the frame, and the open tab's base flared into
   the frame's top line with a concave 8px fillet each side (none on the outer edge, where tab and frame are one line) */
#board-hero.lens .lens-flag-tabs{ padding:0; gap:8px; }
#board-hero.lens .lens-flag-tab{ position:relative; border-radius:12px 12px 0 0; }
#board-hero.lens .lens-flag-tab.lit{ border-width:2px; margin-bottom:-2px; }
#board-hero.lens .lens-frame,
#board-hero.lens .lens-flag-tabs:has(.lens-flag-tab.lit:not(:first-child)) + .lens-frame{ border-width:2px; border-radius:0 0 14px 14px; }
#board-hero.lens .lens-flag-tab.lit::before, #board-hero.lens .lens-flag-tab.lit::after{ content:''; position:absolute; bottom:0; width:8px; height:8px; pointer-events:none; }
#board-hero.lens .lens-flag-tab.lit::before{ left:-8px; background:radial-gradient(circle at 0 0, transparent 5.6px, var(--rg) 6px, var(--rg) 7.6px, var(--rg-bg) 8px); }
#board-hero.lens .lens-flag-tab.lit::after{ right:-8px; background:radial-gradient(circle at 100% 0, transparent 5.6px, var(--rg) 6px, var(--rg) 7.6px, var(--rg-bg) 8px); }
#board-hero.lens .lens-flag-tab.lit:first-child::before, #board-hero.lens .lens-flag-tab.lit:last-child::after{ content:none; }
/* 4. the sheet is locked: it scrolls up and down inside, never slides sideways or drags the page behind it */
html, body{ overscroll-behavior:none; }
#app{ overflow:hidden; }
#board-scroll{ overflow-x:hidden; overscroll-behavior:contain; }
/* 5. held on screen while scrolling down: the flag tabs, the companies strip, and the deepest bar (app.js lensPinUpdate) */
#board-hero.lens > .lens-flag-tabs{ position:sticky; top:calc(-1 * var(--pin-pad, 8px)); z-index:6; background:#0b1224; } /* Phil 2026-10-12 #5: ink at rest too, no map in the gaps */
#board-hero.lens.lens-pinned > .lens-flag-tabs::after{ content:''; position:absolute; left:0; right:0; bottom:-2px; height:2px; background:var(--rg); z-index:-1; }
#board-hero.lens .lens-frame > .lens-strip{ position:sticky; top:calc(var(--pin-tabs-h, 56px) + 2px + 8px - var(--pin-pad, 8px)); z-index:4; }
#board-hero.lens .lens-frame > .lens-strip.lens-strip-held{ box-shadow:0 0 0 8px var(--rg-bg); }
.lens-bar.lens-pin-held{ position:fixed !important; z-index:5; margin:0 !important; box-shadow:0 0 0 8px var(--pin-bg, transparent); }

/* PLAN 3 item 3 (2026-10-13): the card's way back to the lens -- "‹ <project>" at the top, "‹ Back" on every section
   header (pinned while its section scrolls) */
.card-bar{ display:flex; align-items:center; margin:0 0 12px; }
/* PLAN 4 (the Read menu): the project's entry in the Project notes, opposite the way back */
.card-notes{ margin-left:auto; font:700 12px/1 var(--display, system-ui); color:var(--frost); text-decoration:none; border:1px solid var(--line, var(--hair)); border-radius:999px; padding:7px 12px; white-space:nowrap; }
.card-notes:hover, .card-notes:focus-visible{ border-color:var(--frost); outline:none; }
.card-back{ font:700 12px/1 var(--display, system-ui); color:var(--frost); background:transparent; border:1px solid var(--line, var(--hair));
  border-radius:999px; padding:7px 12px 7px 10px; cursor:pointer; white-space:nowrap; max-width:100%; overflow:hidden; text-overflow:ellipsis; }
.card-back:hover, .card-back:focus-visible{ border-color:var(--frost); outline:none; }
.section-back{ flex:none; font:600 10px/1 var(--display, system-ui); color:var(--core); background:transparent; border:1px solid var(--line, var(--hair));
  border-radius:999px; padding:5px 8px; cursor:pointer; white-space:nowrap; margin-left:8px; }
.section-back:hover, .section-back:focus-visible{ color:var(--frost); border-color:var(--frost); outline:none; }
.collapse-head-row{ display:flex; align-items:center; border-top:1px solid var(--hair); }
.collapse-head-row > .collapse-header{ flex:1; min-width:0; border-top:none; }
.collapse-head-row > .section-back{ margin-top:6px; }
.collapse-section.open > .collapse-head-row{ position:sticky; top:-26px; z-index:2; background:var(--steel); }
.section-label:has(> .section-back) > span:first-child{ margin-right:auto; }
@media (max-width:640px){ .collapse-section.open > .collapse-head-row{ top:-2px; } } /* the phone sheet's scroller has 2px of top padding, not 26 */

/* PLAN 3 item 4 (2026-10-13): the card in the site's style -- #panel IS the project's folder, full-screen. Chrome only:
   the chart, the timeline and the facts grid keep their markup and inherit these tokens.
   Ground: the company's card tone (paintCardTones sets --co / --co-text2 / .card-light from the lens's own values);
   the navy wells inside (--steel / --steel-2 / --ink) become shades of it. Lines: --line (plan 1 A's hairline, frost at
   22% on dark, ink at 28% on light) and every --hair inside reads it. Frame: 2px --co, 14px corners. */
#panel.card-co{ --line:rgba(231,238,243,.22); --hair:var(--line); --core:var(--co-text2); --core-dim:var(--co-text2);
  --steel:var(--co); --steel-2:color-mix(in srgb, var(--co) 84%, #000); --ink:color-mix(in srgb, var(--co) 70%, #000);
  background:var(--co); border:2px solid var(--co); font-variant-numeric:tabular-nums; }
#panel.card-co.card-light{ --line:rgba(11,18,36,.28); --frost:#0b1224; --ember:#0b1224; --steel-2:color-mix(in srgb, var(--co) 90%, #000);
  --ink:color-mix(in srgb, var(--co) 80%, #000); color:#0b1224; }
#panel.card-co #panel-scroll::-webkit-scrollbar-thumb{ background:var(--line); }
/* type: the lens sizes -- the section labels in the .lens-section-title caps style, 12px tables */
#panel.card-co .section-label, #panel.card-co .collapse-title{ font:700 10.5px/1 var(--display, system-ui); letter-spacing:.12em; text-transform:uppercase; color:var(--frost); }
#panel.card-co .collapse-meta{ font-size:10.5px; }
#panel.card-co table{ font-size:12px; }
#panel.card-co .collapse-section.open > .collapse-head-row{ background:var(--co); }
/* frame: the desktop side panel's left edge (< 900px), the floating card (>= 900px), the phone sheet's top corners */
@media (min-width:641px) and (max-width:899px){ #panel.card-co{ border-width:0 0 0 2px; } }
@media (min-width:900px){ #panel.card-co{ border-radius:14px; } }
/* arrival: the card slides up from the lens's own frame -- half -> full in 240 ms, the lens fading to 0.5 behind it */
#board.landing{ transition:opacity .24s ease-out; }
body.card-over-lens #board.landing{ opacity:.5; pointer-events:none; }
body.card-over-lens #panel{ z-index:61; }
@media (max-width:640px){
  #panel.card-co[data-detent="peek"] .card-bar{ display:none; } /* the peek bar stays name + 3 KPIs; dragging it up shows the way back */
  #panel.card-co{ border-width:2px 2px 0; border-radius:14px 14px 0 0; transition:transform .32s cubic-bezier(.2,.8,.2,1), height .24s ease-out; }
}
#panel.card-co.dragging{ transition:none; }
@media (prefers-reduced-motion: reduce){ #panel.card-co, #board.landing{ transition:none; } }
/* the operator's wordmark keeps the navy it was cut for (every lockup was picked to read on the old navy card), as a
   plate on the company ground -- Cenovus's teal wordmark vanishes on its own teal card, CNRL's white one on its grey */
#panel.card-co .scheme-header-top .logo-chip:not(.monogram){ background:#121c37; border-radius:8px; padding:6px 9px; box-sizing:border-box; }

/* ===================================================================== Phil 2026-10-12 #1: ONE line colour for everything inside a folder */
/* --line is the folder's hairline: the folder's own text tone at low alpha, so it reads on the red, navy, green and every
   company colour without a per-colour rule. Every table rule, divider and frame inset already reads --hair; inside a folder
   --hair IS --line. --hair is re-pointed on the company frame too: a custom property resolves its var() where it is
   declared, so the light card's --line has to be picked up there, not inherited already-resolved from .lens-frame.
   Tune the two numbers here, nowhere else. :root --hair stays navy (drawer, modals, picker, pad sheet). */
#board-hero.lens{ --line:rgba(231,238,243,.22); }                         /* dark grounds: frost at 22% */
#board-hero.lens .lens-frame, #board-hero.lens .lens-coframe{ --hair:var(--line); }
#board-hero.lens.lens-card-light .lens-coframe{ --line:rgba(11,18,36,.28); } /* a light company frame: ink at 28% */

/* PLAN folders E (2026-10-12): the phone landing sheet's two detents -- half (50vh) and peek, its bottom edge on the
   table's top frame line (app.js landingPeekPx measures --landing-peek-h on every render); the sheet slides like #panel */
@media (max-width:900px){
  #board.landing{ transition:top .28s cubic-bezier(.2,.8,.2,1), opacity .24s ease-out; }
  #board.landing[data-detent="peek"]{ top:calc(100% - var(--landing-peek-h, 50vh)); }
  #board.landing[data-detent="peek"] #board-scroll{ overflow-y:hidden; }
  #board.landing #board-hero > .lens-flag-tabs{ touch-action:pan-x; } /* the tab row is the sheet's drag edge */
}
@media (max-width:900px) and (prefers-reduced-motion: reduce){ #board.landing{ transition:none; } }

/* ===================================================================== PLAN B (Phil 2026-10-13): the folder */
/* ONE folder primitive: the picked box in a bar IS the tab; from its two bottom corners the frame drops (the neck,
   app.js drawFolderNecks) to the body, steps out square to the full width and wraps everything that belongs to the pick,
   closing with rounded corners -- the flag tabs -> .lens-frame geometry, one level down. --fr = the colour of what was
   picked (Phil: "1 yes thats great"); --fr-bg = the parent ground one step darker. Converted: the Others level. */
/* --ground: the ground a folder sits on (the region's in the frame, the parent body's inside a folder); a body's own ground
   is that one step darker unless the renderer gives one (the company folder: the company's card colour) */
#board-hero.lens .lens-frame{ --ground:var(--rg-bg); }
.folder{ position:relative; --fr-bg:color-mix(in srgb, var(--ground, var(--rg-bg)) 78%, #0b1224); }
.folder-body{ --ground:var(--fr-bg); }
#board-hero.lens .folder > .lens-bars.folder-tabs{ margin-bottom:0; } /* (out-ranks .lens-frame .lens-bars' 4px: the body is flush) */
.folder-body{ position:relative; margin-top:var(--neck, 10px); border:2px solid var(--fr); border-radius:0 0 var(--lens-r, 0px) var(--lens-r, 0px);
  background:var(--fr-bg); padding:8px 2px 10px; } /* 2px sides, not the plan's 8: at 8 the table cuts "Athabasca Oil" and
  "Northern Hawk" to "..." at 390px (measured; 2px is the widest inset that cuts none) */
.folder-neck{ position:absolute; left:0; top:0; pointer-events:none; overflow:visible; z-index:2; }
/* the lit box wears the tab: the body's own 2px line, top and sides, open at the bottom (an overlay -- the box's stripes
   are children and would paint over an inset shadow) */
.folder > .folder-tabs .lens-lit{ position:relative; box-shadow:none !important; outline:none !important; }
.folder > .folder-tabs .lens-lit::after{ content:''; position:absolute; inset:0; border:2px solid var(--fr); border-bottom:none; pointer-events:none; z-index:1; }
/* the old frames, gone inside a folder: the white square round Others, the black outline round the tucked bar */
.folder > .folder-tabs .lens-bar.lens-hero.lens-tucked{ outline:none; }


/* ===================================================================== Phil's notes 2026-10-13 (first phone check): the tabs */
/* ONE corner rule for the lens: --lens-r. Phil leans to no curves, so it is 0 -- the tabs, the frame, every folder body
   and the company frame read it; curves back = one number here. */
#board-hero.lens{ --lens-r:0px; }
/* (1) flush: the three tabs touch, one continuous shelf (a shared 2px side line, not two); (2) the same height: every
   tab's top on one line, the same padding; the frame's 2px line runs under the others, and the picked one alone runs
   those 2px on into the frame (its ground over the line -- the open bottom), so the pick reads by colour and its open
   bottom, never by height. No bottom border on any tab: a side line meeting a bottom line mitres into a diagonal */
#board-hero.lens .lens-flag-tabs{ gap:0; padding:0; align-items:stretch; } /* stretch: the lit tab's -2px margin makes it exactly 2px longer */
#board-hero.lens .lens-flag-tab{ border:2px solid rgba(231,238,243,.28); border-bottom:0; border-radius:var(--lens-r) var(--lens-r) 0 0;
  margin-bottom:0; padding:9px 4px 9px; }
#board-hero.lens .lens-flag-tab + .lens-flag-tab{ margin-left:-2px; }
#board-hero.lens .lens-flag-tab.lit{ z-index:1; border:2px solid var(--rg); border-bottom:0; margin-bottom:-2px; padding:9px 4px 11px; }
#board-hero.lens .lens-flag-tab.lit::before, #board-hero.lens .lens-flag-tab.lit::after{ content:none; } /* the fillets were curves */
/* (3) square: the frame under the tabs */
#board-hero.lens .lens-frame,
#board-hero.lens .lens-flag-tabs:has(.lens-flag-tab.lit:not(:first-child)) + .lens-frame,
#board-hero.lens .lens-flag-tabs:has(.lens-flag-tab.lit:first-child) + .lens-frame{ border-radius:0 0 var(--lens-r) var(--lens-r); }
/* the same rule on every frame-like shape in the lens: the bars, the strips, the table frames, the company frame. Controls
   and glyphs keep their own shapes (the pill buttons, the chart toggles, the legend dots, the logo chips, label badges) */
#board-hero.lens .board-bar, #board-hero.lens .lens-strip, #board-hero.lens .atable-frame, #board-hero.lens .lens-coframe{ border-radius:var(--lens-r); }

/* ===================================================================== PLAN B, the company level (Phil 2026-10-13 12:36) */
/* the strips are tab rows: strip 1's lit box (the company, or Others) is a tab; through Others strip 2 is the first row of
   the Others body and its lit box the company's tab. The company frame is the company folder's body. The old frames go:
   the stripe's ember ring, the double inset on the lit box, the flare and the frame's own 1.5px border */
.folder > .lens-strip.folder-tabs{ margin:0; box-shadow:none; }
.folder > .folder-body.lens-coframe{ margin-top:var(--neck, 10px) !important; border:2px solid var(--fr); border-radius:0 0 var(--lens-r, 0px) var(--lens-r, 0px); } /* !important: three older .lens-coframe margin rules carry it */
/* held on scroll: strip 1 under the tabs, strip 2 under strip 1 -- the halo in the ground each strip sits on */
#board-hero.lens .lens-frame > .folder > .lens-strip{ position:sticky; top:calc(var(--pin-tabs-h, 56px) + 2px + 8px - var(--pin-pad, 8px)); z-index:4; }
#board-hero.lens .lens-frame .folder-body > .folder > .lens-strip{ position:sticky; z-index:4;
  top:calc(var(--pin-tabs-h, 56px) + 2px + 8px - var(--pin-pad, 8px) + var(--pin-strip-h, 38px) + 8px); }
#board-hero.lens .lens-frame .folder > .lens-strip.lens-strip-held{ box-shadow:0 0 0 8px var(--ground, var(--rg-bg)); }
/* Phil 10-01 D/F + 12:36 (1): no gap -- every picked tab opens straight into its folder (the flag tab -> frame geometry):
   the body's top line runs right under the tab row, cut open under the lit box by the neck (app.js drawFolderNecks), and
   the body's first row sits on that line */
#board-hero.lens .folder{ --neck:0px; }
#board-hero.lens .folder-body{ padding-top:0; }
#board-hero.lens .folder-body > .lens-top:first-child > .lens-bars,
#board-hero.lens .folder-body > .folder:first-child > .lens-bars.folder-tabs{ margin-top:0; } /* the body's first row on its line (.lens-bars' own 4px) */
/* inside the company frame each level costs its 2px line alone (no inset): four deep, the pairs table keeps the 342px its
   columns need at 390 (measured; with the 2px inset the pair level cut its cSOR column) */
#board-hero.lens .lens-coframe .folder-body{ padding-left:0; padding-right:0; }

/* ===================================================================== PLAN 4 item A5 (2026-10-13) */
/* the compare table and the entity table are atableHtml tables (the .atable block is their style); only what is theirs
   alone lives here: the pick's dot and name as one button, the remove x, and the entity table's word-sized pick columns */
.cmp-table .compare-flyto{ display:block; width:100%; background:none; border:0; padding:0; margin:0; font:inherit; color:var(--frost); text-align:left;
  cursor:pointer; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cmp-table .compare-flyto:hover, .cmp-table .compare-flyto:focus-visible{ color:var(--ember); text-decoration:underline; text-underline-offset:2px; outline:none; }
.cmp-table .compare-dot{ margin:0 6px 1px 0; vertical-align:middle; }
/* a pick's name may take two lines (never an ellipsis on a name); a rate column fits "63,753" and "Producing" */
.atable.cmp-table{ --at-name:104px; --at-l:64px; }
.atable.cmp-table td{ height:32px; padding-top:4px; padding-bottom:4px; } /* (a table cell's height is its floor: two-line names grow it) */
.atable.cmp-table td.at-name .compare-flyto, .atable.cmp-table td.at-name .at-main{ white-space:normal; line-height:1.25; }
.atable.cmp-table td.at-name .compare-flyto{ padding-left:14px; text-indent:-14px; }
.cmp-table .compare-remove{ width:22px; height:22px; border-radius:50%; border:1px solid var(--line, var(--hair)); font-size:13px; line-height:1; padding:0; }
.atable.entity-table{ --at-l:118px; --at-name:96px; }
.atable.entity-table td{ white-space:normal; height:auto; min-height:32px; padding-top:7px; padding-bottom:7px; line-height:1.3; text-align:left; overflow:visible; }
.atable.entity-table thead th.entity-col{ text-align:left; vertical-align:top; }
.atable.entity-table .entity-col-head{ display:flex; align-items:flex-start; gap:4px; }
.atable.entity-table .entity-col-head .compare-flyto{ flex:1; min-width:0; white-space:normal; font-weight:600; font-size:11px; line-height:1.2; }
.atable.entity-table .entity-col-head .compare-dot{ flex:none; margin:3px 0 0; }
.atable.entity-table .entity-col-remove{ flex:none; width:18px; height:18px; font-size:11px; }
.atable.entity-table td.at-name{ color:var(--core); position:sticky; left:0; background:var(--ink); z-index:1; }
.atable.entity-table td.at-name .at-main{ white-space:normal; overflow:visible; }
.atable.entity-table tr.entity-row-diff td.at-name{ box-shadow:inset 2px 0 0 var(--ember-dim); }
.atable.entity-table tr.at-rule td{ position:static; }
.atable.entity-table .entity-note-cell{ white-space:normal; color:var(--core); font-size:11px; }

/* ===================================================================== PLAN 4 item B (2026-10-13) */
/* the compare page as one connected object (v=compare2): the picks as chips, then a column of cards -- stacked on a
   phone, two columns from 900px. One pick lit: its marks at full strength in every card, the others faded. */
#compare2{ position:absolute; inset:0; background:var(--ink); overflow:auto; -webkit-overflow-scrolling:touch; padding:112px 22px 90px; }
#compare2-scroll{ max-width:1100px; margin:0 auto; }
@media (max-width:640px){ #compare2{ padding-left:16px; padding-right:16px; } }
.compare-bar .compare-try2{ margin-left:10px; }
.c2-empty{ display:flex; flex-direction:column; align-items:flex-start; gap:12px; }
.c2-picks{ display:flex; flex-wrap:wrap; gap:6px; margin:0 0 14px; align-items:center; }
.c2-pick{ display:inline-flex; align-items:center; gap:6px; min-height:30px; padding:0 4px 0 10px; border:1px solid var(--line, var(--hair)); border-radius:999px;
  font:600 12px/1 var(--display, system-ui); color:var(--frost); cursor:pointer; max-width:100%; }
.c2-pick .c2-pick-name{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.c2-pick.c2-lit{ border-color:var(--pick); box-shadow:inset 0 0 0 1px var(--pick); }
.c2-x{ flex:none; width:22px; height:22px; border-radius:50%; border:0; background:transparent; color:var(--core); font-size:14px; line-height:1; padding:0; cursor:pointer; }
.c2-x:hover, .c2-x:focus-visible{ color:var(--frost); outline:none; }
.c2-cards{ display:grid; grid-template-columns:1fr; gap:14px; }
@media (min-width:900px){ .c2-cards{ grid-template-columns:1fr 1fr; align-items:start; } .c2-card[data-card="table"]{ grid-column:1 / -1; } }
.c2-card{ border:1px solid var(--line, var(--hair)); border-radius:4px; background:var(--steel); padding:12px 12px 10px; min-width:0; }
.c2-card-head{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; margin:0 0 10px; }
.c2-card-title{ font:700 10.5px/1 var(--display, system-ui); letter-spacing:.12em; text-transform:uppercase; color:var(--frost); }
.c2-card-sub{ font-size:11px; color:var(--core); }
.c2-bar{ height:34px; margin:0 0 10px; border-radius:3px; }
.c2-bar .c2-seg{ min-width:3px; cursor:pointer; transition:opacity .12s; }
.c2-note{ font-size:11px; line-height:1.4; color:var(--core); margin:6px 0 0; }
.c2-share-table .at-main .compare-dot{ margin:0 6px 1px 0; vertical-align:middle; }
.c2-row{ cursor:pointer; }
.c2-stack-legend{ margin-top:4px; }
.c2-stack-legend .lens-stack-item{ cursor:pointer; }
.c2-all-toggle{ display:inline-flex; margin:0 0 8px; }
#compare2 .chart-stack-band, #compare2 .c2-seg, #compare2 .c2-row, #compare2 .lens-stack-item, #compare2 .c2-pick, #compare2 .c2-table-wrap [data-pick]{ transition:opacity .12s; }
#compare2.c2-has-lit .c2-dim{ opacity:.28; }
#compare2.c2-has-lit .c2-table-wrap .c2-dim{ opacity:.4; }
#compare2.c2-has-lit .c2-row.c2-lit td, #compare2.c2-has-lit .c2-table-wrap td.c2-lit{ background:var(--ember-wash-2); }
@media (prefers-reduced-motion: reduce){ #compare2 *{ transition:none !important; } }
#c2-stack-svg{ width:100%; height:auto; display:block; overflow:visible; } /* (the lens chart's own sizing: it fills its card) */
.c2-svg{ width:100%; height:auto; display:block; overflow:visible; }
.c2-pills{ display:flex; flex-wrap:wrap; gap:4px; margin:0 0 8px; }
.c2-line{ fill:none; stroke-width:2; stroke-linejoin:round; cursor:pointer; transition:opacity .12s, stroke-width .12s; }
.c2-line.c2-lit{ stroke-width:3.5; }
.c2-dot{ stroke:var(--ink); stroke-width:1.5; cursor:pointer; transition:opacity .12s; }
.c2-dot.c2-lit{ stroke:var(--frost); stroke-width:2.5; }
.c2-table-wrap .atable.entity-table{ width:auto; }
.c2-table-wrap .atable.entity-table col.at-c-name{ width:var(--at-name); }
@media (min-width:641px){ .c2-table-wrap .atable.entity-table{ --at-name:150px; --at-l:150px; } }
.c2-table-wrap .entity-cell{ display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; overflow:hidden; }
.c2-table-wrap .entity-cell.c2-open{ -webkit-line-clamp:unset; display:block; }
.c2-table-wrap .entity-cell.c2-clamped{ cursor:pointer; }
.c2-table-wrap .entity-cell.c2-clamped:not(.c2-open)::after{ content:''; }
.c2-table-wrap .atable-frame{ display:inline-block; max-width:100%; vertical-align:top; }
/* LAUNCH 2026-10-27 (Phil: "change the name everywhere to sagd.app"): the wordmark is lowercase "sagd" + the accented
   ".app" -- every wordmark/title pill drops the old uppercase SAGD ATLAS treatment */
.wordmark-text, .trail-pill .trail-title, #trail-region .trail-title{ text-transform:none; letter-spacing:.01em; }
.board-hero-wordmark .wordmark-text{ letter-spacing:.02em; }
.drawer-foot{ margin:18px 16px 24px; font-size:11px; line-height:1.45; color:var(--core); }
.drawer-foot a{ color:inherit; text-decoration:underline; }
/* LAUNCH A2: the display-month step-back note under a project's KPIs */
.lens-recon-note{ margin:4px 2px 8px; font-size:11px; line-height:1.35; color:var(--core); }
