/*
 * Pontem Tools - application composition layer.
 *
 * The look this file composes is the surveillance console in
 * .design-ref/console-dark.png: a near-black navy ground, panels lifted off
 * it by a hairline blue-grey edge rather than a fill, uppercase letter-spaced
 * labels, cyan reserved for values the model produced or the operator can
 * edit, and monospace numerals everywhere a reading appears. Every colour
 * comes from a token in pontem-theme.css; nothing here hard-codes a hex.
 *
 * Structure follows the screen: chrome bar, rail, tool body, then the
 * building blocks (panel, field row, stat, chart, scrubber) and finally the
 * standalone screens (auth, splash) and the responsive rules.
 */

/* ---------------------------------------------------------------- shell -- */

.app {
  display: flex;
  flex-direction: column;
  height: 100vh;
  overflow: hidden;
  font-size: 14px;
  color: var(--color-text);
  background: var(--color-bg);
}

/* The rail and the tool pane sit side by side *below* the chrome bar, which
   spans the full width - that full-bleed bar is what makes the screen read
   as one instrument rather than a sidebar next to a page. */
.app-body {
  flex: 1;
  min-height: 0;
  display: flex;
}

/* ---------------------------------------------------------- chrome bar -- */

.topbar {
  position: relative;
  flex: none;
  display: flex;
  align-items: stretch;
  gap: 22px;
  height: 68px;
  padding: 0 22px 0 16px;
  background: var(--color-ground);
  border-bottom: 1px solid var(--color-divider);
}

.topbar-brand {
  display: flex;
  align-items: center;
  gap: 14px;
  flex: none;
}

/* The full lockup, cropped to its artwork (see the SVG's own note). It stacks
   mark over wordmark, so "ANALYTICS" is only 10.8% of the artwork height and
   lands near 5.6px at this size - small, but the lockup at a height where
   that line is comfortable makes the bar taller than this console wants. */
.topbar-logo {
  height: 52px;
  width: auto;
  display: block;
}

.topbar-heading {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-width: 0;
  text-align: center;
}

.tool-title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 27px;
  line-height: 1.05;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.kicker {
  font: 500 10.5px var(--font-body);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent-2-600);
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  margin-left: auto;
}

.topbar-actions-label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text);
}

/* ----------------------------------------------------------------- rail -- */

.rail {
  width: 268px;
  flex: none;
  background: var(--color-ground);
  border-right: 1px solid var(--color-divider);
  display: flex;
  flex-direction: column;
  padding: 0 0 14px;
  overflow-x: hidden;
  overflow-y: auto;
  transition: width 0.2s ease;
}

/* Collapsed state: an icon-only strip rather than fully hiding the rail, so
   the tool list and its own toggle stay reachable at every width. */
.rail:not(.is-open) {
  width: 64px;
}

.rail-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 18px 12px;
}

.rail:not(.is-open) .rail-head {
  justify-content: center;
  padding: 16px 10px 12px;
}

.rail-label {
  font: 500 10px var(--font-body);
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--color-accent-2-600);
}

.rail-head .rail-label {
  margin-right: auto;
}

.rail-head:not(.rail-head-recent) .rail-label {
  font-size: 13px;
  font-weight: 700;
}

.rail:not(.is-open) .rail-label {
  display: none;
}

.rail-nav {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 12px;
}

.rail:not(.is-open) .rail-nav {
  padding: 0 10px;
}

.rail-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: var(--radius-lg);
  border: 1px solid transparent;
  color: var(--color-accent-2-700);
  text-decoration: none;
  font-size: 13.5px;
}

.rail:not(.is-open) .rail-item {
  justify-content: center;
  padding: 9px 0;
}

.rail-item:hover {
  color: var(--color-text);
  background: var(--color-surface);
  border-color: var(--color-divider);
}

.rail-item[aria-current='page'] {
  color: var(--color-text);
  background: var(--color-accent-100);
  border-color: var(--color-accent-300);
  font-weight: 500;
}

/* Icons go bright cyan only on the active row. */
.rail-item[aria-current='page']>svg {
  color: var(--color-accent-bright);
}

.rail-item>svg {
  flex: none;
}

.rail-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rail:not(.is-open) .rail-name {
  display: none;
}

/* Every tool but Umbilical Flushing is greyed out and inert while this pass
   focuses on that one screen. */
.rail-item.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}

.rail-runs {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 18px;
}

.rail-run {
  padding: 5px 0;
  font: 400 12px var(--font-mono);
  color: var(--color-accent-2-600);
}

.rail-run.is-old {
  color: var(--color-accent-2-500);
}

.rail:not(.is-open) .rail-runs,
.rail:not(.is-open) .rail-head-recent {
  display: none;
}

/* Pinned to the bottom of the rail regardless of how much tool/run content
   sits above it, via the rail's own flex-column layout. */
.rail-footer {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: auto;
  padding: 14px 18px 0;
  border-top: 1px solid var(--color-divider);
}

.rail-footer-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 500 12.5px var(--font-body);
  color: var(--color-accent-2-600);
  margin-right: auto;
}

.rail:not(.is-open) .rail-footer {
  justify-content: center;
  padding: 14px 10px 0;
}

.rail:not(.is-open) .rail-footer-name {
  display: none;
}

/* --------------------------------------------------------- status atoms -- */

/* The live/converged/at-risk pip. It is a real element rather than a ::before
   so a screen reader can be given the state in text next to it. */
.status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
  background: var(--color-accent-2-500);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent-2-500) 22%, transparent);
}

.status-dot.is-ok {
  background: var(--color-ok);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-ok) 22%, transparent);
}

.status-dot.is-warn {
  background: var(--color-warn);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-warn) 22%, transparent);
}

.status-dot.is-danger {
  background: var(--color-danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-danger) 22%, transparent);
}

.status-dot.is-live {
  animation: pip 2.4s ease-in-out infinite;
}

