/* WellSim UI — The PWF design language (thepwf.pages.dev): cool grey-cyan
   surfaces, one burnt-orange accent, IBM Plex Sans/Mono, uppercase
   letterspaced labels, flat corners, subtle shadows. The workbook cell
   semantics (green input / grey calculated / pink output) are preserved. */
:root {
  --bg: #E8ECED;
  --surface: #F6F8F8;
  --raised: #FFFFFF;
  --sunken: #DFE5E6;
  --ink: #0B1418;
  --ink-2: #46585F;
  --ink-3: #78898F;
  --line: #C9D4D7;
  --line-2: #AEBDC1;
  --accent: #C2540B;
  --accent-2: #93400A;
  --accent-soft: rgba(194, 84, 11, .10);
  --seq-lo: #D7E9EB;
  --seq-hi: #00636D;
  --good: #2C7048;
  --crit: #A93A2C;
  --shadow: 0 1px 2px rgba(11, 20, 24, .06), 0 6px 18px -10px rgba(11, 20, 24, .22);
  --barshadow: 0 1px 0 var(--line), 0 6px 16px -12px rgba(11, 20, 24, .5);
  --mono: "IBM Plex Mono", ui-monospace, Consolas, monospace;
  --sans: "IBM Plex Sans", -apple-system, "Segoe UI", system-ui, sans-serif;
}

* { box-sizing: border-box; }
body { margin: 0; font: 14px/1.45 var(--sans); background: var(--bg); color: var(--ink); }

/* ---------- header bar: light, sticky, with the live headline result ---------- */
header {
  position: sticky; top: 0; z-index: 30;
  background: var(--surface); color: var(--ink);
  padding: 10px 20px 0; display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  box-shadow: var(--barshadow);
}
header h1 { margin: 0; font: 700 19px/1 var(--sans); letter-spacing: -0.2px; }
header h1 em { font-style: italic; color: var(--accent); }
header .sub { color: var(--ink-3); font-size: 11.5px; flex: 1; min-width: 120px; }
#hdr-result { text-align: right; line-height: 1.1; display: none; }
#hdr-result .hv { font: 500 17px/1 var(--mono); color: var(--ink); font-variant-numeric: tabular-nums; }
#hdr-result .hk { display: block; font: 500 9.5px/1.4 var(--sans); text-transform: uppercase; letter-spacing: 0.8px; color: var(--ink-3); }
nav { display: flex; gap: 2px; flex-wrap: wrap; align-items: stretch; width: 100%; }
.tab {
  background: none; color: var(--ink-2); border: 0; border-bottom: 2px solid transparent;
  padding: 9px 16px 8px; cursor: pointer;
  font: 600 11.5px/1 var(--sans); text-transform: uppercase; letter-spacing: 1px;
}
.tab:hover { color: var(--ink); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }
.hdr-link {
  align-self: center; color: var(--ink-2); font: 500 10.5px/1 var(--sans);
  text-transform: uppercase; letter-spacing: 0.8px; text-decoration: none;
  border: 1px solid var(--line-2); padding: 6px 10px; margin-left: 4px; cursor: pointer;
  background: var(--raised);
}
.hdr-link:hover { border-color: var(--accent); color: var(--accent); }


/* account panel: the per-company server case database (free use stays) */
#acct-panel {
  position: absolute; top: 100%; right: 16px; z-index: 40; background: var(--raised);
  border: 1px solid var(--line); border-top: 2px solid var(--accent);
  padding: 12px 14px; width: 290px; box-shadow: var(--shadow);
}
#acct-panel .acct-title { font: 600 10.5px/1.3 var(--sans); text-transform: uppercase; letter-spacing: 0.8px; color: var(--ink-2); margin-bottom: 8px; }
#acct-panel input { display: block; width: 100%; margin-bottom: 6px; padding: 6px 8px; border: 1px solid var(--line); background: var(--surface); color: var(--ink); font: 400 13px var(--sans); }
#acct-panel input::placeholder { color: var(--ink-3); }
#acct-panel .acct-btns { display: flex; gap: 6px; margin: 4px 0 6px; flex-wrap: wrap; }
#acct-panel .acct-note { font-size: 10.5px; color: var(--ink-3); line-height: 1.4; }
/* name + Save share one row: "Save case to server" alongside Refresh and
   Sign out needed 301 px inside a 262 px panel, so the row wrapped. */