@keyframes pip {

  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: 0.35;
  }
}

@media (prefers-reduced-motion: reduce) {
  .status-dot.is-live {
    animation: none;
  }
}

/* ------------------------------------------------------------ tool main -- */

.tool-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
}

.tool-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 404px 1fr;
  gap: 20px;
  padding: 20px 22px;
}

.tool-col {
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  overflow-y: auto;
  padding-right: 4px;
}

/* Screens whose panels read top-to-bottom rather than as an inputs/outputs
   pair (Admin), so a wide table gets the full width instead of 1fr of a
   two-column grid. */
.tool-body-stacked {
  grid-template-columns: 1fr;
}

/* A column with a pinned footer (e.g. Calculate) scrolls only its panels -
   the footer itself stays put below the scroll area. */
.tool-col-pinned {
  overflow: hidden;
  padding-right: 0;
}

.tool-col-scroll {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
  overflow-y: auto;
  padding-right: 4px;
}

.tool-col-footer {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 14px;
  margin-top: 4px;
  border-top: 1px solid var(--color-divider);
}

/* ------------------------------------------------------------ run strip -- */

/* Shown in place of the Calculate button while a solve is in flight.

   It replaces the button rather than disabling it: a dead primary button
   sitting next to a live secondary one inverts the affordance, leaving the
   only clickable control looking like the quiet one. A readout with a single
   action reads correctly, and it stops the uppercase primary from rendering
   the elapsed unit as "0S". */
.run-strip {
  position: relative;
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 9px 9px 14px;
  border: 1px solid var(--color-divider);
  border-radius: 8px;
  background: var(--color-inset);
  overflow: hidden;
}

.run-strip-label {
  font: 600 11.5px var(--font-body);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent-700);
}

/* Elapsed time is a reading, so it gets the console's numeral treatment -
   and tabular figures so the strip doesn't twitch as the digits change. */
.run-strip-elapsed {
  margin-left: auto;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-accent-2-700);
}

.run-strip .btn {
  flex: none;
  padding: 6px 14px;
  font-size: 12.5px;
}

/* Indeterminate sweep along the bottom edge: the solver gives us no progress
   to report, so this says "still alive" without implying a percentage. */
.run-strip-progress {
  position: absolute;
  inset: auto 0 0 0;
  height: 2px;
  background-image: linear-gradient(
    90deg,
    transparent,
    var(--color-accent-700),
    transparent
  );
  background-size: 40% 100%;
  background-repeat: no-repeat;
  animation: run-strip-sweep 1.6s ease-in-out infinite;
}

@keyframes run-strip-sweep {
  from {
    background-position: -45% 0;
  }
  to {
    background-position: 145% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .run-strip-progress {
    animation: none;
    background-position: 0 0;
    background-size: 100% 100%;
    opacity: 0.4;
  }
}

/* Themed scrollbar for the app's internal scroll panes, replacing the
   browser default so it reads as part of the instrument rather than the OS. */
.tool-col,
.tool-col-scroll,
.rail {
  scrollbar-width: thin;
  scrollbar-color: var(--color-accent-2-400) transparent;
}

.tool-col::-webkit-scrollbar,
.tool-col-scroll::-webkit-scrollbar,
.rail::-webkit-scrollbar {
  width: 8px;
}

.tool-col::-webkit-scrollbar-track,
.tool-col-scroll::-webkit-scrollbar-track,
.rail::-webkit-scrollbar-track {
  background: transparent;
}

.tool-col::-webkit-scrollbar-thumb,
.tool-col-scroll::-webkit-scrollbar-thumb,
.rail::-webkit-scrollbar-thumb {
  background-color: var(--color-accent-2-300);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: content-box;
}

.tool-col:hover::-webkit-scrollbar-thumb,
.tool-col-scroll:hover::-webkit-scrollbar-thumb,
.rail:hover::-webkit-scrollbar-thumb {
  background-color: var(--color-accent-2-400);
}

/* --------------------------------------------------------------- panels -- */

.panel {
  padding: 14px 16px 16px;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg);
}

/* The whole header toggles the panel (see .panel-head-toggle); the
   hover/focus fill is what tells a user the whole row - not just the chevron
   - is what they click. */
.panel-head {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--color-divider);
  margin: -6px -8px 13px;
  padding: 6px 8px 10px;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  border-radius: var(--radius-sm);
}

.panel-head:hover {
  background: color-mix(in srgb, var(--color-accent-700) 7%, transparent);
}

.panel-head:hover .panel-title {
  color: var(--color-accent-700);
}

.panel-head:hover .panel-toggle {
  color: var(--color-accent-700);
}

.panel-head:has(.panel-head-toggle:focus-visible) {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

/* The disclosure button is the title text, stretched over the whole header by
   its ::after - so the info tip beside it can be a separate button (raised
   above the overlay) rather than one nested inside another. */
.panel-head-toggle {
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.panel-head-toggle:focus-visible {
  outline: none;
}

.panel-head-toggle::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.panel-head .info-tip {
  position: relative;
  z-index: 1;
}

/* Collapsed panels shed the body, so the header rule and gap go with it. */
.panel-head.is-collapsed {
  border-bottom: 0;
  margin-bottom: -8px;
  padding-bottom: 6px;
}

.panel-toggle {
  color: var(--color-accent-2-500);
  flex: none;
  transition: transform 0.15s ease, color 0.15s ease;
}

.panel-toggle.is-collapsed {
  transform: rotate(-90deg);
}

.panel-title {
  margin: 0;
  margin-right: auto;
  min-width: 0;
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text);
}

.panel-meta {
  flex: 0 1 auto;
  font: 400 11px var(--font-mono);
  line-height: 1.35;
  color: var(--color-accent-2-600);
  text-align: right;
}

.info-tip {
  display: inline-flex;
  vertical-align: middle;
  margin-left: 6px;
  /* A <button> now; shed the UA button chrome so it stays a bare glyph. */
  border: 0;
  padding: 0;
  background: none;
  color: var(--color-accent-2-500);
  cursor: help;
}

.info-tip:hover,
.info-tip:focus-visible {
  color: var(--color-accent-700);
}

.info-tip:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: 999px;
}

.info-tip-content.info-tip-content {
  max-width: 280px;
  white-space: normal;
  text-align: left;
  line-height: 1.45;
  background: var(--color-ground);
  border: 1px solid var(--color-accent-300);
  color: var(--color-text);
}

.panel-rows {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* ------------------------------------------------------------ field row -- */

.field-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.field-row>.field-label {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  font: 400 11.5px var(--font-body);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-accent-2-700);
}

.field-row>.input {
  width: 118px;
  flex: none;
}

/* A row with no unit column: the control takes the column's width (52px
   plus the 10px gap) on its right, so its left edge still lines up with the
   rows around it. */
.field-row.is-unitless>.input {
  width: calc(118px + 62px);
}

.field-row>.unit {
  width: 52px;
  flex: none;
  font: 400 10.5px var(--font-mono);
  letter-spacing: 0.04em;
  color: var(--color-accent-2-500);
}

/* ----------------------------------------------------------------- tabs -- */

.tabs {
  display: flex;
  align-items: center;
  gap: 24px;
  border-bottom: 1px solid var(--color-divider);
  flex: none;
}

.tab {
  padding: 0 2px 9px;
  font: 600 13px var(--font-heading);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent-2-600);
  background: none;
  border: 0;
  cursor: pointer;
  margin-bottom: -1px;
  border-bottom: 2px solid transparent;
}

.tab:hover {
  color: var(--color-text);
}

.tab[aria-selected='true'] {
  color: var(--color-accent-700);
  border-bottom-color: var(--color-accent-700);
}

.tab-tools {
  margin-left: auto;
  display: flex;
  gap: 6px;
  padding-bottom: 6px;
  color: var(--color-accent-2-600);
}

.tab-tools button {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: inherit;
}

.tab-tools button:hover {
  color: var(--color-accent-700);
}

/* ---------------------------------------------------------------- chart -- */

.chart-panel {
  flex: 1;
  min-height: 0;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg);
  padding: 14px 18px 10px;
  display: flex;
  flex-direction: column;
}

.chart-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  row-gap: 8px;
  gap: 12px;
  margin-bottom: 8px;
}

.chart-title {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text);
}

.chart-sub {
  font: 400 11.5px var(--font-mono);
  color: var(--color-accent-2-600);
}

/* The "Pipe Volume: ... gal" line - its own row below the title, matching
   the reference tool's layout instead of crowding it onto the title row. */
.chart-pipe-volume {
  font: 400 11.5px var(--font-mono);
  color: var(--color-accent-2-600);
  margin: -2px 0 8px;
}

.chart-head-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 2px;
  margin-left: auto;
  flex: none;
  justify-content: flex-end;
}

.chart-toolbar {
  display: flex;
  align-items: center;
  gap: 2px;
}

.btn-icon.chart-tool-btn {
  width: 28px;
  height: 28px;
  color: var(--color-accent-2-500);
}

.chart-tool-btn:hover {
  color: var(--color-accent-700);
}

.chart-tool-btn[aria-pressed='true'] {
  color: var(--color-accent-700);
  background: color-mix(in srgb, var(--color-accent-700) 16%, transparent);
}

/* --------------------------------------------------------- chart zoom -- */

.chart-canvas-wrap {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
}

.chart-interaction-layer {
  /* Geometry is set inline from the measured plot rect, so the layer stops
     short of the x axis and the Trends brush strip and leaves their pointer
     events alone. */
  position: absolute;
  z-index: 5;
  touch-action: none;
  user-select: none;
}

.chart-tooltip-content.chart-tooltip-content {
  background: var(--color-ground);
  border: 1px solid var(--color-accent-300);
  color: var(--color-text);
  font: 500 11.5px var(--font-body);
}

/* --------------------------------------------------------------- toast -- */

.app-toast.app-toast {
  box-shadow: var(--shadow-lg);
  font-family: var(--font-body);
  font-size: 13px;
}

.app-toast [data-title] {
  font-weight: 600;
  letter-spacing: 0.01em;
}

.app-toast [data-description] {
  color: var(--color-accent-2-700);
}

.chart-svg {
  width: 100%;
  flex: 1;
  min-height: 220px;
}

.chart-canvas {
  flex: 1;
  min-height: 0;
}

.legend {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding-top: 10px;
  border-top: 1px solid var(--color-divider);
  margin-top: 8px;
  font-size: 12px;
  color: var(--color-accent-2-700);
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.legend-swatch {
  width: 20px;
  height: 2.5px;
  flex: none;
  border-radius: 2px;
}

/* ------------------------------------------------------------ stat tile -- */

.stat-grid {
  display: grid;
  gap: 12px;
}

.stat {
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.stat-head {
  display: flex;
  align-items: center;
  gap: 9px;
}

.stat-badge {
  width: 26px;
  height: 22px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm);
  background: var(--color-accent-2-200);
  color: var(--color-accent-2-700);
  font: 600 10px var(--font-mono);
}

.stat-label {
  font: 500 10px var(--font-body);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent-2-700);
}

.stat-value {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 26px;
  line-height: 1.15;
  letter-spacing: -0.01em;
  /* Readings use a space as the thousands separator; a monospace space at
     this size opens a gap wide enough to read as two numbers, so it's pulled
     back to roughly a thin space. */
  word-spacing: -0.3em;
  font-variant-numeric: tabular-nums;
  color: var(--color-accent-700);
}

.stat-unit {
  font: 400 11px var(--font-body);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent-2-600);
}

.stat-note {
  font: 400 11.5px var(--font-mono);
  color: var(--color-accent-2-600);
}