#acct-panel .acct-saverow { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; }
#acct-panel .acct-saverow input { flex: 1; min-width: 0; margin-bottom: 0; }
#acct-panel .acct-saverow .copybtn { flex: none; }
#acct-panel .acct-caseshead { font: 400 10px var(--sans); color: var(--ink-3); margin-top: 6px; }
/* the newest TWO rows are visible and the rest scroll (author request):
   a long list turned the panel into a wall that covered the app. */
#acct-cases { max-height: 58px; overflow-y: auto; margin-top: 2px; }
#acct-cases .case-row { display: flex; align-items: center; gap: 6px; padding: 3px 0; border-top: 1px solid var(--line); font-size: 11.5px; color: var(--ink); }
#acct-cases .case-row .nm { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#acct-cases .case-row .meta { color: var(--ink-3); font-size: 10px; }

main { padding: 14px 20px; }
.panel { display: grid; grid-template-columns: 460px 1fr; gap: 16px; align-items: start; }
@media (max-width: 1100px) { .panel { grid-template-columns: 1fr; } }

/* ---------- input cards ---------- */
.inputs fieldset, .inputs .group {
  background: var(--raised); border: 1px solid var(--line); border-radius: 2px;
  margin: 0 0 10px; padding: 10px 12px 12px; box-shadow: var(--shadow);
}
fieldset { min-inline-size: 0; }
.panel > div { min-width: 0; }
.inputs legend, .group h3 {
  font: 500 10.5px/1.3 var(--sans); text-transform: uppercase; letter-spacing: 1.1px;
  color: var(--ink-2); padding: 0 4px; margin: 0 0 6px;
}
/* compact input array: label | small box, flowing in two columns */
.rows { columns: 2; column-gap: 16px; }
.frow { display: grid; grid-template-columns: minmax(0, 1fr) 84px; gap: 6px; align-items: center; break-inside: avoid; margin-bottom: 2px; }
.frow label { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.4px; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.frow input {
  width: 100%; padding: 3px 5px; border: 1px solid var(--line); border-radius: 2px;
  background: #EDF5EC; font: 400 12.5px var(--mono); text-align: right;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.frow input:focus { outline: 2px solid var(--accent); background: #F3FAF2; }
.frow select { width: 100%; padding: 3px 4px; border: 1px solid var(--line); border-radius: 2px; background: var(--surface); font: 400 12px var(--sans); color: var(--ink); }
.frow .unit { color: var(--ink-3); font-size: 10px; margin-left: 3px; }
/* blank cells filled by the program: grayed italic until the user types */
input.computed { color: var(--ink-3) !important; font-style: italic; background: var(--sunken) !important; border-style: dashed !important; }
/* pure output columns (the workbook's pink prod_data outputs): read-only */
input.outcell { background: #F5ECEF !important; color: #5A4A52 !important; border-color: #D9C6CD !important; cursor: default; }

/* ---------- actions: flat accent, uppercase, letterspaced ---------- */
.action {
  display: block; width: 100%; margin-top: 4px; padding: 12px 10px;
  font: 600 12.5px/1 var(--sans); text-transform: uppercase; letter-spacing: 1.3px;
  color: var(--surface); background: var(--accent); border: 0; border-radius: 2px; cursor: pointer;
}
.action:hover { background: var(--accent-2); }
.action.secondary {
  background: var(--raised); color: var(--ink-2); border: 1px solid var(--line-2);
  font-size: 11px; padding: 9px 8px; margin-top: 8px;
}
.action.secondary:hover { border-color: var(--accent); color: var(--accent); background: var(--raised); }

/* reserve module: table takes half the page, chart beside it */
.panel.mode-reserve { grid-template-columns: 1fr 1fr; }
/* ...but only while a half page is still wide enough to draw in. The base
   .panel collapses at 1100px; this rule is more specific, so without its own
   query it kept the 50/50 split all the way down to the phone breakpoint and
   squeezed the chart to ~90px beside the fixed 250px results table. A chart
   needs ~350px and the table is a fixed 250px + 10px gap, so a half page
   must be ~610px. Measured: main padding + gap eats 71px, so a half page is
   (vw-71)/2 and the chart is that minus 260 — 610px of half page wants a
   ~1300px viewport. Below that, one column. */
@media (max-width: 1300px) { .panel.mode-reserve { grid-template-columns: 1fr; } }
/* production tables size to the half-page column like the oil one: no hard
   per-column minimums (they forced the 9-column gas table past its card on
   a 1366-wide screen). Only the date cell gets a floor, and reads left. */
#gas-prod-table td:first-child input,
#oil-prod-table td:first-child input,
#gas-sithp-table td:first-child input,
#oil-static-table td:first-child input { min-width: 88px; text-align: left; }
.tbl-actions { display: flex; gap: 6px; align-items: center; margin: 2px 0 4px; flex-wrap: wrap; }

/* reservoir-limit view: hide non-essential prod columns so the half-page
   table and the chart fit together (Date | FTHP | q | dt | Pwf remain) */
.rlt-slim .col-cgrStbMMscf, .rlt-slim .col-wgrStbMMscf,
.rlt-slim .col-gorScfStb, .rlt-slim .col-wcPct,
.rlt-slim .col-presPsi, .rlt-slim .col-z { display: none; }

/* big-font GIP result under the reserve calcs */
.giipbanner { margin: 10px 0 4px; line-height: 1.15; }
.giipbanner .method { display: block; font: 500 10px/1.6 var(--sans); text-transform: uppercase; letter-spacing: 1px; color: var(--ink-2); }
.giipbanner .val { font: 500 30px/1.1 var(--mono); color: var(--good); font-variant-numeric: tabular-nums; }
.giipbanner .val.warn { color: var(--accent-2); font-size: 19px; }

/* per-selection best-practice / limitation guidance */
.guidance { font-size: 11.5px; color: var(--ink-2); background: var(--surface); border-left: 3px solid var(--seq-hi); padding: 6px 9px; margin: 6px 0; white-space: pre-line; }

/* custom-pump curve: the rows that carry the thrust markers (workbook
   ESP sheet rows — index 3 = down-thrust limit, 5 = BEP, 7 = up-thrust
   limit; esp-catalog.js THRUST). The marker rows are inputs like any
   other — the colour says which physics reads them. */
.thrust-cell { font: 600 10.5px var(--sans); white-space: nowrap; padding: 0 6px; text-align: right; }
tr.thrust-down .thrust-cell { color: #2B5B8A; }
tr.thrust-bep .thrust-cell { color: #8A6D1A; }
tr.thrust-up .thrust-cell { color: #A0452F; }
tr.thrust-down input { background: #E8F0FB !important; }
tr.thrust-bep input { background: #FFF3D6 !important; }
tr.thrust-up input { background: #FBE9E7 !important; }
.thrust-legend { display: flex; gap: 12px; margin: 2px 0 6px; font: 400 11px var(--sans); color: var(--ink-2); }
.thrust-legend .sw { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 4px; vertical-align: -1px; border: 1px solid var(--line); }

.sens { width: 100%; border-collapse: collapse; margin: 4px 0; }
.sens th { font: 500 10px/1.4 var(--sans); text-transform: uppercase; letter-spacing: 0.4px; color: var(--ink-2); text-align: left; padding: 2px 4px; }
.sens td { padding: 2px 4px; }
.sens input {
  width: 100%; padding: 4px 5px; border: 1px solid var(--line); border-radius: 2px;
  background: #EDF5EC; font: 400 12.5px var(--mono); font-variant-numeric: tabular-nums; color: var(--ink);
}
.sens input:focus { outline: 2px solid var(--accent); }
.sens select {
  width: 100%; padding: 4px 3px; border: 1px solid var(--line); border-radius: 2px;
  background: #EDF5EC; font: 400 12px var(--sans); color: var(--ink); min-width: 74px;
}
.sens select:focus { outline: 2px solid var(--accent); }
/* Grid tables scroll sideways inside their own box rather than squeezing:
   with twelve columns the reserve prod_data cells collapsed to ~25 px, too
   narrow to read a pressure in. The floors below are what a value actually
   needs; the table takes the width it needs and the box scrolls. */
.gridscroll { overflow-x: auto; overflow-y: hidden; }
.sens th small { display: block; font: 400 8.5px/1.3 var(--sans); letter-spacing: 0; text-transform: none; color: var(--ink-3); }
.gridscroll .sens { width: auto; min-width: 100%; }
.gridscroll .sens th { white-space: nowrap; }
.gridscroll .sens td input { min-width: 62px; }
.gridscroll .sens td select { min-width: 78px; }
/* a checkbox cell (the multi-layer Active column) must not inherit the
   input floors above, or it stretches to a 62px box */
.sens td input[type=checkbox], .gridscroll .sens td input[type=checkbox] {
  min-width: 0; width: 18px; height: 18px; min-height: 0; margin: 6px auto; display: block; padding: 0;
}
.sens .col-active { width: 44px; text-align: center; }
.sens .col-name input { min-width: 80px; }
#oil-prod-table .col-date input { min-width: 104px; }
#oil-prod-table .col-gorScfStb input, #oil-prod-table .col-injMMscfd input { min-width: 72px; }
#oil-prod-table .col-wcPct input, #oil-prod-table .col-espHz input,
#oil-prod-table .col-dtDays input, #oil-prod-table .col-z input { min-width: 54px; }
/* the lift columns appear only when a row asks for them */
#oil-prod-table.no-gl .col-injMMscfd, #oil-prod-table.no-esp .col-espHz { display: none; }

.senshead { font: 500 10.5px/1.5 var(--sans); text-transform: uppercase; letter-spacing: 0.6px; color: var(--ink-2); margin: 8px 0 2px; }
.presrow { display: flex; gap: 8px; }
.presrow input { width: 90px; padding: 5px 6px; border: 1px solid var(--line); border-radius: 2px; background: #EDF5EC; font: 400 13px var(--mono); }
.radio { display: inline-flex; align-items: center; gap: 6px; margin-right: 16px; font-size: 13px; cursor: pointer; }
input[type="radio"], input[type="checkbox"] { accent-color: var(--accent); }

/* ---------- results ---------- */
.results .chart { background: var(--raised); border: 1px solid var(--line); border-radius: 2px; margin-bottom: 12px; min-height: 40px; box-shadow: var(--shadow); }
.chartrow { display: flex; gap: 10px; margin-bottom: 12px; align-items: stretch; }
.chartrow .chart { flex: 1; margin-bottom: 0; min-width: 0; }
/* stacked variant: results table full-width below the chart (forecast) */
.chartrow.stack { flex-direction: column; }
.chartrow.stack .datatable { width: 100%; max-height: 300px; }
.datatable { width: 250px; background: var(--raised); border: 1px solid var(--line); border-radius: 2px; padding: 4px 8px 8px; max-height: 380px; overflow: auto; box-shadow: var(--shadow); }
.datatable:empty { display: none; }
.dt-head { display: flex; justify-content: space-between; align-items: center; font: 500 10px/1.5 var(--sans); text-transform: uppercase; letter-spacing: 0.6px; color: var(--ink-2); margin: 4px 0 2px; }
.copybtn {
  font: 500 10px/1 var(--sans); text-transform: uppercase; letter-spacing: 0.8px;
  padding: 5px 10px; border: 1px solid var(--line-2); background: var(--raised); cursor: pointer; color: var(--ink-2);
}
.copybtn:hover { border-color: var(--accent); color: var(--accent); }
.copybtn:active { background: var(--accent-soft); }
.datatable table { border-collapse: collapse; width: 100%; margin-bottom: 6px; font-size: 11px; }
.datatable th { text-align: right; color: var(--ink-2); border-bottom: 1px solid var(--line-2); padding: 1px 4px; font-weight: 600; white-space: nowrap; }
.datatable td { text-align: right; padding: 1px 4px; border-bottom: 1px solid var(--line); font-family: var(--mono); font-size: 10.5px; font-variant-numeric: tabular-nums; }
.summary { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.summary .card { background: var(--raised); border: 1px solid var(--line); border-left: 3px solid var(--accent); padding: 8px 14px; min-width: 120px; box-shadow: var(--shadow); }
.summary .card .k { font: 500 9.5px/1.6 var(--sans); text-transform: uppercase; letter-spacing: 0.7px; color: var(--ink-3); }
.summary .card .v { font: 500 16px/1.2 var(--mono); color: var(--ink); font-variant-numeric: tabular-nums; }
.summary .card.warn { border-left-color: var(--crit); }
.note { font-size: 12px; color: var(--ink-2); margin-top: 6px; white-space: pre-line; }

#error-bar { position: fixed; bottom: 0; left: 0; right: 0; background: var(--crit); color: #fff; padding: 10px 20px; font-size: 14px; z-index: 50; }
/* the same bar carries a short success line — saving now closes the panel,
   so this is the only confirmation the user gets */
#error-bar.ok { background: var(--good); }

/* ---------- mobile bottom bar: Inputs | Results views ---------- */
#mobilebar { display: none; }

/* ---------- print report: results only, clean page ---------- */
@media print {
  header nav, .inputs, #error-bar, #acct-panel, .copybtn, #mobilebar, #hdr-result { display: none !important; }
  header { position: static; background: #fff; color: var(--ink); padding: 0 0 8px; border-bottom: 2px solid var(--ink); box-shadow: none; }
  header .sub { color: var(--ink-2); display: inline; }
  body { background: #fff; }
  .panel, .panel.mode-reserve { display: block; }
  .inputs { display: none !important; }
  .results { display: block !important; }
  .results .chart, .datatable { border: 1px solid #ccc; box-shadow: none; break-inside: avoid; page-break-inside: avoid; }
  .chartrow { display: block; }
  .chartrow .chart { margin-bottom: 8px; }
  .datatable { width: 100%; max-height: none; overflow: visible; }
  .summary .card { border: 1px solid #ccc; box-shadow: none; }
  .giipbanner .val { color: var(--good) !important; }
}

/* ---------- mobile (phones) ---------- */
@media (max-width: 640px) {
  header { padding: 8px 12px 0; gap: 8px; }
  header .sub { display: none; }
  #hdr-result { display: block; flex: 1; }
  #hdr-result.empty { display: none; }
  /* the three well tabs get a full row with real touch targets;
     utility links wrap onto a second row below them */
  .tab { flex: 1 1 30%; padding: 13px 0 11px; min-height: 44px; text-align: center; }
  /* utility links size to their own text (no clipped labels) and wrap into
     rows; the cap + ellipsis only guards long signed-in account names */
  .hdr-link {
    flex: 1 1 auto; margin-left: 0; min-width: 0; max-width: 48%;
    min-height: 40px; padding: 8px 9px; letter-spacing: 0.5px;
    display: inline-flex; align-items: center; justify-content: center;
    text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  main { padding: 8px 8px 76px; }
  .panel { gap: 10px; }
  /* reserve mode's half-page split is a desktop layout — full width on phones */
  .panel.mode-reserve { grid-template-columns: 1fr; }

  /* one-column input array, finger-sized boxes; 16px font prevents the
     iOS focus auto-zoom */
  .rows { columns: 1; }
  .frow { grid-template-columns: minmax(0, 1fr) 112px; margin-bottom: 4px; }
  .frow input, .presrow input { font-size: 16px; padding: 6px 8px; }
  .frow select { font-size: 16px; padding: 6px 4px; }
  .frow label { font-size: 11px; }
  .presrow { flex-wrap: wrap; }
  .presrow input { width: 31%; }
  /* NOT overflow-x: auto. An auto overflow-x forces overflow-y to auto too,
     which made every card a scroll container: the sticky Run button then
     pinned to the CARD's bottom edge instead of the viewport's, and floated
     over the prod_data rows while the card scrolled its caption and buttons
     sideways along with the table. Every grid table now scrolls inside its
     own .gridscroll box, so the card itself only needs to clip. Measured on
     a 375px phone, 25 Sep 2026. */
  fieldset, .group { overflow-x: clip; }

  /* dense grid tables (reserve prod data, static surveys, multi-rate tests,
     layers): compact cells with sensible column widths — the table scrolls
     sideways inside its card instead of bloating */
  .sens { width: auto; min-width: 100%; }
  .sens th { font-size: 9px; letter-spacing: 0.2px; padding: 2px 3px; white-space: nowrap; }
  .sens td { padding: 1px 2px; }
  .sens input { font-size: 13px; padding: 5px 4px; min-width: 56px; min-height: 32px; }
  .sens select { font-size: 13px; padding: 5px 3px; min-height: 32px; }
  .sens td:first-child input { min-width: 92px; }
  #gas-prod-table td:first-child input, #oil-prod-table td:first-child input,
  #gas-sithp-table td:first-child input, #oil-static-table td:first-child input { min-width: 96px; text-align: left; }

  /* selection radios: finger-sized targets */
  .radio { min-height: 40px; padding: 2px 0; margin-right: 12px; font-size: 14px; }
  .radio input { width: 19px; height: 19px; }
  .copybtn { min-height: 38px; padding: 8px 12px; font-size: 11px; }
  .tbl-actions { gap: 8px; }

  /* Account panel: full-width sheet under the header. It was position:fixed
     with top:auto, which resolves to the static position — measured at
     top:-16px on a 375px phone, so the panel drew ABOVE the viewport and its
     title row was cut off. Absolute + top:100% anchors it under the sticky
     header exactly as on desktop (header overflow is visible, so nothing
     clips) and leaves the Sign-in toggle reachable. Fixed 31 Aug 2026. */
  #acct-panel { position: absolute; top: 100%; left: 8px; right: 8px; width: auto; }
  /* case rows are taller here (38px touch targets), so the desktop 64px
     showed one row plus a clipped one; 90px is exactly two rows */
  #acct-cases { max-height: 90px; }

  /* charts stack above their data tables, tables full width */
  .chartrow { flex-direction: column; }
  .datatable { width: 100%; max-height: 250px; }
  .datatable table { font-size: 12px; }

  .summary { gap: 6px; }
  .summary .card { flex: 1 1 44%; min-width: 0; padding: 6px 10px; }
  .summary .card .v { font-size: 15px; }

  /* Inputs | Results bottom bar (The PWF pattern) */
  #mobilebar {
    display: flex; position: fixed; bottom: 0; left: 0; right: 0; z-index: 45;
    background: var(--surface); border-top: 1px solid var(--line);
    box-shadow: 0 -4px 16px -8px rgba(11, 20, 24, .4);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  #mobilebar button {
    flex: 1; background: none; border: 0; border-top: 2px solid transparent;
    padding: 14px 0 12px; min-height: 50px; cursor: pointer;
    font: 600 11px/1 var(--sans); text-transform: uppercase; letter-spacing: 1.2px; color: var(--ink-3);
  }
  #mobilebar button.active { color: var(--accent); border-top-color: var(--accent); }
  /* view switching: one of the two halves shows at a time */
  body.view-results .panel .inputs { display: none; }
  body.view-inputs .panel .results { display: none; }

  /* the main call-to-action stays reachable while scrolling the inputs,
     above the bottom bar and iPhone home indicators */
  .action { position: sticky; bottom: calc(60px + env(safe-area-inset-bottom, 0px)); z-index: 10; box-shadow: 0 4px 14px rgba(11, 20, 24, 0.3); }
  .action.secondary { position: static; box-shadow: none; }
  #error-bar { bottom: calc(50px + env(safe-area-inset-bottom, 0px)); }
}

/* charts that have not been drawn yet render nothing, not an empty box */
.results .chart:empty { display: none; }

/* multi-layer IPR: a layer whose Pr sits below the flowing pressure takes
   fluid IN. It is the one row in that table a reader must not skim past, so
   it gets the warning tint and its own left rule rather than relying on a
   minus sign in one column. */
tbody tr.crossflow td { background: #FBE9E7; color: #7a1f14; font-weight: 600; }
tbody tr.crossflow td:first-child { box-shadow: inset 3px 0 0 var(--crit); }