/* Inverted tile - the headline KPI in a row, lifted by an accent edge rather
   than a fill so it never outshines its own number. */
.stat.is-primary {
  background: var(--color-accent-100);
  border-color: var(--color-accent-300);
}

.stat.is-primary .stat-badge {
  background: var(--color-accent-300);
  color: var(--color-accent-800);
}

.stat.is-primary .stat-value {
  color: var(--color-accent-800);
}

/* Large KPI variant, for a headline reading */
.stat.is-lg {
  padding: 15px 17px;
}

.stat.is-lg .stat-value {
  font-size: 38px;
  line-height: 1.05;
}

.stat.is-lg .stat-unit {
  font-size: 13px;
}

/* --------------------------------------------------------------- notice--- */

.notice {
  padding: 12px 14px;
  background: var(--color-accent-100);
  border: 1px solid var(--color-accent-300);
  border-radius: var(--radius-md);
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.notice svg {
  flex: none;
  margin-top: 1px;
  color: var(--color-accent-700);
}

.notice-text {
  font-size: 12.5px;
  color: var(--color-accent-800);
  line-height: 1.5;
}

.notice.is-danger {
  background: color-mix(in srgb, var(--color-danger) 12%, transparent);
  border-color: var(--color-danger-dim);
}

.notice.is-danger svg {
  color: var(--color-danger);
}

.notice.is-danger .notice-text {
  color: color-mix(in srgb, var(--color-danger) 72%, var(--color-text));
}

/* Advisory rather than blocking - the run can still go ahead. */
.notice.is-warn {
  background: color-mix(in srgb, var(--color-warn) 10%, transparent);
  border-color: var(--color-warn-dim);
}

.notice.is-warn svg {
  color: var(--color-warn);
}

.notice.is-warn .notice-text {
  color: color-mix(in srgb, var(--color-warn) 55%, var(--color-text));
}

/* ------------------------------------------------------------- scrubber -- */

.scrubber {
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg);
  padding: 12px 18px 14px;
}

.scrubber-row {
  display: flex;
  align-items: center;
  gap: 14px;
}

.scrubber-track {
  flex: 1;
  position: relative;
  height: 32px;
  display: flex;
  align-items: center;
}

.scrubber-rail {
  height: 3px;
  width: 100%;
  border-radius: 999px;
  background: var(--color-accent-2-300);
}

.scrubber-fill {
  position: absolute;
  left: 0;
  height: 3px;
  border-radius: 999px;
  background: var(--color-accent-700);
}

.scrubber-handle {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-accent-700);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-accent-700) 22%, transparent);
  transform: translateX(-50%);
}

/*
 * The real range input sits over the track at opacity 0, so its own focus
 * ring is invisible. Ring the drawn handle instead when it has keyboard focus.
 */
.scrubber-track:has(input:focus-visible) .scrubber-handle {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
}

.scrubber-bubble {
  position: absolute;
  top: -6px;
  transform: translateX(-50%);
  background: var(--color-accent-300);
  color: var(--color-accent-900);
  font: 500 10.5px var(--font-mono);
  border-radius: var(--radius-sm);
  padding: 1px 7px;
  white-space: nowrap;
}

.scrubber-total {
  font: 400 11.5px var(--font-mono);
  color: var(--color-accent-2-600);
  flex: none;
}

.scrubber-ticks {
  display: flex;
  justify-content: space-between;
  font: 400 10.5px var(--font-mono);
  color: var(--color-accent-2-500);
  padding: 6px 46px 0;
}

/* ----------------------------------------------------------------- auth -- */

.auth {
  display: flex;
  height: 100vh;
  font-size: 14px;
  color: var(--color-text);
  background: var(--color-bg);
}

.auth-plate {
  width: 560px;
  flex: none;
  background: var(--color-ground);
  border-right: 1px solid var(--color-divider);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 44px 52px;
  overflow-y: auto;
}

.auth-plate-copy {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 22px;
}

/* The Analytics lockup stacks its mark above the wordmark (roughly 4:3), where
   the old mark was a 6:1 strip - so it is sized by width here. Held to a
   height it shrinks to ~60px across and the wordmark stops being readable. */
.auth-logo {
  align-self: flex-start;
  width: 132px;
  height: auto;
}

.auth-plate h2 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 44px;
  line-height: 1.06;
  letter-spacing: 0.01em;
  color: var(--color-text);
  max-width: 15ch;
}

.auth-plate p {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-accent-2-700);
  max-width: 44ch;
}

.auth-plate-foot {
  font: 400 11px var(--font-mono);
  color: var(--color-accent-2-500);
  letter-spacing: 0.08em;
}

/* The bridge photograph - the structure the company is named for - sits on
   this side, behind the form rather than behind the pitch. The form card is a
   solid surface, so it reads as a lit panel floating on the structure and the
   photo never has to carry type. This is the wider half, so `center` keeps the
   pylon and the point where the cables converge both in frame; the scrim is
   even, since nothing is written directly on it. */
.auth-form-wrap {
  flex: 1;
  min-width: 0;
  display: grid;
  place-items: center;
  padding: 44px;
  overflow-y: auto;
  background-color: var(--color-bg);
  background-image: linear-gradient(180deg,
      color-mix(in srgb, var(--color-bg) 62%, transparent) 0%,
      color-mix(in srgb, var(--color-bg) 70%, transparent) 100%),
    url('/brand/auth-background.jpg');
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
}

.auth-form {
  padding: 30px 32px;
  display: flex;
  flex-direction: column;
  gap: 18px;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}

.auth-eyebrow {
  font: 500 10px var(--font-body);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent-2-600);
}

.auth-form h3 {
  margin: 3px 0 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 28px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.auth-or {
  display: flex;
  align-items: center;
  gap: 12px;
  font: 400 10px var(--font-body);
  letter-spacing: 0.18em;
  color: var(--color-accent-2-600);
}

.auth-or::before,
.auth-or::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--color-divider);
}

.auth-alt {
  font-size: 13px;
  color: var(--color-accent-2-600);
}

.auth-alt a {
  color: var(--color-accent-700);
}

/* Inline actions in the sub-text under the form ("Send again", "Use a
   different email") - real buttons, styled to read as links. */
.auth-link-btn {
  font: inherit;
  color: var(--color-accent-700);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.auth-link-btn:hover,
.auth-link-btn:focus-visible {
  color: var(--color-accent-900);
}

/* The six-digit sign-in code: monospace and widely tracked, so it reads as a
   transcribed reading like every other numeral in the console. */
.auth-form .input-otp {
  font: 600 22px var(--font-mono);
  letter-spacing: 0.42em;
  text-align: center;
  padding-block: 12px;
  /* letter-spacing pads the right of the last glyph; nudge back to centre. */
  text-indent: 0.42em;
}

.auth-meter {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 8px;
}

.auth-meter span {
  flex: 1;
  height: 3px;
  border-radius: 999px;
  background: var(--color-accent-2-300);
}

.auth-meter span.is-on {
  background: var(--color-accent-700);
}

.auth-meter .auth-meter-label {
  flex: none;
  font: 400 11px var(--font-mono);
  color: var(--color-accent-700);
  background: none;
  height: auto;
}

.auth-error {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--color-danger);
  background: color-mix(in srgb, var(--color-danger) 12%, transparent);
  border: 1px solid var(--color-danger-dim);
  border-radius: var(--radius-md);
  padding: 9px 12px;
}

/* The primary action is cyan-on-ground: the one filled object on the screen. */
.btn-pontem {
  background: var(--color-accent-700);
  border-color: var(--color-accent-700);
  color: var(--color-ground);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.btn-pontem:hover {
  background: var(--color-accent-800);
  border-color: var(--color-accent-800);
}

.btn-pontem:active {
  background: var(--color-accent-600);
  border-color: var(--color-accent-600);
}

/* --------------------------------------------------------------- splash -- */

.splash {
  height: 100vh;
  background: var(--color-ground);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 36px;
  position: relative;
  color: var(--color-text);
}

/* Sized by width for the same reason as `.auth-logo` - the lockup stacks, so
   a height constraint starves the wordmark. This screen is otherwise empty,
   so it can afford the lockup at a size where "ANALYTICS" still reads. */
.splash-logo {
  z-index: 1;
  width: 240px;
  height: auto;
}

.splash-progress {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  z-index: 1;
  width: min(420px, 84vw);
}

.splash-label {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--color-accent-700);
}

.splash-bar {
  width: 100%;
  height: 3px;
  border-radius: 999px;
  background: var(--color-accent-2-300);
  position: relative;
  overflow: hidden;
}

.splash-bar span {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 999px;
  background: var(--color-accent-700);
  transition: width 0.3s linear;
}

.splash-meta {
  display: flex;
  justify-content: center;
  width: 100%;
  font: 400 12px var(--font-mono);
  color: var(--color-accent-2-600);
}

.splash-steps {
  display: flex;
  flex-direction: column;
  gap: 7px;
  z-index: 1;
  font-size: 12.5px;
  color: var(--color-accent-2-700);
  width: 420px;
}

.splash-step {
  display: flex;
  align-items: center;
  gap: 9px;
}

.splash-step.is-pending {
  color: var(--color-accent-2-500);
}

.splash-step svg {
  flex: none;
}

.splash-step.is-done svg {
  color: var(--color-ok);
}

.splash-foot {
  position: absolute;
  bottom: 68px;
  font: 400 11px var(--font-mono);
  letter-spacing: 0.16em;
  color: var(--color-accent-2-500);
}

/* ------------------------------------------------------------ empty tool -- */

.tool-empty {
  flex: 1;
  min-height: 0;
  display: grid;
  place-items: center;
  padding: 40px;
  text-align: center;
}

.tool-empty-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  max-width: 46ch;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg);
}

.tool-empty h3 {
  margin: 0;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.tool-empty p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--color-accent-2-600);
}

/* ------------------------------------------------------------- variants -- */

/* 12px segmented control, the in-panel size used throughout the app. */
.seg-sm .seg-opt {
  font-size: 11.5px;
  padding: 6px 11px;
}

/* Industry declares .seg as inline-flex, but a flex column stretches it to the
   full panel width. An explicit intrinsic width beats align-items: stretch. */
.seg {
  width: fit-content;
}

/* Pontem tag tones. Industry's own .tag-accent pair uses the 100/800 steps;
   the design reaches for 200/800 for "teal" and an inverted navy chip for
   selected + protected states, so those are declared here rather than
   overriding the design system's classes. */
.tag-teal {
  background: var(--color-accent-200);
  color: var(--color-accent-800);
}

.tag-slate {
  background: var(--color-accent-2-100);
  color: var(--color-accent-2-800);
}

.tag-navy {
  background: var(--color-accent-900);
  color: var(--color-accent-400);
}

/* Rare API-failure state - reuses the same danger palette as .notice. */
.tag-danger {
  background: color-mix(in srgb, var(--color-danger) 18%, transparent);
  color: var(--color-danger);
}

/* A run that completed successfully - the same green as the status pip. */
.tag-ok {
  background: color-mix(in srgb, var(--color-ok) 18%, transparent);
  color: var(--color-ok);
}

/* Marginal / watch-it state - the amber counterpart to tag-ok / tag-danger. */
.tag-warn {
  background: color-mix(in srgb, var(--color-warn) 18%, transparent);
  color: var(--color-warn);
}

/* On the navy auth plate, where both other tones would disappear. */
.tag-plate {
  background: color-mix(in srgb, var(--color-accent) 22%, transparent);
  color: var(--color-bg);
}

/* Selectable chips (brine salts, requested tools) - a tag that is a button. */
.tag-btn {
  border: 0;
  cursor: pointer;
  font-family: inherit;
}

.tag-btn:hover {
  filter: brightness(1.25);
}

/* Any run of digits the model produced or the operator typed. */
.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* -------------------------------------------------- console chrome -------- */

/*
 * Industry frames every card, button, input and segmented control as a
 * square, hairline-bordered wireframe object (industry.css, "blueprint
 * frame"). The console keeps the hairline - on a dark ground an edge is the
 * only thing separating one plane from the next - but rounds the corners and
 * sinks the interactive controls below their panel instead of lifting them
 * above it. Everything below is that adjustment, in one place, so no screen
 * has to restate it.
 */
.card,
.dialog,
.notice {
  border-radius: var(--radius-lg);
}

.btn,
.input,
.seg {
  border-radius: var(--radius-md);
}

.tag {
  border-radius: 999px;
}

.card,
.dialog {
  background: var(--color-surface);
  border-color: var(--color-divider);
}

/* An input is a well cut into its panel: darker than the panel, edged in the
   accent, and carrying its value in cyan monospace. That pairing - cyan box,
   cyan number - is the console's signal for "this is yours to change". */
.input {
  background: var(--color-inset);
  border-color: var(--color-accent-400);
  color: var(--color-accent-800);
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  min-height: 32px;
  padding: 5px 10px;
}

.input::placeholder {
  color: var(--color-accent-2-500);
}

.input:hover {
  border-color: var(--color-accent-500);
}

.input:focus-visible {
  border-color: var(--color-accent-700);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent-700) 18%, transparent);
}

.btn {
  border-color: var(--color-divider);
  font-family: var(--font-body);
  font-weight: 500;
  letter-spacing: 0.06em;
}

.btn-secondary {
  background: var(--color-surface);
  color: var(--color-text);
}

.btn-secondary:hover {
  background: var(--color-accent-2-200);
  border-color: var(--color-accent-2-400);
}

.btn-secondary:active {
  background: var(--color-accent-2-300);
}

.btn-ghost {
  border-color: transparent;
  color: var(--color-accent-2-700);
}

.btn-ghost:hover {
  color: var(--color-accent-700);
  background: color-mix(in srgb, var(--color-accent-700) 10%, transparent);
}

.btn-primary {
  background: var(--color-accent-700);
  border-color: var(--color-accent-700);
  color: var(--color-ground);
}

.btn-primary:hover {
  background: var(--color-accent-800);
  border-color: var(--color-accent-800);
}

.btn-primary:active {
  background: var(--color-accent-600);
  border-color: var(--color-accent-600);
}

.seg {
  background: var(--color-inset);
  border-color: var(--color-divider);
  overflow: hidden;
}

.seg-opt {
  color: var(--color-accent-2-700);
}

.seg-opt+.seg-opt {
  border-left-color: var(--color-divider);
}

.seg-opt:has(input:checked) {
  background: var(--color-accent-300);
  color: var(--color-accent-900);
}

.seg-opt:not(:has(input:checked)):hover {
  background: color-mix(in srgb, var(--color-accent-700) 10%, transparent);
}

/* Industry's radio dot punches its centre out with --color-bg; on the console
   the control sits on a panel, so the punch-out has to match that instead. */
.radio .dot {
  border-color: var(--color-accent-2-400);
}

.radio input:checked+.dot {
  border-color: var(--color-accent-700);
  background: var(--color-accent-700);
  box-shadow: inset 0 0 0 4px var(--color-surface);
}

.field>label {
  font: 400 10.5px var(--font-body);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent-2-600);
}

/* A password field with a reveal toggle docked inside its own input, rather
   than beside it - the same well, with a button at its right edge. */
.input-affix {
  position: relative;
  display: flex;
}

.input-affix .input {
  flex: 1;
  padding-right: 34px;
}

.input-affix-btn {
  position: absolute;
  top: 50%;
  right: 4px;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-accent-2-500);
  cursor: pointer;
}

.input-affix-btn:hover,
.input-affix-btn:focus-visible {
  color: var(--color-accent-700);
}

.input-affix-btn:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

/* Industry's backdrop mixes from --color-neutral-900, which is now the
   *brightest* neutral - it would wash the screen out instead of dimming it. */
.dialog-backdrop {
  background: color-mix(in srgb, #000 68%, transparent);
}

/* ---------------------------------------------------------- responsive -- */

.auth-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

/* The rail is collapsible everywhere via its own header toggle, always as an
   icon-only strip rather than a hidden drawer, so it never blocks reaching
   the control that reopens it. */

/* Tool shell: below this width the two-column body would get too cramped
   to use, so it stacks into one scrolling column. */
@media (max-width: 1180px) {
  .tool-body {
    grid-template-columns: 360px 1fr;
  }
}

@media (max-width: 980px) {
  .topbar {
    height: auto;
    padding: 10px 16px;
    flex-wrap: wrap;
    gap: 14px;
  }

  /* This bar grows to its content on a phone, so a 72px lockup would spend
     most of a short screen's header on the logo. */
  .topbar-logo {
    height: 52px;
  }

  .topbar-heading {
    position: static;
    transform: none;
    align-items: flex-start;
    text-align: left;
    margin-right: auto;
  }

  .tool-title {
    font-size: 21px;
    letter-spacing: 0.12em;
  }

  .tool-body {
    grid-template-columns: 1fr;
    padding: 16px 14px;
  }
}

/* Below this, even a single stacked column reads better as one scrolling
   page than two internally-scrolling panes. */
@media (max-width: 640px) {
  .app {
    height: auto;
    min-height: 100vh;
    overflow: visible;
  }

  .app-body {
    display: block;
  }

  .tool-main {
    overflow: visible;
  }

  .tool-body {
    overflow: visible;
  }

  .tool-col,
  .tool-col-scroll {
    overflow: visible;
  }

  .tool-col-pinned {
    overflow: visible;
  }

  /* The rail turns on its side. Stacked above the content as a 64px-wide
     block it became a ~330px tall column of icons before the page even
     started - all of a phone's first screen spent on navigation. As a strip
     it costs one row, scrolls sideways if the tools outgrow it, and keeps
     every destination one tap away. */
  .rail,
  .rail:not(.is-open) {
    width: 100%;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-right: 0;
    border-bottom: 1px solid var(--color-divider);
    overflow-x: auto;
    overflow-y: hidden;
  }

  /* The collapse toggle and the "Calculations" caption are both meaningless
     on a strip that is already icon-only and can't collapse further. */
  .rail-head {
    display: none;
  }

  .rail-nav,
  .rail:not(.is-open) .rail-nav {
    flex-direction: row;
    padding: 0;
  }

  .rail-item {
    padding: 8px 10px;
  }

  /* The rail's own name labels stay hidden here as they are when collapsed -
     each item keeps its `title` and icon. */
  .rail-name {
    display: none;
  }

  .rail-footer,
  .rail:not(.is-open) .rail-footer {
    margin-top: 0;
    margin-left: auto;
    padding: 0 0 0 10px;
    border-top: 0;
    border-left: 1px solid var(--color-divider);
  }

  .auth {
    flex-direction: column;
    height: auto;
    min-height: 100vh;
    overflow-y: auto;
  }

  .auth-plate {
    width: 100%;
    padding: 28px 22px;
  }

  .auth-plate h2 {
    font-size: 30px;
  }

  .auth-form-wrap {
    padding: 28px 22px;
  }

  .auth-grid-2 {
    grid-template-columns: 1fr;
  }

  .splash-logo {
    width: 168px;
  }

  .splash-steps {
    width: min(420px, 84vw);
  }
}

/* ------------------------------------------------- hydrate curves --------- */

/*
 * Controls that only the Hydrate Curves screen needs: a select that reads as
 * one of the console's sunk input wells, the composition table, the
 * inhibitor/salinity rows, and the plotted-trace list beside the chart.
 */

.select-input {
  appearance: none;
  width: 118px;
  /* Room for the chevron drawn in the background, so a long option name
     doesn't run underneath it. */
  padding-right: 26px;
  background-image: linear-gradient(45deg, transparent 50%, var(--color-accent-700) 50%),
    linear-gradient(135deg, var(--color-accent-700) 50%, transparent 50%);
  background-position: calc(100% - 14px) calc(50% + 1px), calc(100% - 9px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

.select-input option {
  background: var(--color-surface);
  color: var(--color-text);
}

.field-row > .select-input.is-wide {
  width: 176px;
}

.field-row.is-unitless > .select-input {
  width: calc(118px + 62px);
}

.field-row.is-unitless > .select-input.is-wide {
  width: calc(176px + 62px);
}

/* Composition: eleven components is too many for a field row each, so they
   go in a two-column table of name / mole % - the reference tool's layout. */
.composition-grid {
  display: grid;
  grid-template-columns: 1fr 88px;
  gap: 6px 10px;
  align-items: center;
}

.composition-grid > .composition-head {
  font: 400 10.5px var(--font-body);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-accent-2-500);
  padding-bottom: 2px;
}

.composition-grid > label {
  font: 400 12px var(--font-body);
  color: var(--color-accent-2-700);
}

.composition-grid > .input {
  width: 100%;
}

.composition-total {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--color-divider);
  font: 400 11.5px var(--font-body);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-accent-2-700);
}

.composition-total > span:last-child {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  color: var(--color-accent-800);
}

.check-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font: 400 12.5px var(--font-body);
  color: var(--color-accent-2-700);
  cursor: pointer;
}

.check-row input {
  accent-color: var(--color-accent-700);
  width: 15px;
  height: 15px;
  cursor: pointer;
}

.salt-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.salt-row > .select-input {
  flex: 1;
  width: auto;
}

.salt-row > .input:not(.select-input) {
  width: 72px;
}

/* The plotted curves, as a grid of cells under the chart. Each is removable
   on its own - the point of the screen is stacking curves up to compare
   them, so the list is a working control rather than a legend. Rows are a
   fixed height so the list can stop at three of them and scroll after that:
   however many curves are plotted, the chart keeps its height. */
.trace-list {
  --trace-row: 30px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  grid-auto-rows: var(--trace-row);
  gap: 6px;
  margin-top: 12px;
  max-height: calc(3 * var(--trace-row) + 2 * 6px);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--color-divider) transparent;
}

.trace-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 0 4px 0 9px;
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-md);
  background: var(--color-inset);
}

.trace-chip:hover,
.trace-chip:focus-within {
  border-color: var(--color-accent-300);
}

.trace-chip-swatch {
  flex: none;
}

.trace-chip-name {
  flex: 1 1 auto;
  min-width: 0;
  font: 400 12.5px var(--font-body);
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The chip's name while it is being renamed - sized to the label it replaces. */
.trace-chip-input {
  flex: 1 1 auto;
  min-width: 0;
  height: 22px;
  padding: 0 6px;
  font: 400 12.5px var(--font-body);
}

.trace-chip-remove {
  flex: none;
  border: 0;
  background: none;
  color: var(--color-accent-2-600);
  cursor: pointer;
  line-height: 1;
  padding: 2px 4px;
  border-radius: var(--radius-sm);
}

.trace-chip-remove:hover {
  color: var(--color-danger);
  background: var(--color-surface);
}

/* Rename and remove stay out of the way until the cell is pointed at or
   tabbed into - but only where there is a pointer that can hover; on touch
   they are always shown. Hidden by opacity, not display, so Tab still
   reaches them. */
@media (hover: hover) {
  .trace-chip .trace-chip-remove {
    opacity: 0;
  }

  .trace-chip:hover .trace-chip-remove,
  .trace-chip:focus-within .trace-chip-remove {
    opacity: 1;
  }
}

/* Same small icon button, but renaming isn't destructive - no danger red. */
.trace-chip-rename {
  display: inline-flex;
}

.trace-chip-rename:hover {
  color: var(--color-accent-700);
}

/* "Clear plot", in the chart header beside the zoom and export tools. */
.btn.chart-clear-btn {
  height: 28px;
  padding: 0 8px;
  margin-right: 6px;
  font-size: 12px;
  color: var(--color-accent-2-600);
}

.btn.chart-clear-btn:hover {
  color: var(--color-danger);
}

.trace-empty {
  padding: 14px 12px;
  border: 1px dashed var(--color-divider);
  border-radius: var(--radius-md);
  font: 400 12px var(--font-body);
  color: var(--color-accent-2-600);
  text-align: center;
}

/* ------------------------------------------------------- flow regime -- */

/* The two regime maps side by side, as AFS laid them out, stacking once the
   column is too narrow for two readable log-log plots. */
/* Natural height rather than flex: the results column scrolls, and a map
   squeezed to share its height with the case list stops being readable. */
.regime-maps {
  flex: none;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 12px;
}

.regime-maps .chart-panel {
  height: 440px;
}

.chart-panel.regime-cases {
  flex: none;
}

.regime-case-table {
  width: 100%;
  border-collapse: collapse;
  font: 400 12.5px var(--font-body);
  color: var(--color-text);
}

.regime-case-table th,
.regime-case-table td {
  padding: 5px 8px;
  border-bottom: 1px solid var(--color-divider);
  text-align: left;
}

.regime-case-table thead th {
  font: 600 10.5px var(--font-heading);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent-2-600);
}

.regime-case-table td {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--color-accent-700);
}

.regime-case-table td:last-child {
  width: 1%;
  text-align: right;
}

.regime-case-table tbody tr:hover {
  background: var(--color-inset);
}

.regime-case-table tbody th {
  font-weight: 400;
}

.regime-case-swatch {
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 8px;
  border-radius: 50%;
  vertical-align: baseline;
}

/* A caption over a group of rows - "Input Method", "Pressure Range" - in the
   reference tool's own wording. Same voice as a field label, one step dimmer. */
.field-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field-group-label {
  font: 400 10.5px var(--font-body);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--color-accent-2-500);
}

/* ------------------------------------------------------- brine density -- */

/*
 * A unit picker in a field row's unit column (Brine Density's temperature
 * and density). Wider than the 52px static unit, so a row carrying one - or
 * asking to line up with one (`has-wide-unit`) - widens its unit column to
 * match, and the inputs in a panel still share one left edge.
 */
.field-row.has-wide-unit > .unit,
.field-row > .select-input.unit-select {
  width: 84px;
  flex: none;
}

.field-row > .select-input.unit-select {
  font-size: 12px;
}

/* ------------------------------------------------ steady state pipeline -- */

/*
 * Field units here run longer than Brine Density's (MMscf/d, Btu/ft²·h·°F),
 * so this screen's unit pickers - and the static units lined up with them -
 * get a wider column. The wrapper itself is layout-neutral.
 */
.profile-form {
  display: contents;
}

.profile-form .field-row.has-wide-unit > .unit,
.profile-form .field-row > .select-input.unit-select {
  width: 104px;
}

/*
 * Both profiles in one card, as AFS lays them out: a shared head (distance
 * unit, Clear), a small head per plot, the chips at the foot. Each plot keeps
 * a floor so an error notice above can't squeeze them into each other.
 */
.profile-plot {
  flex: 1;
  min-height: 230px;
  display: flex;
  flex-direction: column;
}

.profile-plot + .profile-plot {
  border-top: 1px solid var(--color-divider);
  margin-top: 6px;
  padding-top: 8px;
}

.profile-plot-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.profile-plot-title {
  font: 600 11px var(--font-heading);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent-2-700);
}

/* A plot's own unit choice, in the chart head beside the zoom toolbar. */
.select-input.chart-unit-select {
  width: auto;
  min-width: 64px;
  height: 28px;
  padding-block: 0;
  font-size: 12px;
  margin-right: 6px;
}

/* The results table grows with its rows; the panel scrolls it, not the page. */
.brine-results {
  flex: 1;
  min-height: 0;
}

.results-table-wrap {
  flex: 1;
  min-height: 0;
  overflow: auto;
}

.results-table {
  width: 100%;
  border-collapse: collapse;
  font: 400 12.5px var(--font-body);
  color: var(--color-text);
}

.results-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--color-surface);
  padding: 8px 10px;
  border-bottom: 1px solid var(--color-divider);
  font: 500 10px var(--font-body);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent-2-700);
  text-align: left;
  white-space: nowrap;
}

.results-table .results-unit {
  margin-left: 4px;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--color-accent-2-500);
}

.results-table tbody th,
.results-table tbody td {
  padding: 7px 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--color-divider) 60%, transparent);
  text-align: left;
  font-weight: 400;
}

.results-table tbody tr:hover {
  background: color-mix(in srgb, var(--color-accent-700) 6%, transparent);
}

/* The last Calculate's answer: an accent edge and a tint, the table's
   equivalent of a lifted readout. */
.results-table tbody tr.is-latest {
  background: var(--color-accent-100);
}

.results-table tbody tr.is-latest > th {
  box-shadow: inset 2px 0 0 var(--color-accent-700);
  color: var(--color-accent-800);
}

.results-table .is-num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* The value the solver produced for this row - cyan, as everything
   model-computed is; the typed value beside it stays in plain text. */
.results-table td.is-solved {
  color: var(--color-accent-700);
}

.results-table td.is-warn {
  color: var(--color-warn);
}

.results-table .results-remove {
  width: 32px;
  text-align: right;
}