/* Dark theme -----------------------------------------------------------------
   Additive, and deliberately so. Every rule in this file is scoped under
   [data-theme="dark"], so main.css and ai-interpret.css are untouched and the
   light build cannot regress from anything here.

   Two halves:

   1. The token block, ported verbatim from the design system's tokens/dark.css.
      It is derived from the product's own palette rather than invented, so a
      dark build stays recognisably PaintOmics. Two things deliberately do not
      change - the six omic fills and the database badge palette - because both
      are type-coding read against the pathway diagrams, and both already carry
      near-black ink that reads correctly on a dark surface.

   2. An override layer, which is the part the design system could not supply.
      The system assumes a tokenised stylesheet; this application is not one.
      main.css carries 490 literal colour values against 23 tokens, and
      ai-interpret.css carries 79 against none, so redefining tokens alone would
      have repainted almost nothing. The rules below therefore restate the
      surfaces by selector. They cover the application's own chrome and content,
      plus the ExtJS Neptune widgets it builds on, which ship their own baked-in
      light palette in a vendor stylesheet nothing here can tokenise.

   Known to stay light: the KEGG and Reactome pathway diagrams. They are raster
   and SVG artwork served by those databases with white canvases baked in, and
   inverting them would falsify the data colouring painted onto them - the whole
   point of the bwr ramp is that white means zero. They are content, not chrome,
   and content that is white on paper stays white here.
*/
[data-theme="dark"]{
  /* Ink */
  --pa-ink: #E7E8EA;
  --pa-ink-strong: #FFFFFF;
  --pa-ink-title: #EDEEF0;
  --pa-ink-body: #C9CBD0;
  --pa-ink-label: #A6A9B0;
  --pa-ink-soft: #8B8E96;
  --pa-ink-muted: #8B8E96;
  --pa-ink-nav: #C9CBD0;
  --pa-ink-control: #E7E8EA;

  /* Accents — lifted in lightness to clear AA on a dark field. The link-hover
     quirk survives: it still turns green rather than a darker blue. */
  --pa-link: #6BB6FF;
  --pa-link-hover: #6ED3A8;
  --pa-accent-blue: #6BA8F0;
  --pa-accent-orange: #E38A5A;
  --pa-accent-green: #6BC46A;
  --pa-bold-blue: #8FB3D9;
  /* Currently unread. Their only reader was the hero's uppercase eyebrow badge,
     which was removed on 2026-08-11 along with the version chip beside the
     product name. Kept because they are one half of the accent ramp and the
     pair is the measured answer to a real question -- --pa-teal is 2.33:1 in
     small type on the page ground, so anything reaching for teal at that size
     needs the hover step, not the base one. Do not "clean up" the base without
     the hover, or the next reader repeats the measurement. */
  --pa-teal: #4FB6C4;
  --pa-teal-hover: #7ACBD6;
  --pa-focus-ring: #4CA6FF;

  /* Surfaces */
  --pa-surface: #1E1F23;
  --pa-surface-page: #17181B;
  --pa-surface-sunken: #232429;
  --pa-surface-subtle: #202126;
  --pa-surface-quiet: #2A2C32;
  --pa-surface-toolbar: #212227;
  --pa-border: #33353B;
  --pa-border-row: #2A2C32;
  --pa-border-control: #6E7178;
  --pa-border-control-hover: #8A8D95;
  --pa-border-hover: #4A4D55;
  --pa-scrim: rgba(0, 0, 0, 0.62);

  /* Controls on a toolbar band. The polarity flips here relative to main.css:
     on the ivory band a control brightens to white under the cursor, and on
     this #212227 band it has to step lighter than the band rather than to
     --pa-surface, which is #1E1F23 and darker than the bar it would sit on. */
  --pa-control-bg: #2A2C32;
  --pa-control-hover-bg: #2E3037;
  --pa-control-active-bg: #3A3C44;

  /* Buttons — hues held, lightness raised so white ink still clears AA. */
  --pa-btn-default-bg: #2A2C32;
  --pa-btn-default-ink: #E7E8EA;
  --pa-btn-default-bg-hover: #33353B;
  /* "Lightness raised so white ink still clears AA" is what the line above
     intends, and for the primary it did the opposite. Measured on the rendered
     button: #3D82C4 carries white at 4.05:1 and #4A91D4 at 3.34:1, both under
     the 4.5:1 AA asks of 14px text -- raising the lightness of a mid blue moves
     it *towards* white, not away. This is the Sign in button, Create account,
     Send instructions and the Step 4 view controls.

     So the light theme's own pair is used in both themes: #337AB7 is 4.56:1 on
     the label and still 3.61:1 against the dark surface, and the hover darkens
     to #2E6DA4 (5.47:1 / 3.01:1). Darkening on hover rather than lightening is
     this file's established answer to exactly this problem -- see the
     .acceptButton:hover note in main.css, where no green light enough to read
     as "brighter" could carry white text either. */
  --pa-btn-primary-bg: #337AB7;
  --pa-btn-primary-border: #2E6DA4;
  --pa-btn-primary-bg-hover: #2E6DA4;
  --pa-btn-primary-border-hover: #285F8C;
  --pa-btn-secondary-bg: #2E9A78;
  --pa-btn-secondary-border: #2E9A78;
  --pa-btn-secondary-bg-hover: #38AC87;
  --pa-btn-secondary-border-hover: #38AC87;
  --pa-btn-success-bg: #3F9A3F;
  --pa-btn-success-border: #3F9A3F;
  --pa-btn-success-bg-hover: #4BAE4B;
  --pa-btn-success-border-hover: #4BAE4B;
  --pa-btn-danger-bg: #DB4B47;
  --pa-btn-danger-border: #DB4B47;
  --pa-btn-danger-bg-hover: #E75D59;
  --pa-btn-danger-border-hover: #E75D59;
  --pa-btn-neutral-bg: #3A3B41;
  --pa-btn-neutral-ink: #E7E8EA;
  --pa-btn-neutral-bg-hover: #1D8CBB;
  --pa-btn-ghost-danger-ink: #FF8A82;
  --pa-btn-ghost-danger-ink-hover: #FFA9A3;
  --pa-btn-ghost-danger-bg-hover: #2E2022;

  /* Status */
  --pa-status-error: #E4795F;
  --pa-status-error-ink: #F09A83;
  --pa-status-warning: #E0952E;
  --pa-status-warning-ink: #EDAE55;
  --pa-status-info: #4FA3EE;
  --pa-status-info-ink: #6FB7F5;
  --pa-status-success: #4FA84B;
  --pa-status-success-ink: #6BC46A;
  --pa-toast-success-bg: #1E2A16;
  --pa-toast-success-border: #4E7A22;
  --pa-toast-error-bg: #2E1A1A;
  --pa-toast-error-border: #A34747;
  --pa-toast-warning-bg: #2C2415;
  --pa-toast-warning-border: #9A7420;
  --pa-toast-ink: #D6D8DC;

  /* Navigation accents */
  --pa-nav-accent-1: #E4739B;
  --pa-nav-accent-2: #CBB93E;
  --pa-nav-accent-3: #6FA9DE;
  --pa-nav-accent-4: #62B571;
  --pa-nav-pill-active: #3A3D45;
  --pa-toc-strip-bg: rgba(23, 24, 27, 0.94);
  --pa-toc-current-bg: #E7E8EA;
  --pa-toc-current-ink: #17181B;
  --pa-toc-marker: #E7E8EA;
  --pa-tab-edge: #3C5670;
  --pa-tab-accent: #4E93E0;

  /* Grid */
  --pa-grid-header-bg: #2A2C32;
  --pa-grid-header-ink: #EDEEF0;
  --pa-grid-action: #A79FA3;
  --pa-grid-action-active: #7FC0FF;
  --pa-grid-row-selected: #26333F;
  --pa-grid-row-alt: #1F272E;
  /* The "no data for this pathway" cell. PA_Step3Views writes this as an inline
     style, so it is read through var(--pa-cell-empty, #D4D4D4): light keeps the
     literal, dark substitutes this. It has to stay distinguishable from an
     ordinary empty cell without reading as a value, which is what the light grey
     did - so it is one step off the row ground, not a colour. */
  --pa-cell-empty: #2C2E34;

  /* Charts (Highcharts draws its own light palette into the SVG) */
  --pa-chart-bg: #1E1F23;
  --pa-chart-ink: #C9CBD0;
  --pa-chart-ink-soft: #A6A9B0;
  --pa-chart-grid: #33353B;
  --pa-chart-axis: #4A4D55;

  /* Form controls */
  --pa-invalid-bg: #2E1C21;
  --pa-invalid-border: #A15C5C;
  --pa-legacy-field-bg: #23252A;
  --pa-legacy-field-ink: #B7BAC1;
  --pa-legacy-field-border: #3B3E45;
  --pa-legacy-field-shadow: none;
  --pa-segmented-on: #4E6E92;
  --pa-segmented-off: #4A4C52;
  --pa-segmented-ink: #EDEEF0;

  /* AI */
  --pa-ai-blue: #4A90D9;
  --pa-ai-blue-hover: #5CA0E6;
  --pa-ai-panel-bg: #1A1B1F;
  --pa-ai-bubble-bg: #24262B;
  --pa-ai-user-bubble: #1F2E3D;
  --pa-ai-user-bubble-border: #2E4358;
  --pa-ai-section-border: #2C3E50;
  --pa-ai-section-bg: linear-gradient(to bottom, #1C2029, #191C23);
  --pa-ai-pathway-link: #5FC08B;
  --pa-ai-pathway-link-hover: #85D2A8;
  --pa-ai-consent-warn: #F08A5D;
  --pa-ai-progress-bg: #1C2530;
  --pa-ai-progress-ink: #9FC2E8;
  --pa-ai-progress-track: #2A3746;

  /* Elevation — shadows on a dark page need more alpha to register at all. */
  --pa-shadow: 0 1px 3px rgba(0, 0, 0, 0.45), 0 1px 2px -1px rgba(0, 0, 0, 0.35);
  --pa-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.5);
  --pa-shadow-overlay: 0 12px 28px -8px rgba(0, 0, 0, 0.7), 0 6px 12px -6px rgba(0, 0, 0, 0.5);
  --pa-shadow-panel: 0 12px 32px rgba(0, 0, 0, 0.6);
  --pa-shadow-soft: 0 1px 4px rgba(0, 0, 0, 0.4);
  --pa-shadow-soft-hover: 0 4px 12px rgba(0, 0, 0, 0.5);
  --pa-shadow-image: 0 2px 12px rgba(0, 0, 0, 0.5);
  --pa-shadow-ai-panel: 0 8px 32px rgba(0, 0, 0, 0.55);

  color-scheme: dark;
}

/* ---------------------------------------------------------------------------
   1. Page and application chrome
   --------------------------------------------------------------------------- */

[data-theme="dark"] body,
[data-theme="dark"] .x-body {
	background-color: var(--pa-surface-page);
	color: var(--pa-ink);
}

/* The centre panel's grey is written inline by MainView's viewport config, so
   it needs the specificity of an id to come back. */
[data-theme="dark"] #mainViewCenterPanel {
	background-color: var(--pa-surface-page) !important;
}

[data-theme="dark"] .mainTopToolbar {
	background: var(--pa-surface-toolbar);
	border-bottom-color: var(--pa-border);
}
[data-theme="dark"] #header h1 { color: var(--pa-ink); }

[data-theme="dark"] ul.lateralMenu-body { background: var(--pa-surface-quiet); }
[data-theme="dark"] .lateralMenu-body > .menuOption { color: var(--pa-ink-nav); }
[data-theme="dark"] .lateralMenu-body > .menuOption:hover,
[data-theme="dark"] .lateralMenu-body > .menuOption.selected {
	background: var(--pa-nav-pill-active);
	color: var(--pa-ink-strong);
}
[data-theme="dark"] .lateralMenu-body ul.submenu {
	background: var(--pa-surface);
	border-color: var(--pa-border);
	box-shadow: var(--pa-shadow-overlay);
}
[data-theme="dark"] ul.submenu li.menuOption { color: var(--pa-ink-body); }
[data-theme="dark"] ul.submenu li.menuOption:hover { background: var(--pa-surface-quiet); }
[data-theme="dark"] ul.submenu a { color: var(--pa-link); }

/* The More panel. Its column headings and citation metadata take --pa-ink-muted,
   which the token block above already redefines, so only the three places that
   name a colour or a border literally in main.css need restating here. */
[data-theme="dark"] .navPanel-foot { border-top-color: var(--pa-border); }
[data-theme="dark"] .navPanel-cite-name { color: var(--pa-ink-strong); }
[data-theme="dark"] .navPanel-cite-bib { border-color: var(--pa-border); }
[data-theme="dark"] .navPanel-cite-bib:hover { background: var(--pa-surface-quiet); }
/* The divider between the step actions and the utility corner. main.css sets a
   dark ink at 0.18, which on a dark bar is very nearly invisible; a hairline has
   to be lighter than what it sits on here, not darker. */
[data-theme="dark"] .mainTopToolbar .headerUtilities::before { background: rgba(255, 255, 255, 0.20); }

/* Header and step-action controls. main.css states the ghost button's fill,
   ink and border literally, so all three are restated. */
[data-theme="dark"] .mainTopToolbar .button,
[data-theme="dark"] .secondTopToolbar .button,
[data-theme="dark"] .paToolbarMiniature .button {
	background-color: var(--pa-btn-default-bg);
	color: var(--pa-btn-default-ink);
	border-color: var(--pa-border-control);
}
[data-theme="dark"] .mainTopToolbar .button:hover,
[data-theme="dark"] .secondTopToolbar .button:hover {
	background-color: var(--pa-btn-default-bg-hover);
	color: var(--pa-ink-strong);
	border-color: var(--pa-border-control-hover);
}
[data-theme="dark"] .secondTopToolbar .button.btn-success {
	background-color: var(--pa-btn-success-bg);
	border-color: transparent;
	color: #FFFFFF;
}
[data-theme="dark"] .secondTopToolbar .button.btn-success:hover {
	background-color: var(--pa-btn-success-bg-hover);
}
[data-theme="dark"] .mainTopToolbar .button.btn-danger,
[data-theme="dark"] .secondTopToolbar .button.btn-danger,
[data-theme="dark"] .paToolbarMiniature .button.btn-danger {
	background-color: transparent;
	color: var(--pa-btn-ghost-danger-ink);
	border-color: var(--pa-border-control);
}
/* The highlight ring on the miniature's Settings button: the light theme's
   #B3261E measures poorly on the dark card, so use the same danger ink the
   dark button itself carries. */
[data-theme="dark"] .paToolbarMiniature .paMiniatureTarget {
	box-shadow: 0 0 0 2px var(--pa-btn-ghost-danger-ink);
}
[data-theme="dark"] .mainTopToolbar .button.btn-danger:hover,
[data-theme="dark"] .secondTopToolbar .button.btn-danger:hover {
	background-color: var(--pa-btn-ghost-danger-bg-hover);
	color: var(--pa-btn-ghost-danger-ink-hover);
}
/* The account control keeps a filled treatment in dark too (HeaderButton
   tone="account"), but the neutral fill is only 1.42:1 against the #212227
   toolbar, so unlike the light theme the boundary has to stay on the border -
   --pa-border-control is 3.25:1 on the bar. The old `border-color: transparent`
   mirrored main.css's and cancelled the --pa-border-control outline restated
   above, leaving #2A2C32 on #212227 at 1.14:1 where WCAG 1.4.11 asks for 3:1. */
[data-theme="dark"] .mainTopToolbar .button {
	background-color: var(--pa-btn-neutral-bg);
	color: var(--pa-btn-neutral-ink);
	border-color: var(--pa-border-control);
}
/* Without this the filled pill turns back into a ghost the moment it is pointed
   at: the rule above is (0,3,0) and the shared header hover further up is
   (0,4,0), so on hover the account control lost its fill and its identity. This
   is (0,4,0) too and comes later, which is what it takes to win.

   The fill is the light theme's #117EA9 rather than the design system's dark
   --pa-btn-neutral-bg-hover (#1D8CBB). The token is the nominally correct one
   and it fails here: white on #1D8CBB is 3.80:1, under the 4.5:1 this control's
   12.5px label needs. #117EA9 gives 4.58:1 on the label and 3.46:1 against the
   bar, and has the side effect that both themes now hover to the same colour. */
[data-theme="dark"] .mainTopToolbar .button:hover {
	background-color: #117EA9;
	color: #FFFFFF;
	border-color: var(--pa-border-control-hover);
}

/* Contents rail */
[data-theme="dark"] .pa-toc { background: var(--pa-toc-strip-bg); }
[data-theme="dark"] .pa-toc-link { color: var(--pa-ink-label); }
[data-theme="dark"] .pa-toc-link:hover { color: var(--pa-ink-strong); }
/* The current item inverts in the dark theme - a light pill carrying dark ink -
   which is the design system's own treatment and the only marker on this rail
   that has to win against a page of dark surfaces. Both halves are stated
   together; setting the ink alone left white text on the light pill. */
[data-theme="dark"] .pa-toc-link.current {
	background: var(--pa-toc-current-bg);
	color: var(--pa-toc-current-ink);
	border-color: var(--pa-toc-marker);
}

/* ---------------------------------------------------------------------------
   2. Content surfaces
   --------------------------------------------------------------------------- */

/* The card fill, which this rule used to leave behind.

   `.contentbox` is the results page's card, and main.css states its fill as a
   literal -- `background: #fff`, not a token -- while its border and shadow are
   both tokens this file redefines. So the border went dark, the ink went dark,
   and the fill stayed white: --pa-ink-body #C9CBD0 on #FFFFFF, which measures
   1.62:1 against the 4.5:1 AA asks of body text. Every paragraph on Step 3's
   "Pathways selection", "Pathways summary" and "Multiple databases used" was
   effectively unreadable.

   It hid because `.x-panel-body.contentbox` -- the form cards on step 1 -- were
   already dark: they match the .x-panel-body rule further down, which is (0,2,0)
   and beats a bare `.contentbox`. Only the .contentbox elements that ExtJS does
   not make panel bodies were left white, and those are almost all on Step 3, so
   the light theme and the whole upload flow looked correct.

   --pa-surface, the same token .x-panel-body takes, so a card reads the same
   whether or not ExtJS happened to make it a panel body. The border and shadow
   are what separate it from the page, and both are already themed. */
[data-theme="dark"] .contentbox,
[data-theme="dark"] .omicSummaryBox {
	background: var(--pa-surface);
}
[data-theme="dark"] .contentbox,
[data-theme="dark"] .omicSummaryBox,
[data-theme="dark"] .po-about-section,
/* No fill, border or shadow to restate: the step cards are columns on the
   section's own surface in both themes now, so only their ink is themed. And
   deliberately not in the background rule above -- giving these three a fill is
   the "box drawn inside a box" the .po-step-card comment in main.css exists to
   undo. */
[data-theme="dark"] .po-step-card {
	color: var(--pa-ink-body);
}
/* Card headings carry their own white fill and near-black ink, so both have to
   move together. Recolouring only the ink - which is what a blanket heading
   rule does - turns "How It Works" into near-white text on a white band, which
   is worse than leaving it alone.

   Deliberately no blanket h1-h6 rule here. The base heading colours in main.css
   are already written as var(--pa-accent-orange) and friends, and the token
   block above has redefined those; overriding the headings wholesale would
   throw away the accent the theme just supplied. */
[data-theme="dark"] div.contentbox h2,
[data-theme="dark"] #clusternumber_box h2,
[data-theme="dark"] #threshold_box h2,
[data-theme="dark"] .step4HistoryBox h2 {
	background-color: var(--pa-surface);
	border-bottom-color: var(--pa-border);
	color: var(--pa-ink-title);
}
[data-theme="dark"] a { color: var(--pa-link); }
[data-theme="dark"] a:hover { color: var(--pa-link-hover); }
[data-theme="dark"] b { color: var(--pa-bold-blue); }
[data-theme="dark"] span.infoTip,
[data-theme="dark"] span.infoTip:before { color: var(--pa-accent-blue); }
[data-theme="dark"] span.commentTip { color: var(--pa-ink-muted); }
[data-theme="dark"] .sessionAvatar { color: var(--pa-ink-muted); }

/* ---------------------------------------------------------------------------
   3. ExtJS Neptune widgets

   The vendor stylesheet is loaded before main.css and bakes its own light
   palette into every widget class. These are the surfaces the analysis actually
   renders on: panels, grids, headers, toolbars, fields, menus and dialogs.
   --------------------------------------------------------------------------- */

[data-theme="dark"] .x-panel,
[data-theme="dark"] .x-panel-body,
[data-theme="dark"] .x-panel-body-default,
[data-theme="dark"] .x-container,
[data-theme="dark"] .x-box-inner {
	background-color: var(--pa-surface);
	color: var(--pa-ink-body);
	border-color: var(--pa-border);
}
[data-theme="dark"] .x-panel-header,
[data-theme="dark"] .x-panel-header-default {
	background-color: var(--pa-surface) !important;
	color: var(--pa-ink-title);
	border-color: var(--pa-border);
}
/* `-text` as well as `-title`, and this is the same ExtJS 4.2.1 / 6 naming
   trap the window-header block further down this file already warns about:
   `.x-panel-header-title` is the ExtJS 6 name, and this app runs 4.2.1, where
   the element is `.x-panel-header-text`. So the two selectors that were here
   matched nothing at all - the dark title was only ever legible because
   Neptune's own colour on it happens to be white.

   That went unnoticed until main.css started stating a panel-header title
   colour of its own. A light `#222` on a selector that *does* match, against a
   dark rule on selectors that do not, measured 1.03:1 - black text on a black
   band. Adding the name the DOM actually uses is the fix; the ExtJS 6 names
   stay so this keeps working if the framework is ever upgraded. */
[data-theme="dark"] .x-panel-header-title,
[data-theme="dark"] .x-panel-header-title-default,
[data-theme="dark"] .x-panel-header-text,
[data-theme="dark"] .x-panel-header-default .x-panel-header-text,
[data-theme="dark"] .x-panel-header-default .x-header-text { color: var(--pa-ink-title); }

/* Grids */
[data-theme="dark"] .x-grid-body,
[data-theme="dark"] .x-grid-view,
[data-theme="dark"] .x-grid-item-container {
	background-color: var(--pa-surface);
	border-color: var(--pa-border);
}
[data-theme="dark"] .x-column-header,
[data-theme="dark"] .x-column-header-inner,
[data-theme="dark"] .x-grid-header-ct {
	background-color: var(--pa-grid-header-bg) !important;
	background-image: none !important;
	color: var(--pa-grid-header-ink);
	border-color: var(--pa-border) !important;
}
[data-theme="dark"] .x-column-header-text,
[data-theme="dark"] .x-column-header-text-inner { color: var(--pa-grid-header-ink); }
[data-theme="dark"] .x-grid-cell,
[data-theme="dark"] .x-grid-td {
	background-color: transparent;
	color: var(--pa-ink-body);
	border-color: var(--pa-border-row) !important;
}
[data-theme="dark"] .x-grid-item-alt .x-grid-cell { background-color: var(--pa-grid-row-alt); }
[data-theme="dark"] .x-grid-item-over .x-grid-cell { background-color: var(--pa-surface-quiet); }
[data-theme="dark"] .x-grid-item-selected .x-grid-cell { background-color: var(--pa-grid-row-selected); }
[data-theme="dark"] .x-grid-with-row-lines .x-grid-item { border-color: var(--pa-border-row); }

/* Toolbars, tabs and paging bars */
[data-theme="dark"] .x-toolbar,
[data-theme="dark"] .x-toolbar-default,
[data-theme="dark"] .x-tab-bar,
[data-theme="dark"] .x-tab-bar-default {
	background-color: var(--pa-surface-toolbar) !important;
	background-image: none !important;
	border-color: var(--pa-border);
}
[data-theme="dark"] .x-tab,
[data-theme="dark"] .x-tab-default {
	background-color: var(--pa-surface-quiet);
	background-image: none;
	border-color: var(--pa-border);
}
[data-theme="dark"] .x-tab .x-tab-inner { color: var(--pa-ink-label); }
[data-theme="dark"] .x-tab-active .x-tab-inner { color: var(--pa-ink-strong); }
[data-theme="dark"] .x-tab-active { background-color: var(--pa-surface); }
/* Step 3's database tabs are the one bar main.css rebuilds from scratch - as a
   segmented control, two pills with the selected one filled, see the note
   there. Every colour in that rebuild is a literal chosen against the ivory
   page: `#1A1A18` for the selected fill, `#FFFFFF` for the label knocked out of
   it, `rgba(24,24,27,0.20)` for the hover border. All three are stated by an id
   selector, so these have to carry one too.

   The selected pill inverts rather than dimming. In the light theme it is the
   darkest thing on the page and that is what makes it read as chosen at a
   glance; the same statement here is the lightest, so the fill takes the title
   ink and the label takes the card underneath it. Filling it with a dark grey
   instead - the literal translation - would put the selected pill *closer* to
   the page than the unselected one, which is the one thing this control cannot
   afford to get backwards. */
/* The database tabs are bookmarks now, not pills - see "The database tabs" in
   main.css. That changes what dark mode has to say about them: the selected tab
   is no longer a filled shape to be inverted, it is the card's own surface
   continuing upward, so it takes --pa-surface and the seam takes the same
   colour. Left as it was, the selected tab stayed a near-white slab with dark
   text sitting on a dark card - the one element on the page that had not been
   told the lights were off. */
[data-theme="dark"] div#tabcontainer_network .x-tab {
	background: var(--pa-surface-sunken);
	border-color: var(--pa-border) !important;
}
[data-theme="dark"] div#tabcontainer_network .x-tab:not(.x-active):hover {
	background: var(--pa-control-hover-bg);
	border-color: var(--pa-border-hover) !important;
}
[data-theme="dark"] div#tabcontainer_network .x-tab.x-active {
	background: var(--pa-surface);
	border-color: var(--pa-border) !important;
	box-shadow: 0 1px 0 0 var(--pa-surface);
}
[data-theme="dark"] div#tabcontainer_network .x-tab.x-active .x-tab-inner {
	color: var(--pa-ink-title);
}
[data-theme="dark"] div#tabcontainer_network .x-tab:not(.x-active) .x-tab-inner {
	color: var(--pa-ink-muted);
}
[data-theme="dark"] div#tabcontainer_network .x-tab:not(.x-active):hover .x-tab-inner {
	color: var(--pa-ink-title);
}

/* The pathway explorer card ---------------------------------------------------
   Its two controls - the fold on "Pathway categories" and the Tools/Details
   tabs on the network's rail - are `a` elements, and `[data-theme="dark"] a`
   here scores the same as main.css's `a.paNetRailTab` while loading after it.
   So without these the tabs and the fold came out link-blue on a panel where
   nothing else is a link, and the selected rail tab could not be told from the
   other one by colour at all. */
[data-theme="dark"] a.paExploreFold,
[data-theme="dark"] a.paNetRailTab,
[data-theme="dark"] a.paNetRailHide {
	color: var(--pa-ink-muted);
}
[data-theme="dark"] a.paNetRailTab.is-active {
	color: var(--pa-ink-title);
	background: var(--pa-surface);
}
[data-theme="dark"] a.paExploreFold:hover,
[data-theme="dark"] a.paNetRailTab:hover {
	color: var(--pa-ink-title);
}
[data-theme="dark"] a.paNetRailHide:hover {
	color: var(--pa-accent-orange);
}
/* main.css sets a bare `h4 { color: #27272A }` and dark.css answers it only in
   the places that had been looked at - the AI bubbles, the omic boxes, the two
   side panels. "Category Distribution" and "Filter by category" were not among
   them, so they were near-black on a #1E1F23 card: present in the DOM, legible
   nowhere. Scoped to this card rather than to `div.contentbox h4`, because
   several cards colour their h4s deliberately and a blanket rule here would
   overwrite those without anyone noticing which. */
[data-theme="dark"] .paExploreCard h4 {
	color: var(--pa-ink-label);
}

/* Form fields.

   `.x-form-field` also sits on every ExtJS checkbox and radio
   (class="x-form-field x-form-checkbox ..."), and this blanket's !important
   background pair beat the checkbox rules further down, which are not
   !important: the checked box lost both its --pa-accent-blue fill and its
   background-image tick, so a checked control rendered pixel-identical to an
   unchecked one - on the enrichment toolbar there was no way to see whether
   KEGG or Reactome was selected. Checkboxes and radios are excluded here so
   the dedicated rules below can draw their two states. */
[data-theme="dark"] .x-form-field:not(.x-form-checkbox):not(.x-form-radio),
[data-theme="dark"] .x-form-text,
[data-theme="dark"] .x-form-textarea,
[data-theme="dark"] .x-form-trigger-wrap {
	background-color: var(--pa-legacy-field-bg) !important;
	background-image: none !important;
	color: var(--pa-legacy-field-ink) !important;
	border-color: var(--pa-legacy-field-border) !important;
}
[data-theme="dark"] .x-form-item-label,
[data-theme="dark"] .x-form-item-label-default,
[data-theme="dark"] .x-form-cb-label { color: var(--pa-ink-label); }
[data-theme="dark"] .x-form-invalid-field {
	background-color: var(--pa-invalid-bg) !important;
	border-color: var(--pa-invalid-border) !important;
}
[data-theme="dark"] input::placeholder,
[data-theme="dark"] textarea::placeholder { color: var(--pa-ink-soft); }

/* Buttons, menus, dialogs and tips */
[data-theme="dark"] .x-btn-default-small,
[data-theme="dark"] .x-btn-default-toolbar-small {
	background-color: var(--pa-btn-default-bg);
	background-image: none;
	border-color: var(--pa-border-control);
	color: var(--pa-btn-default-ink);
}
[data-theme="dark"] .x-btn-inner { color: var(--pa-btn-default-ink); }
[data-theme="dark"] .x-menu,
[data-theme="dark"] .x-menu-body {
	background-color: var(--pa-surface);
	border-color: var(--pa-border);
}
[data-theme="dark"] .x-menu-item-text { color: var(--pa-ink-body); }
[data-theme="dark"] .x-menu-item-active .x-menu-item-link { background-color: var(--pa-surface-quiet); }

/* The combobox dropdown - the organism picker, and every other `combo` in the
   app. This had no dark rule at all, and the failure mode is the one the window
   header a few lines below documents: the *ink* was already dark-themed by a
   broad rule, so the list drew --pa-ink-body #C9CBD0 on the white
   .x-boundlist fill Neptune ships. Measured 1.62:1 - not "low contrast", but
   pale grey on white, which is a list of six hundred organisms you cannot read
   at all. The hover row was worse in a way that hid the cause: Neptune paints
   it #D6E8F6, a light blue, so the one row under the pointer looked like a
   deliberate highlight and the rest looked like a rendering glitch.

   .x-boundlist-item-over and -selected both have to be restated. Leaving either
   at its Neptune value puts a light fill back under pale ink, one row at a time,
   which is the same bug with a smaller footprint.

   Floating: ExtJS renders this under <body>, not inside the field. That is fine
   for the selector - [data-theme="dark"] is on <html> - but it is why the list
   cannot inherit anything from the form it belongs to. */
[data-theme="dark"] .x-boundlist {
	background-color: var(--pa-surface);
	border-color: var(--pa-border);
}
[data-theme="dark"] .x-boundlist-item {
	color: var(--pa-ink-body);
	border-color: transparent;
}
[data-theme="dark"] .x-boundlist-item-over {
	background-color: var(--pa-surface-quiet);
	border-color: var(--pa-border-hover);
	color: var(--pa-ink-strong);
}
[data-theme="dark"] .x-boundlist-selected {
	background-color: var(--pa-surface-sunken);
	border-color: var(--pa-border-control);
	color: var(--pa-ink-strong);
}
/* The empty-list and loading rows, which Neptune also leaves on white. */
[data-theme="dark"] .x-boundlist-list-ct,
[data-theme="dark"] .x-combo-list-item,
[data-theme="dark"] .x-boundlist-empty {
	background-color: var(--pa-surface);
	color: var(--pa-ink-body);
}
[data-theme="dark"] .x-window,
[data-theme="dark"] .x-window-body {
	background-color: var(--pa-surface);
	border-color: var(--pa-border);
	color: var(--pa-ink-body);
}
/* The sentence in a MessageBox does not inherit the body colour above, because
 * it is not text -- it is a form field. `Ext.window.MessageBox` builds its
 * `msg` out of `Ext.form.field.Display`, so the element that actually carries
 * "Are you sure you want to exit the current job?" is `.x-form-display-field`,
 * and Neptune ships `.x-form-display-field { color: black }` for it.
 *
 * Neither of the two rules that look like they should have covered this does.
 * `.x-window-body` sets an inherited colour, which stops the moment a
 * descendant declares its own. The `.x-form-field` block near the top of this
 * file is `!important` and would have won -- but a display field never carries
 * that class: `x-form-field` is on the <input>, and a display field renders a
 * <div> instead precisely because it has no input.
 *
 * Measured on a rendered confirm dialog: rgb(0, 0, 0) on --pa-surface #1E1F23,
 * 1.28:1. Every alert(), confirm() and prompt() in the app was a black sentence
 * on a black card -- the buttons and the title were correct, which is why it
 * read as a dialog with its question missing rather than as a broken theme.
 *
 * Not scoped to `.x-message-box`: the leak is Neptune's default for the field
 * type, so any display field this app grows later would arrive black too.
 */
[data-theme="dark"] .x-form-display-field { color: var(--pa-ink-body); }
/* Window headers need the SURFACE as well as the text colour.
 *
 * This block used to set `color` only, which produced light text on the
 * ExtJS default header background (#f6f6f6) -- every modal title in dark mode
 * was white on near-white and effectively invisible. It was not noticed
 * because the two windows that existed (the regulatory-method chooser and the
 * info dialogs) are read for their body text, not their title.
 *
 * `.x-window-header-title` is the ExtJS 6 class name; this app runs ExtJS
 * 4.2.1, where the element is `.x-window-header-text`. Both are listed so the
 * rule survives an upgrade, but only the second one matches today. Verified by
 * measuring the computed style on a rendered window, not by eye.
 */
[data-theme="dark"] .x-window-header {
	background-color: var(--pa-surface-quiet);
	background-image: none;
	border-color: var(--pa-border);
}
[data-theme="dark"] .x-window-header,
[data-theme="dark"] .x-window-header-text,
[data-theme="dark"] .x-window-header-title { color: var(--pa-ink-title); }
/* main.css already claims this element with
 *     .x-window-default > .x-window-header .x-header-text { color: #222; }
 * at specificity (0,3,0), which outranks the (0,2,0) selectors above -- so
 * without this the title merely went from invisible-white to invisible-dark
 * once the header background was darkened. Matching main.css's shape and
 * adding the theme attribute puts it at (0,4,0). Measured on a rendered
 * window: computed colour must be the light token, not rgb(34,34,34).
 */
[data-theme="dark"] .x-window-default > .x-window-header .x-header-text {
	color: var(--pa-ink-title);
}
[data-theme="dark"] .x-mask { background-color: var(--pa-scrim); }
[data-theme="dark"] .x-tip,
[data-theme="dark"] .x-tip-body {
	background-color: var(--pa-surface-quiet) !important;
	background-image: none !important;
	color: var(--pa-ink-body) !important;
	border-color: var(--pa-border) !important;
}

/* ---------------------------------------------------------------------------
   4. AI interpretation surfaces (ai-interpret.css owns these, untokenised)
   --------------------------------------------------------------------------- */

[data-theme="dark"] .ai-widget-panel {
	background: var(--pa-ai-panel-bg);
	border-color: var(--pa-border);
	box-shadow: var(--pa-shadow-ai-panel);
}
[data-theme="dark"] .ai-widget-header { background: var(--pa-ai-blue); }
[data-theme="dark"] .ai-widget-messages { background: var(--pa-ai-panel-bg); }
[data-theme="dark"] .ai-msg-bubble {
	background: var(--pa-ai-bubble-bg);
	color: var(--pa-ink-body);
}
[data-theme="dark"] .ai-msg-user .ai-msg-bubble {
	background: var(--pa-ai-user-bubble);
	border-color: var(--pa-ai-user-bubble-border);
}
[data-theme="dark"] .ai-widget-input-area {
	background: var(--pa-surface);
	border-top-color: var(--pa-border);
}
[data-theme="dark"] .ai-widget-input-area textarea {
	background: var(--pa-legacy-field-bg);
	color: var(--pa-ink-body);
	border-color: var(--pa-legacy-field-border);
}
[data-theme="dark"] .ai-widget-fab { background: var(--pa-ai-blue); }
[data-theme="dark"] .ai-progress-track { background: var(--pa-ai-progress-track); }
[data-theme="dark"] .ai-progress-detail { color: var(--pa-ai-progress-ink); }
/* The activity feed sits on the same progress surface, so it takes the same
   ink; the muted columns step down from it rather than using the light values,
   which fall to about 2:1 on the dark panel. */
[data-theme="dark"] .ai-activity-row { color: var(--pa-ai-progress-ink); }
[data-theme="dark"] .ai-activity-detail,
[data-theme="dark"] .ai-activity-ms,
[data-theme="dark"] .ai-activity-row.is-count { color: var(--pa-ink-muted); }
[data-theme="dark"] .ai-activity-row.is-failed .ai-activity-tool,
[data-theme="dark"] .ai-activity-row.is-failed .ai-activity-detail { color: #ff8a80; }
[data-theme="dark"] .ai-pathway-link { color: var(--pa-ai-pathway-link); }
[data-theme="dark"] .ai-pathway-link:hover { color: var(--pa-ai-pathway-link-hover); }
[data-theme="dark"] .ai-citations-toggle { color: var(--pa-link); }
/* The report's attribution caption. ai-interpret.css sets #555 on white, which
   is 2.03:1 once the bubble goes dark. --pa-ink-muted (#8B8E96) on
   --pa-ai-bubble-bg (#24262B) measures 4.62:1, over AA for the 11px it is set
   at, and keeps the caption quieter than the report body it annotates. The
   #e0e0e0 rule above it is a near-white hairline on that bubble, so it moves to
   --pa-border with the rest of the dark separators. */
[data-theme="dark"] .ai-report-provenance {
	color: var(--pa-ink-muted);
	border-top-color: var(--pa-border);
}
/* The report itself. .ai-msg-bubble was restated above, so its paragraphs came
   out at 9.33:1 -- but the markdown block inside it never was, and every
   element there carries an ink chosen for a white bubble. Measured on a real
   report in this theme:

       h1 1.13:1   h2 1.38:1   h3 1.63:1   strong 1.38:1 (x39 in one report)

   so bold made text *less* legible than the sentence around it. The
   light-theme ordering is kept: h1 strongest, h2/h3 and bold a step above the
   body, h4 a step below. The #e0e0e0 hairlines on h2 and hr go with them. */
[data-theme="dark"] .ai-msg-bubble h1 { color: var(--pa-ink-strong); }
[data-theme="dark"] .ai-msg-bubble h2,
[data-theme="dark"] .ai-msg-bubble h3,
[data-theme="dark"] .ai-msg-bubble strong,
[data-theme="dark"] .ai-msg-bubble b { color: var(--pa-ink-title); }
[data-theme="dark"] .ai-msg-bubble h4 { color: var(--pa-ink-label); }
[data-theme="dark"] .ai-msg-bubble h2,
[data-theme="dark"] .ai-msg-bubble hr { border-color: var(--pa-border); }
/* `em` needs no rule: it inherits the bubble's ink, which is why
   ai-interpret.css sets `color: inherit` on it rather than a grey. */

/* Tinted runs. #f0f7ff and #f5f5f5 are white slabs here, and a callout cannot
   set itself apart by being the brightest thing in a dark panel. `pre` already
   ships a dark fill. */
[data-theme="dark"] .ai-msg-bubble blockquote {
	background: var(--pa-surface-quiet);
	border-left-color: var(--pa-accent-blue);
	color: var(--pa-ink-body);
}
[data-theme="dark"] .ai-msg-bubble code { background: var(--pa-surface-quiet); }
[data-theme="dark"] .ai-msg-bubble th {
	background: var(--pa-surface-quiet);
	border-color: var(--pa-border);
}
[data-theme="dark"] .ai-msg-bubble td { border-color: var(--pa-border); }

/* Step 1's AI paragraph and the consent notice's fine print. Both carried
   their colour inline and were reached from section 7 below by matching on the
   `style` attribute; they are classes now, so they take the same two inks the
   attribute selectors were mapping #555 and #666 to. */
[data-theme="dark"] .ai-intro-copy { color: var(--pa-ink-body); }
[data-theme="dark"] .ai-gdpr-fineprint { color: var(--pa-ink-label); }

/* ---------------------------------------------------------------------------
   5. The toggle itself
   --------------------------------------------------------------------------- */

/* No `margin-left: auto` here. It used to be, and it was the whole problem: the
   switch was a direct child of the header's flex row and the only one with an
   auto margin, so it swallowed every pixel of free space and came to rest
   wherever that happened to leave it - a lone unlabelled glyph between the step
   actions and the account pill, in a group of its own size one. The margin now
   belongs to `.headerUtilities` in main.css, the wrapper holding this control
   and the account button, and this one just sits inside it on the group's 8px
   gap. main.css's `.secondTopToolbar` no longer needs to know this control's
   width either: it reserves the group's measured width instead. */
.themeToggle {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	border: 1px solid transparent;
	border-radius: 999px;
	background: transparent;
	color: var(--pa-ink-nav, #3A3B42);
	font-size: 14px;
	line-height: 1;
	cursor: pointer;
}
.themeToggle:hover {
	background: var(--pa-surface-quiet, #F1F2F4);
	color: var(--pa-ink-strong, #111111);
}
.themeToggle:focus-visible {
	outline: 2px solid var(--pa-focus-ring);
	outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   6. The landing page

   Its hero, step cards and about section predate the token layer entirely and
   state every colour literally, so none of them moved with the tokens above.
   Measured on the dark build before these rules, twenty-eight text nodes here
   sat below 3:1 against their own background - the hero description and the
   "Data Uploading" headings were the worst, at 2.2 and 1.0.
   --------------------------------------------------------------------------- */

[data-theme="dark"] .po-hero,
[data-theme="dark"] .po-hero-section,
[data-theme="dark"] .po-about-section { background: var(--pa-surface-page); }
[data-theme="dark"] .po-hero h1 { color: var(--pa-ink-title); }
[data-theme="dark"] .po-hero-desc { color: var(--pa-ink-body); }

[data-theme="dark"] .po-step-card h3 { color: var(--pa-ink-title); }
[data-theme="dark"] .po-step-card {
	color: var(--pa-ink-body);
}
[data-theme="dark"] .po-step-card li,
[data-theme="dark"] .po-step-card p { color: var(--pa-ink-body); }
/* The diagram plate. Its light fill is one of the warm literals main.css lists
   as untokenised, so it cannot follow a token here and has to be restated - the
   same reason the surfaces around it are restated by selector rather than by
   swapping a variable. The step-head hairline needs nothing: it is already
   drawn with --pa-border, which this sheet redefines.

   The diagrams themselves keep their light strokes and fills on purpose. They
   are pictures of the real interface - the omic row colours, the bwr value
   swatches, the painted network - and recolouring them for the theme would
   show a reader something the application never draws. */
[data-theme="dark"] .po-step-art { background: var(--pa-surface-quiet); }
/* The type inside the diagrams - the omic names in step 1, the identifiers and
   accessions in step 2. It is drawn with fill="currentColor" precisely so this
   one declaration can move it; as a hardcoded #3F3F46 it was dark grey on a
   dark plate, which is to say it was not there. */
[data-theme="dark"] .po-step-art-svg { color: var(--pa-ink-body); }
[data-theme="dark"] .po-hero-actions .po-btn-outline {
	color: var(--pa-ink);
	border-color: var(--pa-border-control);
	background: transparent;
}
[data-theme="dark"] .po-hero-actions .po-btn-outline:hover {
	background: var(--pa-surface-quiet);
	border-color: var(--pa-border-control-hover);
}
[data-theme="dark"] .po-hero-ai-highlight {
	background: var(--pa-ai-section-bg);
	border-color: var(--pa-ai-section-border);
}
[data-theme="dark"] .po-hero-ai-highlight p { color: var(--pa-ink-body); }
/* The light theme darkens this blue to #1F6BC1 to clear 4.5:1 on a near-white
   panel. On the dark panel the requirement inverts - a dark blue would be the
   unreadable one - so it takes the brighter AI blue that the mark beside it
   uses, which is where --pa-ink-strong stood before the heading became blue. */
[data-theme="dark"] .po-hero-ai-highlight strong { color: var(--pa-ai-blue); }
[data-theme="dark"] .po-hero-ai-highlight .po-ai-icon { color: var(--pa-ai-blue); }
/* The three verbs are --pa-ink-muted in light mode, which this sheet retunes
   for the dark ground; naming it here rather than relying on inheritance
   because `div.contentbox li` sets its own colour further up. */
[data-theme="dark"] .po-hero-ai-does li { color: var(--pa-ink-muted); }
[data-theme="dark"] .po-hero-ai-does li::before { background: var(--pa-ai-blue); }
[data-theme="dark"] .po-hero-title .po-hero-ai { color: var(--pa-ai-blue); }
/* The diagram's plate, on the same token .po-step-art takes here - the hero's
   drawing and the three step drawings are the same kind of thing and now sit on
   the same surface in both themes. */
[data-theme="dark"] .po-hero-visual::before { background: var(--pa-surface-quiet); }
[data-theme="dark"] .po-hero-actions .po-btn-quiet {
	color: var(--pa-ink-muted);
	background: transparent;
	border-color: transparent;
}
[data-theme="dark"] .po-hero-actions .po-btn-quiet:hover {
	color: var(--pa-ink-strong);
	background: var(--pa-surface-quiet);
}
[data-theme="dark"] .po-ai-section-body,
[data-theme="dark"] .po-ai-section-body p { color: var(--pa-ink-body); }

/* The hero diagram is inline SVG with its own light fills, drawn to sit on a
   white card. Nudging the three panel plates and their ink is enough; the omic
   swatches and the bwr ramp are data colouring and stay exactly as they are. */
[data-theme="dark"] .po-hero-flow rect[fill="#FFFFFF"] { fill: var(--pa-surface); }
[data-theme="dark"] .po-hero-flow rect[stroke="#E4E4E7"] { stroke: var(--pa-border); }
[data-theme="dark"] .po-hero-flow text[fill="#27272A"] { fill: var(--pa-ink-title); }
[data-theme="dark"] .po-hero-flow text[fill="#3F3F46"] { fill: var(--pa-ink-body); }
[data-theme="dark"] .po-hero-flow text[fill="#71717A"] { fill: var(--pa-ink-label); }

/* Inline "Load example" / "Run PaintOmics" / "Next step" chips inside the help
   prose. These are portraits of real controls, so each one has to be the colour
   its counterpart in the toolbar actually is - and in dark mode neither of them
   was.

   The reason is a specificity tie that only dark mode loses. `.button.btn-success`
   in main.css is (0,2,0); so is `[data-theme="dark"] .button` below, whose whole
   job is to give an untyped button a neutral grey fill. Equal weight, and this
   sheet loads second, so the neutral fill won and every btn-success that is not
   explicitly re-themed came out grey. The toolbar is explicitly re-themed a few
   hundred lines up; these were not. Measured: the real Run PaintOmics drew
   rgb(63,154,63) and its inline portrait rgb(58,59,65) - a grey pill with a
   green outline, next to a sentence telling you to click the green button.

   Load example was wrong the other way and for a plainer reason: main.css pins
   it to a white fill with near-black ink so it matches the light toolbar's ghost
   button, and a pinned literal cannot follow a theme. In dark the real control
   is a dark fill with pale ink and a visible border, so that is what its picture
   is given here.

   The comment this replaces said the fills were "stated inline in PA_Step1Views
   so only the ink needs restating" - true when it was written, and not since the
   paint and AI chips moved their colours out of style attributes and into
   main.css. Those two are still correct in dark without help, but by specificity
   rather than by inlining: `.po-step-card a.button.btn-paint` is (0,3,0) and
   outranks the neutral rule outright. Same shape used here. */
[data-theme="dark"] .button.btn-inline { color: #FFFFFF; }
[data-theme="dark"] .po-step-card a.button.btn-success.btn-inline {
	background-color: var(--pa-btn-success-bg);
	border-color: transparent;
	color: #FFFFFF;
}
[data-theme="dark"] .po-step-card a.button.btn-secondary.btn-inline {
	background-color: var(--pa-btn-default-bg);
	color: var(--pa-btn-default-ink);
	border-color: var(--pa-border-control);
}

/* Step 1's omic selection.
   .availableOmicsBox is in scope, and the note that used to be here said it was
   not. That note was written when the chip was a flat block of --pa-omic-color:
   repainting one of those dark left an unlabelled grey slab, because its ink is
   chosen against the colour rather than against the page. The chip is a tint
   now, and a tint has a base -- so the answer is not to leave it alone but to
   re-base it. Mixed toward #FFFFFF it stayed a near-white slab on a dark page,
   four of them down the left edge; mixed toward this theme's surface at 24% it
   is the same hue at the same job, and the ink follows the theme like any other
   text. The saturated value itself is untouched: it is type-coding shared with
   the pathway diagrams and the legends.

   .omicboxTitle is in scope, and was not before, because it is no longer a
   colour: main.css turned the card's header into a white band with the omic's
   hue as a 5px bar down its edge. The bar is a box-shadow reading
   --pa-omic-color and needs nothing here; the band is a surface like any other
   card header and follows the theme, and its title is near-black ink that had
   nothing left to sit on once it did. */
[data-theme="dark"] .omicSubmittingPanel,
[data-theme="dark"] .omicSummaryContainer {
	background: var(--pa-surface);
	border-color: var(--pa-border);
	color: var(--pa-ink-body);
}
[data-theme="dark"] .availableOmicsBox {
	--pa-omic-tint: 24%;
	--pa-omic-tint-base: var(--pa-surface);
}
/* main.css sets both to #1A1A1A, chosen against a pastel body that this theme
   no longer paints. */
[data-theme="dark"] div.availableOmicsBox h4,
[data-theme="dark"] .availableOmicsBox a {
	color: var(--pa-ink);
}
[data-theme="dark"] .omicbox {
	background: var(--pa-surface);
	border-color: var(--pa-border);
}
[data-theme="dark"] .omicboxTitle {
	background: var(--pa-surface-quiet);
	border-bottom-color: var(--pa-border);
}
[data-theme="dark"] div.omicboxTitle h4,
[data-theme="dark"] .omicboxTitle a { color: var(--pa-ink-title); }

/* Step 1's help panel and the numbered section labels around it are plain prose
   in a box with no class of their own, so they inherit whatever the page gives
   them - which was near-black. */
[data-theme="dark"] .paStep1Form,
[data-theme="dark"] .paStep1Form p,
[data-theme="dark"] .paStep1Form li,
[data-theme="dark"] .paStep1Form label,
[data-theme="dark"] #mainViewCenterPanel .content,
[data-theme="dark"] #mainViewCenterPanel .content p,
[data-theme="dark"] #mainViewCenterPanel .content i,
[data-theme="dark"] #mainViewCenterPanel .content span { color: var(--pa-ink-body); }
[data-theme="dark"] #mainViewCenterPanel .content h5 { color: var(--pa-ink-title); }

/* ---------------------------------------------------------------------------
   7. Prose that has no class of its own

   Step 1's section headings and body copy are bare h3/p inside form boxes, so
   nothing above could reach them by selector and they kept their light-theme
   near-black: measured at 1.58 and 2.21 against the dark page. Scoped to the
   centre panel so the header and the contents rail are not caught by it.
   --------------------------------------------------------------------------- */

[data-theme="dark"] #mainViewCenterPanel h3 { color: var(--pa-ink-title); }
[data-theme="dark"] #mainViewCenterPanel .paStep1Form p,
[data-theme="dark"] #mainViewCenterPanel .po-ai-section p,
[data-theme="dark"] #mainViewCenterPanel .contentbox > p,
[data-theme="dark"] #mainViewCenterPanel .contentbox div > p { color: var(--pa-ink-body); }


/* All three inline `style="color:#555"` / `#666` writers are gone now. The
   Step 1 AI paragraph and the consent notice's fine print became
   .ai-intro-copy and .ai-gdpr-fineprint when the AI surfaces were put on one
   type scale; the last one was PA_Step3Views.js's .paColorLegend, which now
   states its colours in main.css and takes its ink from the theme tokens like
   everything else. The two `[style*=...] { ... !important }` rules that stood
   here existed only because an inline declaration cannot be reached by a
   stylesheet - with nothing left writing one, they had nothing to override.

   The legend's own dark-theme needs are two: its inset hairline is a black
   shadow, invisible on a dark panel, and its zero tick is a black line for the
   same reason. Both are restated against light instead. */
[data-theme="dark"] .paColorLegend-bar { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16); }
[data-theme="dark"] .paColorLegend-tick { background: rgba(255, 255, 255, .55); }

/* And the omic name beside that legend, for the third time on this file's
   terms: main.css sets a bare `h4 { color: #27272A }`, and every card that
   draws an h4 has to answer it here or the heading is inked near-black on a
   near-black panel. Measured on the metabolite hub's node detail card:
   #27272A on #1E1F23 is 1.06:1, which is not dim, it is absent -- the omic's
   name simply was not on the screen in dark mode. */
[data-theme="dark"] .pa-hub-omic h4 { color: var(--pa-ink-label); }

/* ---------------------------------------------------------------------------
   8. Step 1's AI callout

   .po-ai-section-body states `background: linear-gradient(to bottom, #f8faff,
   #f2f6fc)`. The token block above moved its background-COLOUR, but a gradient
   is a background-IMAGE and paints over the colour, so the callout stayed a
   near-white slab on the dark form - the largest bright surface on Step 1 at
   1285x182. Both halves have to be restated, and the border with them: #c8d6e5
   is a light-theme hairline that reads as a highlight here.
   --------------------------------------------------------------------------- */

[data-theme="dark"] .po-ai-section-body {
	background: var(--pa-ai-section-bg);
	border-color: var(--pa-ai-section-border);
}

/* Section 1's panel is the same shape in neutral. Being built out of tokens this
   file already moves is not enough for it, because two blanket rules above reach
   it first and both are right where they were written:

     [data-theme="dark"] .x-container  repaints every ExtJS container with
     --pa-surface, which flattens this panel into the white card it sits on -
     measured, both were rgb(30,31,35) and the section lost its edges entirely;

     [data-theme="dark"] #mainViewCenterPanel .paStep1Form p  gives every
     paragraph on the upload form --pa-ink-body, which un-mutes the two captions
     under the organism field and the note under the databases - three lines that
     are quiet by design in light and were shouting here.

   So the fill, the border and the muted ink are all restated, at the weight it
   takes to win. Same lesson as .po-ai-section-body directly above. */
/* A well, not a plate. --pa-surface-sunken is #232429 and the card under it is
   #1E1F23, so on this theme the "sunken" panel was the lighter of the two and
   sat on the card rather than in it -- and its border, --pa-border at #33353B,
   was lighter than both, which drew a bright ring around all four sides. Read
   together at a rounded corner that is a glow, and the owner read it as a weird
   outer shadow. It is: the light theme's elevation kit (raised fill, hairline,
   soft drop shadow) says "recessed" only when the fill is the darkest thing in
   the stack, which on white it is and here it was not.

   So the panel takes the page's own ground, one clear step below the card, and
   drops both the ring and the 4%-black blur that could not be seen on this
   ground anyway. Nothing is left to draw the edge except the change in value,
   which is what a well is. */
[data-theme="dark"] .po-form-panel {
	background: var(--pa-surface-page);
	border-color: transparent;
	box-shadow: none;
}
/* The same 4%-black blur, on the two AI panels. It is 1/25th of an already
   black shadow over a near-black card: it cannot be seen, and it costs a
   composited layer on every repaint. */
[data-theme="dark"] .po-ai-section-body {
	box-shadow: none;
}
/* And the columns inside all three panels, which were painting over them.

   `[data-theme="dark"] .x-container` (0,2,0) fills every ExtJS container with
   --pa-surface. Each of these panels holds two of them -- the control column
   and the note column -- plus the .x-box-inner the hbox wraps them in, so a
   #1E1F23 rectangle was drawn over the panel's own fill, inset by its padding
   and stopping short of its bottom edge. On Section 1 that reads as a lighter
   block floating inside the well (the owner called it an inner shadow, which is
   exactly what a lighter inset rectangle with a hard edge looks like); on
   Sections 2 and 3 it was quietly painting out the blue that makes them the AI
   surfaces. The panel owns its ground; the containers inside it own none. */
[data-theme="dark"] .po-form-panel .x-container,
[data-theme="dark"] .po-form-panel .x-box-inner,
[data-theme="dark"] .po-ai-section-body .x-container,
[data-theme="dark"] .po-ai-section-body .x-box-inner {
	background-color: transparent;
}
[data-theme="dark"] #mainViewCenterPanel .paStep1Form p.po-db-note {
	color: var(--pa-ink-muted);
}
/* The request pill is a white-on-white surface in light; here the ground is
   dark, so it takes the panel's own surface and the theme's line. The database
   checkboxes need nothing: they are boxes and labels, and both are themed
   already. */
/* `div.contentbox a.po-ghost-action` in main.css is (0,2,2), so a plain
   `[data-theme="dark"] a.po-ghost-action` at (0,2,1) lost to it and the button
   kept a border stated as an alpha of black -- invisible on this ground.
   Transparent rather than a fill: on the dark panel an outline is what an
   optional action looks like. */
[data-theme="dark"] div.contentbox a.po-ghost-action,
[data-theme="dark"] a.po-ghost-action {
	background: transparent;
	border-color: var(--pa-border);
}
[data-theme="dark"] a.po-ghost-action:hover {
	border-color: var(--pa-accent-blue);
	color: var(--pa-accent-blue);
}

/* ---------------------------------------------------------------------------
   9. Step 2

   Two cards on this step are drawn by a sledgehammer in main.css:

       #clusternumber_box div, #clusternumber_box span,
       #threshold_box div, #threshold_box span { background-color: white !important; }

   It exists to flatten ExtJS's widget chrome inside those cards, and because it
   is !important on 34 elements it was the single brightest thing in the whole
   dark build - 2.6M px2 of white. Nothing in this file could reach it: beating
   an !important needs !important, and beating (1,0,1) needs the theme attribute
   to make it (1,1,1). Both are here.

   Because the light rule already forces every one of those descendants white,
   none of them carries a meaningful colour of its own, so mapping the whole set
   to the card surface loses no information.
   --------------------------------------------------------------------------- */

[data-theme="dark"] #clusternumber_box div,
[data-theme="dark"] #clusternumber_box span,
[data-theme="dark"] #threshold_box div,
[data-theme="dark"] #threshold_box span {
	background-color: var(--pa-surface) !important;
}

/* The Step 2 "Multiple databases" table - a white card with near-black ink.
   Its former Step 3 twin (#multisource_summary) is no longer restated here: it
   lives inside the summary band now and its light rules are written on
   --pa-ink-* tokens over a transparent ground, so the token block above is all
   the theming it needs.

   The <dt> database names are included even though they are ink, not surface:
   at #27272A on the dark card they measured 1.4:1, which is the same defect
   seen from the other side. */
[data-theme="dark"] #dbs_message table {
	background-color: var(--pa-surface-sunken);
	border-color: var(--pa-border);
}
[data-theme="dark"] #dbs_message table th {
	background-color: var(--pa-grid-header-bg);
	border-bottom-color: var(--pa-border);
	color: var(--pa-grid-header-ink);
}
[data-theme="dark"] #dbs_message table td {
	border-top-color: var(--pa-border-row);
	color: var(--pa-ink-body);
}
[data-theme="dark"] #dbs_message dt { color: var(--pa-ink-title); }

/* The compound disambiguation cards. main.css inks every bare h4 #27272A and
   this file answers that card by card rather than with a blanket (the
   .paExploreCard note in section 2 says why); the "N compounds found" and
   "N alternative compounds found" counters on these cards were not among the
   answers, so they sat at 1.4:1 on the dark card. Label ink, not body ink:
   they are secondary counts over the checkbox lists that carry the content. */
[data-theme="dark"] .metaboliteBox h4 { color: var(--pa-ink-label); }

/* ---------------------------------------------------------------------------
   10. Highcharts

   The mapped/unmapped donuts and the data-distribution box plots are Highcharts
   SVG. It writes fill="#ffffff" on the backdrop as a presentation attribute,
   which a CSS `fill` outranks, so no chart reconfiguration is needed - eleven
   charts, 54,000 px2 of white each.

   Only the chart's own chrome moves: backdrop, axes, gridlines, labels and the
   box-plot's unfilled box. The donut segments are the mapped/unmapped
   green/red and are left exactly as they are, for the same reason the omic
   fills are: they are the reading, not the frame around it.
   --------------------------------------------------------------------------- */

[data-theme="dark"] .highcharts-background { fill: var(--pa-chart-bg); }
[data-theme="dark"] .highcharts-plot-background { fill: transparent; }
[data-theme="dark"] .highcharts-plot-border,
[data-theme="dark"] .highcharts-axis-line,
[data-theme="dark"] .highcharts-tick { stroke: var(--pa-chart-axis); }
[data-theme="dark"] .highcharts-grid-line { stroke: var(--pa-chart-grid); }
/* Except on a pie. Highcharts draws `.highcharts-plot-border` for every chart
   and leaves it unstroked, so on a chart with axes the rule above turns it into
   the frame the axes hang off - and on the classification pie, which has no
   axes, it turns it into a bare 513x215 rectangle floating around the slices.
   That box is in every dark screenshot of Step 3 and belongs to nothing. */
[data-theme="dark"] div[id ^= "pathwayDistributionsContainer_"] .highcharts-plot-border {
	stroke: none;
}
[data-theme="dark"] .highcharts-axis-labels text,
[data-theme="dark"] .highcharts-legend-item text { fill: var(--pa-chart-ink-soft) !important; }
[data-theme="dark"] .highcharts-axis-title,
[data-theme="dark"] .highcharts-title,
[data-theme="dark"] .highcharts-subtitle { fill: var(--pa-chart-ink) !important; }
/* The box plot's box is drawn white so the median line and whiskers read
   through it; on a dark chart the equivalent is the chart ground, not white. */
[data-theme="dark"] .highcharts-boxplot-box { fill: var(--pa-surface-quiet); }
[data-theme="dark"] .highcharts-plot-line-label { fill: var(--pa-chart-ink-soft); }
[data-theme="dark"] .highcharts-tooltip > span {
	background: var(--pa-surface-quiet) !important;
	color: var(--pa-ink-body) !important;
	border-color: var(--pa-border) !important;
}
/* The classification pie's percentage labels are HTML (useHTML), not SVG text,
   so the fill rules above never touched them. Highcharts writes its drilldown
   default inline on the span - navy #003399, underlined - which was 1.9:1 on
   the dark card and needs !important to beat. Drillable labels take the link
   colour because clicking them is the pie's whole interaction; a drilled-down
   level has nothing further to open and reads as plain chart ink. The
   category badge inside each label keeps its own inline ink and fill (it is
   type-coding, same as the slices), and neither rule reaches it: they colour
   the wrapper span only, and the badge's inline value beats inheritance. */
[data-theme="dark"] div[id^="pathwayDistributionsContainer_"] .highcharts-data-label > span {
	color: var(--pa-chart-ink) !important;
}
[data-theme="dark"] div[id^="pathwayDistributionsContainer_"] .highcharts-drilldown-data-label > span {
	color: var(--pa-link) !important;
}

/* ---------------------------------------------------------------------------
   11. Step 3

   The pathway table, the classification panel and the network view. The network
   surfaces are matched on the id prefix main.css uses, because each one is
   suffixed with the database name at render time.

   Not here, deliberately: the significance cells. Those are written inline as
   rgb(255, tint, tint) with the tint computed from the p-value, and their ink is
   #9B1C1C chosen against that ramp. They are the same kind of thing as the bwr
   scale on the pathway diagrams - the colour IS the result - so they keep their
   values. Nor the classification swatches, which are category type-coding.
   --------------------------------------------------------------------------- */

[data-theme="dark"] .paGridBar {
	background: var(--pa-surface);
	border-color: var(--pa-border);
}
[data-theme="dark"] .paGridBar-filters { background: var(--pa-surface-subtle); }
/* Checkboxes, radios and sliders --------------------------------------------
   main.css draws all four of these in CSS now rather than from sprites, so the
   dark theme has real properties to move instead of an image it could only
   leave alone. Not scoped to this toolbar any more: the same controls fill the
   network's Tools column, the pathway view's settings panel and the upload
   forms, and every one of them was painting a white 16px box on a dark panel.

   The mark inverts as well as the fill. --pa-accent-blue is #6BA8F0 in this
   theme - light, because it has to read as a link on a dark page - and a white
   tick on it is 2.3:1, i.e. invisible at 16px. The tick and the radio's dot are
   drawn in the page colour instead, which is how a filled control is marked on
   every dark UI: the mark is a hole in the fill, not ink on top of it. */
[data-theme="dark"] .x-form-checkbox,
[data-theme="dark"] .x-form-radio,
[data-theme="dark"] div.checkbox:not(.viewbox):not(.nobox) input[type="checkbox"] + label:before,
[data-theme="dark"] div.radio input[type="radio"] + label:before {
	background-color: var(--pa-legacy-field-bg);
	border-color: var(--pa-border-control);
}
[data-theme="dark"] .x-form-checkbox:hover,
[data-theme="dark"] .x-form-radio:hover,
[data-theme="dark"] div.checkbox:not(.viewbox):not(.nobox):hover input[type="checkbox"]:not(:checked) + label:before,
[data-theme="dark"] div.radio:hover input[type="radio"]:not(:checked) + label:before {
	border-color: var(--pa-border-control-hover);
}
[data-theme="dark"] .x-form-cb-checked .x-form-checkbox,
[data-theme="dark"] .x-form-cb-checked .x-form-radio,
[data-theme="dark"] div.checkbox:not(.viewbox):not(.nobox) input[type="checkbox"]:checked + label:before,
[data-theme="dark"] div.radio input[type="radio"]:checked + label:before {
	background-color: var(--pa-accent-blue);
	border-color: var(--pa-accent-blue);
}
[data-theme="dark"] .x-form-cb-checked .x-form-checkbox,
[data-theme="dark"] div.checkbox:not(.viewbox):not(.nobox) input[type="checkbox"]:checked + label:before {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%2317181B' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round' d='M3.6 8.4l2.9 2.9 5.9-6.3'/%3E%3C/svg%3E");
}
[data-theme="dark"] .x-form-cb-checked .x-form-radio,
[data-theme="dark"] div.radio input[type="radio"]:checked + label:before {
	box-shadow: inset 0 0 0 3.5px #17181B;
}
/* The slider's unfilled track. Its filled portion and its thumb border are
   --pa-accent-blue, which this theme already moves; only the groove behind
   them was a light-theme literal. */
[data-theme="dark"] .slider-ui.ui-slider,
[data-theme="dark"] .ui-slider-horizontal {
	background: var(--pa-border-control);
}
/* The thumb's own fill is set by the .ui-state-default block further down this
   file, which is later and therefore wins; it is left as the one place that
   describes a jQuery UI thumb. */
[data-theme="dark"] .paGridBar a.downloadXLS:hover,
[data-theme="dark"] .paGridBar #configureButton:not(.x-item-disabled):hover {
	background-color: var(--pa-surface-quiet);
}
[data-theme="dark"] .paGridBar a.multiDelete:hover { background-color: var(--pa-btn-ghost-danger-bg-hover); }
[data-theme="dark"] .paWeightsTip { background-color: var(--pa-surface); }
[data-theme="dark"] .paWeightsTip .x-tip-header,
[data-theme="dark"] .paWeightsTip .x-tip-header-default { background: var(--pa-surface-quiet); }

/* The details table lost its zebra (main.css: hairline separators carry the
   structure now, in .pa-details-table tokens that dark redefines), so the
   even-row repaint that mirrored it is gone too. */
/* Disabled classification chips grey out to #E8E8E8 with !important. */
[data-theme="dark"] .step3ClassificationsTitle.disabled > i.classificationNameBox {
	background-color: var(--pa-surface-quiet) !important;
}

[data-theme="dark"] div[id ^= "pathwayNetworkBox_"].fullscreen { background-color: var(--pa-surface-page); }
[data-theme="dark"] div[id ^= "pathwayNetworkWaitBox_"] { background-color: rgba(23, 24, 27, 0.76); }
[data-theme="dark"] span.networkClusterImage > i { background-color: rgba(30, 31, 35, 0.54); }
[data-theme="dark"] span.networkClusterImage.networkAICluster:hover { background-color: rgba(255, 255, 255, 0.06); }
/* The network toolbar, its status line and its two popovers used to need three
   translucent literals here because main.css painted them with
   `rgba(255,255,255,.91)`. They are stated in tokens now - see
   network-views.css, which describes this bar and the MORE network's together -
   so the only thing left to say in dark is the one !important the reorder
   popover carries in main.css, and the toolbar controls' ink.

   The ink needs saying because the pathways toolbar builds its controls out of
   `<a>`, and `[data-theme="dark"] a` up at the top of this file is (0,1,1) to
   `.pa-net-tool`'s (0,1,0) - so in dark mode every control in the strip came
   out link-blue and turned green under the cursor, while the identical
   `<button>`s in the MORE toolbar stayed neutral. Two toolbars, same design,
   different colours, for no reason but the element each was built from. */
[data-theme="dark"] .pa-net-toolbar .pa-net-tool { color: var(--pa-ink-control); }
[data-theme="dark"] .pa-net-toolbar .pa-net-tool:hover,
[data-theme="dark"] .pa-net-toolbar .pa-net-tool:focus { color: var(--pa-ink-strong); }
[data-theme="dark"] div[id ^= "step3-network-toolbar_"] div[id ^= "reorderOptions"] {
	background: var(--pa-surface) !important;
}

/* ---------------------------------------------------------------------------
   12. Step 4

   The pathway view. Its two side panels share .lateralOptionsPanel, but only
   one of them was dark: the information panel is an .x-container and so was
   caught by the ExtJS block above, while the diagram viewport is an
   .x-component and was not - main.css's `.lateralOptionsPanel { background:
   #fff }` was left standing over the whole 1039x656 viewport and its header.
   Measured on the rendered page, that one element was 3,093 of the 3,561
   bright samples on this screen.

   The KEGG and Reactome artwork inside it still has a white canvas, and still
   should: it is opaque - verified by painting the viewport behind it and
   watching only the margins change - so it now reads as a light diagram laid on
   a dark desk, which is what it is.

   The header's fill is restated without !important on purpose. The information
   panel carries its teal inline, and an inline declaration outranks this, so
   the coloured header keeps its colour while the plain one goes dark. */

[data-theme="dark"] .lateralOptionsPanel { background: var(--pa-surface); }
[data-theme="dark"] .lateralOptionsPanel-header {
	background: var(--pa-surface-quiet);
	border-bottom-color: var(--pa-border);
}
[data-theme="dark"] .lateralOptionsPanel-header h2 { color: var(--pa-ink-title); }
[data-theme="dark"] div.lateralOptionsPanel-header .toolbarOption.downloadTool {
	background: var(--pa-btn-default-bg);
	border-color: var(--pa-border-control);
	color: var(--pa-btn-default-ink);
}
[data-theme="dark"] div.lateralOptionsPanel-header .toolbarOption.downloadTool:hover {
	background: var(--pa-btn-default-bg-hover);
}
[data-theme="dark"] div.lateralOptionsPanel input[type="text"]:not([id^=numberfield]) {
	background-color: var(--pa-legacy-field-bg);
	border-color: var(--pa-legacy-field-border);
	color: var(--pa-ink-body);
}
[data-theme="dark"] .lateralOptionsSelector.omicSelection {
	background: var(--pa-surface-sunken);
	border-color: var(--pa-border);
}
[data-theme="dark"] .globalHeatmapConfigurator {
	background: var(--pa-surface-sunken);
	border-color: var(--pa-border);
}
[data-theme="dark"] div.lateralOptionsPanel div.updateMessageContainer {
	background: var(--pa-toast-warning-bg);
	border-color: var(--pa-toast-warning-border);
	color: var(--pa-ink-body);
}
[data-theme="dark"] div.lateralOptionsPanel div.updateMessageContainer h3 { color: var(--pa-ink-title); }
[data-theme="dark"] .step4PathwayThumbnailHover { background-color: rgba(23, 24, 27, 0.67); }
[data-theme="dark"] td.whiteBackground { background: var(--pa-surface); }
/* The Heatmap/Line-chart and Genes/Metagenes segmented control (twoOptionsButton,
   main.css) is built entirely from surface and ink tokens now, so it themes
   itself - no dark override needed here any more. */

/* ---------------------------------------------------------------------------
   13. Controls and widgets that appear on more than one step
   --------------------------------------------------------------------------- */

/* The base .button, which had no dark rule at all - and worse, was being
   actively repainted by the wrong one.

   Every one of these buttons is an <a>, and `[data-theme="dark"] a` in section
   5 is (0,1,1): one attribute selector plus one type selector. `.button` in
   main.css is (0,1,0). So the link colour won, and a dark-mode .button drew
   its label in link blue (#6BB6FF) on the grey fill (#5b5a59) - about 3.2:1,
   under AA for 14px text. On hover it was worse: `a:hover` at (0,2,1) beat
   `.button:hover` at (0,2,0), giving link-hover green on the hover fill,
   about 2.5:1.

   The fix belongs here rather than in section 5's `a` rule, which is correct
   for actual links. These selectors are (0,2,0) and (0,3,0), which outrank the
   link rules on the b component without needing !important. */
[data-theme="dark"] .button {
	background-color: var(--pa-btn-neutral-bg);
	color: var(--pa-btn-neutral-ink);
}
[data-theme="dark"] .button:hover {
	background-color: var(--pa-btn-neutral-bg-hover);
	color: #ffffff;
}
[data-theme="dark"] .button.btn-primary {
	background-color: var(--pa-btn-primary-bg);
	border-color: var(--pa-btn-primary-border);
	color: #ffffff;
}
[data-theme="dark"] .button.btn-primary:hover {
	background-color: var(--pa-btn-primary-bg-hover);
	border-color: var(--pa-btn-primary-border-hover);
	color: #ffffff;
}
[data-theme="dark"] .button.acceptButton {
	background-color: var(--pa-btn-success-bg);
	border-color: var(--pa-btn-success-border);
	color: #ffffff;
}
[data-theme="dark"] .button.acceptButton:hover {
	background-color: var(--pa-btn-success-bg-hover);
	border-color: var(--pa-btn-success-border-hover);
	color: #ffffff;
}

/* .btn-default is white-on-outline in light mode, so in dark it needs the
   border as well as the fill - without it the button is a dark rectangle with
   no boundary against the dialog, which is the WCAG 1.4.11 failure the light
   theme's #878787 outline exists to avoid. */
[data-theme="dark"] .btn-default {
	background-color: var(--pa-btn-default-bg);
	color: var(--pa-btn-default-ink);
	border-color: var(--pa-border-control);
}
[data-theme="dark"] .btn-default:hover {
	background-color: var(--pa-btn-default-bg-hover);
	border-color: var(--pa-border-control-hover);
}

/* The sign-in dialog's validation line. main.css states it as #D22, which is
   4.51:1 on white but only about 3.4:1 on the dark panel. */
[data-theme="dark"] .formMessage { color: var(--pa-status-error-ink); }

/* The rule that divides the sign-in panel's two columns. It was an inline
   `border-left: 1px solid #E7E7E7` on three separate divs, which no stylesheet
   could reach, so a near-white hairline survived into dark mode. */
[data-theme="dark"] .signInColumnDivider { border-left-color: var(--pa-border); }

/* Step 1's white pill buttons - the "Browse..." split buttons on every omic
   card. main.css claims them at (0,3,1), so the generic button rules in section
   3 lost to it and these were among the last white surfaces left on Step 1. The
   selectors below mirror main.css's exactly and add the theme attribute, which
   is the smallest change that wins.

   The split arrow is drawn as a CSS triangle rather than taken from the Neptune
   sprite (see main.css), so it does not follow the button fill and has to be
   restated with it - otherwise it stays #71717A on a dark pill. */
[data-theme="dark"] .omicbox a.x-btn.x-btn-default-small {
	background-color: var(--pa-btn-default-bg);
	background-image: none;
	border-color: var(--pa-border-control);
}
[data-theme="dark"] .omicbox a.x-btn.x-btn-default-small:hover {
	background-color: var(--pa-btn-default-bg-hover);
	border-color: var(--pa-border-control-hover);
}
[data-theme="dark"] .omicbox a.x-btn .x-btn-inner { color: var(--pa-btn-default-ink); }
[data-theme="dark"] .omicbox a.x-btn .x-btn-wrap::after { border-top-color: var(--pa-ink-label); }
[data-theme="dark"] .omicbox a.x-btn .x-btn-wrap::before { border-left-color: var(--pa-border-control); }
[data-theme="dark"] .fieldBox,
[data-theme="dark"] .container { background-color: var(--pa-surface); }
[data-theme="dark"] .dragHerePanel {
	background: var(--pa-surface-sunken);
	border-color: var(--pa-border);
}
[data-theme="dark"] span.currentStep { background: var(--pa-surface-quiet); }
[data-theme="dark"] select {
	background: var(--pa-legacy-field-bg);
	color: var(--pa-legacy-field-ink);
	border-color: var(--pa-legacy-field-border);
}
[data-theme="dark"] .sigma-tooltip {
	background-color: var(--pa-surface-quiet);
	color: var(--pa-ink-body);
	border-color: var(--pa-border);
}
[data-theme="dark"] .invalid-cell { background-color: var(--pa-invalid-bg) !important; }
[data-theme="dark"] .x-grid-row-editor { background: var(--pa-surface-quiet); }
[data-theme="dark"] .x-trigger-cell { background-color: var(--pa-legacy-field-bg); }
/* The combobox arrow and the number-field spinners. Only the fill moves - the
   glyphs come from ExtJS's spinner/trigger sprites, which are mid-grey on
   transparent and stay legible on the field ground (checked on a rendered
   spinner at 5x rather than assumed). */
[data-theme="dark"] .x-form-trigger { background-color: var(--pa-legacy-field-bg); }
[data-theme="dark"] #warningMessage {
	background: var(--pa-toast-warning-bg);
	border-color: var(--pa-toast-warning-border);
	color: var(--pa-ink-body);
}
[data-theme="dark"] .repDetectionWarn {
	background: var(--pa-toast-warning-bg);
	border-color: var(--pa-toast-warning-border);
}
[data-theme="dark"] .repDetectionPreview,
[data-theme="dark"] .repDetectionManual { background: var(--pa-surface-sunken); }
[data-theme="dark"] .paProgressTrack { background-color: var(--pa-ai-progress-track); }
[data-theme="dark"] .dropdown-menu a { background: var(--pa-surface-quiet); }
[data-theme="dark"] .pa-toc-list::-webkit-scrollbar-thumb { background: var(--pa-border-control); }
/* jQuery UI ships a light texture as a background-image, so the colour alone
   does not cover it. Used by the autocomplete menu on the search fields. */
[data-theme="dark"] ul.ui-menu.ui-widget.ui-widget-content,
[data-theme="dark"] .ui-widget-content {
	background: var(--pa-surface) !important;
	background-image: none !important;
	border-color: var(--pa-border);
	color: var(--pa-ink-body);
}
[data-theme="dark"] .ui-menu .ui-menu-item:hover,
[data-theme="dark"] .ui-menu .ui-state-active { background: var(--pa-surface-quiet); }
/* The network view's sliders. Their thumbs are jQuery UI's .ui-state-default,
   a near-white fill plus a texture image, which left a row of white blobs down
   the settings column. Doubling the class beats jQuery UI's own
   `.ui-widget-content .ui-state-default` without reaching for !important. */
[data-theme="dark"] .ui-slider-handle.ui-state-default,
[data-theme="dark"] .ui-widget-content .ui-slider-handle.ui-state-default {
	background: var(--pa-btn-default-bg);
	background-image: none;
	border-color: var(--pa-border-control);
}
[data-theme="dark"] .ui-slider-handle.ui-state-hover,
[data-theme="dark"] .ui-slider-handle.ui-state-active,
[data-theme="dark"] .ui-widget-content .ui-slider-handle.ui-state-hover,
[data-theme="dark"] .ui-widget-content .ui-slider-handle.ui-state-active {
	background: var(--pa-btn-default-bg-hover);
	background-image: none;
	border-color: var(--pa-border-control-hover);
}

/* ---------------------------------------------------------------------------
   14. AI interpretation surfaces that state their own light fills
   --------------------------------------------------------------------------- */

[data-theme="dark"] .ai-widget-progress {
	background: var(--pa-ai-progress-bg);
	color: var(--pa-ai-progress-ink);
}
[data-theme="dark"] .ai-widget-progress.is-done { background: var(--pa-toast-success-bg); }
[data-theme="dark"] .ai-widget-progress.is-error { background: var(--pa-toast-error-bg); }
[data-theme="dark"] .ai-citation-item:hover { background: var(--pa-surface-quiet); }
[data-theme="dark"] .ai-send-btn:disabled { background: var(--pa-btn-neutral-bg); }
[data-theme="dark"] .ai-gdpr-disclaimer {
	background: var(--pa-surface);
	border-color: var(--pa-border);
	color: var(--pa-ink-body);
}
[data-theme="dark"] .ai-gdpr-disclaimer-header { background: var(--pa-surface-quiet); }
/* The notice's own title. Its body text inherits from .ai-gdpr-disclaimer,
   which this file restates, but the title carries `color: #333` of its own,
   which inherits from nothing - 1.10:1 on the header lightened just above. */
[data-theme="dark"] .ai-gdpr-disclaimer-header strong { color: var(--pa-ink-title); }

/* The provenance blocks in the AI privacy notice. main.css tints them
   #eef4fb, which is a near-white panel on the dark disclaimer surface. The
   inline variant needs no rule: it has no colour of its own. */
[data-theme="dark"] .ai-gdpr-where,
[data-theme="dark"] .ai-gdpr-transfer {
	background: var(--pa-surface-quiet);
	border-left-color: var(--pa-accent-blue);
}

/* The disclosure lists in the AI privacy notice. Their fills were inline until
   now, so the dark theme could not reach them: it lightened the notice's body
   ink to #C9CBD0 and left the fills at #fff3e0 / #e8f5e9, which measured
   1.48:1 and 1.44:1 in the browser - the two paragraphs that say what leaves
   the server were the only unreadable thing in the dialog.

   Dark fills derived the same way as the toast tokens: the hue held, the
   lightness dropped under the body ink rather than a grey substituted, so the
   warn/safe pairing still reads as warn and safe. */
[data-theme="dark"] .ai-gdpr-sent {
	background: var(--pa-toast-warning-bg);
	border-left-color: var(--pa-status-warning);
}
[data-theme="dark"] .ai-gdpr-notsent {
	background: var(--pa-toast-success-bg);
	border-left-color: var(--pa-status-success);
}
[data-theme="dark"] .ai-gdpr-sent-title { color: var(--pa-status-warning-ink); }
[data-theme="dark"] .ai-gdpr-notsent-title { color: var(--pa-status-success-ink); }
/* The consent checkbox's warning ink. --pa-ai-consent-warn was declared for
   this and had nothing to apply to until the colour stopped being an inline
   style on the boxLabel; #F08A5D is 6.66:1 on the surface underneath, against
   the 3.29:1 the light-theme #C44500 was managing there. This is the sentence
   naming the recipient of the data, so it has to be read, not decoded. */
[data-theme="dark"] .ai-consent-warn {
	color: var(--pa-ai-consent-warn);
}
/* The privacy link on the dark surface. */
[data-theme="dark"] .ai-gdpr-info-link { color: var(--pa-ink-muted); }
[data-theme="dark"] .ai-gdpr-info-link:hover { color: var(--pa-accent-blue); }

/* The account dialog. main.css states its surface literally (so that the
   framework's #f2f2f2 panel fill loses), which means it is restated here.
   --pa-surface-sunken rather than --pa-surface: this file has no overlay
   surface token, and a modal wants to sit a step off the page rather than
   match it exactly. #232429 against the #17181B page is the same separation
   the cards get, and the scrim underneath does the rest of the lifting. */
[data-theme="dark"] .userViewsDialog,
[data-theme="dark"] .userViewsDialog .x-window-body {
	background-color: var(--pa-surface-sunken);
}
[data-theme="dark"] .userViewsDialog .x-form-item-label,
[data-theme="dark"] .userViewsDialog .x-form-item-label-inner {
	color: var(--pa-ink-body);
}
/* The rest of the modernised account dialog. Every value below is a literal in
   main.css - chosen against a white dialog - so none of them carry, and a
   `--pa-*` fallback cannot rescue a colour that was never a token. Measured on
   the rendered dialog: "Data protection" at #3F3F46 on the #232429 surface is
   1.17:1, i.e. a label you cannot see at all. */
[data-theme="dark"] .po-auth-terms-label {
	color: var(--pa-ink-body);
}
[data-theme="dark"] .po-pass-toggle {
	color: var(--pa-ink-soft);
}
[data-theme="dark"] .po-pass-toggle:hover {
	color: var(--pa-ink);
	background: var(--pa-surface-quiet);
}
/* The confirmation glyph - "Check your inbox", "Password changed". The light
   wash is a 10% tint of the light theme's green mixed against white, which
   over a dark card reads as a muddy brown ring rather than a tile. */
[data-theme="dark"] .po-auth-notice-icon {
	color: var(--pa-accent-green);
	background: rgba(107, 196, 106, 0.14);
}
/* The sign-in dialog's second column. `.signInColumnDivider` is restated
   further up this file for the plain hairline the guest and no-login panels
   still use; inside the dialog it is a panel, so it needs a surface. Its
   heading needs nothing here - `.userViewsDialog h2` already takes
   --pa-ink-title, which this file redefines. */
[data-theme="dark"] .po-auth-aside .signInColumnDivider {
	background: var(--pa-surface-quiet);
	border-color: var(--pa-border);
}
[data-theme="dark"] .userViewsDialog .x-form-text:hover {
	border-color: var(--pa-border-control-hover) !important;
}
[data-theme="dark"] .po-exp-design-hint,
[data-theme="dark"] .po-exp-design-draft-note {
	color: var(--pa-ink-muted);
}
/* The failure line, restated because the rule above would otherwise swallow it.

   main.css says `.po-exp-design-draft-note.is-error` and reaches
   --pa-ai-consent-warn through var(), which this file redefines -- so the
   colour was right and the selector still lost. Both are (0,2,0): two classes
   against one attribute plus one class. Equal specificity is decided by order,
   dark.css is loaded after main.css in index.html, and the muted grey won.
   Measured in the browser: rgb(139,142,150) where #F08A5D was expected, on the
   one line in this control that reports a failure. */
[data-theme="dark"] .po-exp-design-draft-note.is-error {
	color: var(--pa-ai-consent-warn);
}

/* Personal storage. main.css states the account and storage surfaces with
   literal hexes as fallbacks, so the ink is restated here; the meter track and
   its three status fills are stated too, because the light values were chosen
   against white and none of them carry to a dark card. The fills come from
   this file's own status ramp, which is already lightened for a dark ground. */
[data-theme="dark"] .po-account dd,
[data-theme="dark"] .po-storage-used,
[data-theme="dark"] .po-stat-value {
	color: var(--pa-ink-title);
}
[data-theme="dark"] .po-storage-unit {
	color: var(--pa-ink-body);
}
[data-theme="dark"] .po-storage-track {
	background: var(--pa-surface-quiet);
}
[data-theme="dark"] .po-storage-fill.is-ok       { background: var(--pa-status-success); }
[data-theme="dark"] .po-storage-fill.is-warning  { background: var(--pa-status-warning); }
[data-theme="dark"] .po-storage-fill.is-critical { background: var(--pa-status-error); }

/* Pathways summary counts. The glyph colours already follow --pa-accent-*,
   which this file redefines, so only the washes behind them are restated: they
   are literal rgba in main.css, mixed against white, and a 12% tint of the
   light accent goes muddy on a dark card rather than reading as a tile. Stated
   from the dark accents at a slightly higher alpha, because a wash needs more
   weight to separate from a dark ground than from a white one. */
[data-theme="dark"] .po-pathway-icon {
	background: rgba(107, 168, 240, 0.18);
}
[data-theme="dark"] .po-pathway-icon.is-significant {
	background: rgba(227, 138, 90, 0.18);
}
[data-theme="dark"] .po-pathway-count {
	color: var(--pa-ink-title);
}
[data-theme="dark"] .po-pathway-label {
	color: var(--pa-ink-body);
}
/* The summary band's heading strip carries the card-heading treatment (white
   fill, hairline) on a wrapper row rather than on the h2 itself - see "The
   summary band" in main.css - so the same move `div.contentbox h2` makes
   above is restated for the row here, and the h2 inside it stays transparent
   against the dark heading rule, which outscores the light transparent one. */
[data-theme="dark"] .po-band-head {
	background-color: var(--pa-surface);
	border-bottom-color: var(--pa-border);
}
[data-theme="dark"] .po-band-card .po-band-head h2 {
	background: transparent;
}
/* The job chip's fill is --pa-surface-subtle in the light theme; this file
   redefines that token to within two points of the card it sits on, so the
   chip would arrive as an empty outline. --pa-surface-sunken is the token for
   a well within a surface. The ID inside it opts back out of the blanket
   `[data-theme="dark"] b` blue - it is an identifier, not emphasis - and the
   glyph buttons' hover wash is restated from the dark accent, same as the
   .po-pathway-icon tiles above. */
[data-theme="dark"] .po-job-chip {
	background: var(--pa-surface-sunken);
}
[data-theme="dark"] .po-job-chip > b {
	color: var(--pa-ink-title);
}
[data-theme="dark"] .po-job-chip > a:hover {
	background: rgba(107, 168, 240, 0.18);
}

/* ---------------------------------------------------------------------------
   The second- and third-level surfaces

   Everything below is the dark counterpart of the level-2/3 pass in main.css:
   the side panels' type scale, the in-panel toolbars, the example picker and
   the two overlays. The pattern is the one this file uses throughout - main.css
   states the light value as a literal because it was measured against a white
   card, and the same role is restated here from a token.
   --------------------------------------------------------------------------- */

/* Side-panel headings. `div.lateralOptionsPanel h4/h5` are near-black literals,
   which on a #1E1F23 panel measure about 1.2:1 - the settings columns' control
   labels were effectively invisible. The group label above them already reads
   --pa-ink-muted and needs nothing, but it has to be restated after the general
   rule for the same source-order reason main.css gives. */
[data-theme="dark"] div.lateralOptionsPanel h4,
[data-theme="dark"] div.lateralOptionsPanel h5,
/* The MORE network's rail shares those two rules in main.css, so it inherits
   the same near-black literal and the same problem here. Measured before this
   line: "Condition", "R² ≥", "|coef| ≥" and "Edges" were #27272A on the dark
   rail, while the readouts beside them - which resolve through --pa-ink - were
   legible, so each filter showed its value and not its name. */
[data-theme="dark"] .more-net-side .more-net-field-label { color: var(--pa-ink-title); }
[data-theme="dark"] div.paSettingsPanel h4,
[data-theme="dark"] .more-net-side h6 { color: var(--pa-ink-muted); }
[data-theme="dark"] .lateralOptionsPanel-header { background: var(--pa-surface); }

/* In-panel toolbars: the network strip, the two download chips and the ✕ that
   hides a side panel. Their neutral ink and their hover wash are both stated
   against a white card in main.css - a 6% black wash is invisible on a dark
   panel, so the hover inverts to a light one. */
[data-theme="dark"] div.contentbox a.toolbarOption { color: var(--pa-ink-label); }
[data-theme="dark"] div.contentbox a.toolbarOption:hover,
[data-theme="dark"] .lateralOptionsPanel-toolbar .toolbarOption.hideOption:hover {
	color: var(--pa-ink-title);
	background-color: rgba(255, 255, 255, 0.08);
}
[data-theme="dark"] .lateralOptionsPanel-toolbar .toolbarOption.hideOption { color: var(--pa-ink-muted); }
[data-theme="dark"] .lateralOptionsPanel-toolbar .toolbarOption.downloadTool {
	background: var(--pa-btn-default-bg);
	border-color: var(--pa-border-control);
	color: var(--pa-btn-default-ink);
}
[data-theme="dark"] .lateralOptionsPanel-toolbar .toolbarOption.downloadTool:hover {
	background: var(--pa-btn-default-bg-hover);
	border-color: var(--pa-border-control-hover);
}
/* The network strip is described in tokens in network-views.css and needs no
   dark counterpart; only the veil that covers the diagram while it lays out
   does. */
[data-theme="dark"] div[id ^= "pathwayNetworkWaitBox_"] {
	background-color: rgba(23, 24, 27, 0.76);
}

/* Step 1's help note and the omic column titles. */
/* The information note, in all three places it is now drawn: the Help panel at
   the bottom of the form and the two column notes in Sections 1 and 2. The
   surface and the border are tokens, but the label is not -- main.css states it
   as #27272A, chosen against that panel's near-white fill, and on this ground it
   measured 1.1:1 against the note behind it. Invisible, not merely dim. */
/* The note is a hairline and its prose now, not a filled card (see main.css),
   so only the line needs the theme's own colour -- an alpha of black would be a
   shadow on this ground rather than a rule. */
[data-theme="dark"] #additionalInfoContainer div.content,
[data-theme="dark"] .po-info-note {
	background: none;
}
[data-theme="dark"] #additionalInfoContainer div.content h5,
[data-theme="dark"] .po-info-note h5 { color: var(--pa-ink-title); }

/* The example picker. All new markup, so none of it was reachable before. */
[data-theme="dark"] .po-example {
	background: var(--pa-surface);
	border-color: var(--pa-border);
}
[data-theme="dark"] .po-example:hover { border-color: var(--pa-border-hover); }
[data-theme="dark"] .po-example-title { color: var(--pa-ink-title); }
[data-theme="dark"] .po-example-tests { border-top-color: var(--pa-border); }
[data-theme="dark"] .po-example-dot { color: var(--pa-border-control); }
/* The two badges are 8%-ish tints mixed against white in main.css. Same hues,
   restated as washes over the dark card. */
[data-theme="dark"] .po-example-badge-sim {
	background: rgba(107, 168, 240, 0.18);
	color: var(--pa-accent-blue);
}
[data-theme="dark"] .po-example-badge-real {
	background: rgba(227, 138, 90, 0.18);
	color: var(--pa-accent-orange);
}
[data-theme="dark"] .po-example-badge-default {
	background: var(--pa-surface-quiet);
	color: var(--pa-ink-muted);
}

/* The AI conversion sheet and the Step 1 upload strips. The sheet declares
   its own tints as --cv-* custom properties (inputconvert.css), so one block
   restates them; everything else in it already reads the tokens above. */
[data-theme="dark"] .pa-convert-panel {
  --cv-line: rgba(255, 255, 255, 0.09);
  --cv-line-strong: rgba(255, 255, 255, 0.17);
  --cv-ai-bg: #1B2431;
  --cv-ai-line: #2C3E55;
  --cv-ai-tint: #243247;
  --cv-ok-bg: #182619;
  --cv-ok-line: rgba(107, 196, 106, 0.35);
  --cv-warn-bg: #2A2118;
  --cv-warn-line: rgba(227, 138, 90, 0.35);
  --cv-bad: #F28B82;
  --cv-bad-ink: #F6B1AB;
  --cv-bad-bg: #2E1B1B;
  --cv-bad-line: rgba(242, 139, 130, 0.35);
  box-shadow: -24px 0 60px -20px rgba(0, 0, 0, 0.7);
}
[data-theme="dark"] .pa-convert-overlay.pa-convert-open { background: rgba(0, 0, 0, 0.62); }
[data-theme="dark"] .pa-convert-col-numeric { color: #B9CCE6; }
[data-theme="dark"] .pa-convert-kept .pa-convert-chip { color: #A8DDA6; }
[data-theme="dark"] .pa-convert-preview th { background: rgba(255, 255, 255, 0.05); }
[data-theme="dark"] .pa-convert-accept { background: #2F7A2F; border-color: #3E9A3E; }
[data-theme="dark"] .pa-convert-accept:hover { background: #358A35; }
[data-theme="dark"] .pa-convert-composer-send { background: var(--pa-accent-blue); border-color: var(--pa-accent-blue); color: #0F1A2B; }
[data-theme="dark"] .pa-convert-composer-send:hover:not(:disabled) { background: #86B8F4; }
[data-theme="dark"] .pa-convert-composer-input:focus { box-shadow: 0 0 0 3px rgba(107, 168, 240, 0.25); }

/* Class activity map. Re-stepped for the dark surface rather than inverted:
   the light blue/red pair drops below 3:1 against #151D26. */
:root[data-theme="dark"] .paClassMapBand { fill: #1B242E; }
:root[data-theme="dark"] .paClassMapGrid { stroke: #28333F; }
:root[data-theme="dark"] .paClassMapDisc { fill: #35424F; stroke: #151D26; }
:root[data-theme="dark"] .paClassMapUp { fill: #4A8CD2; stroke: #151D26; }
:root[data-theme="dark"] .paClassMapDown { fill: #C9524D; stroke: #151D26; }
:root[data-theme="dark"] .paClassMapNeutral { fill: #7C93AD; stroke: #151D26; }
:root[data-theme="dark"] .paClassMapRing { stroke: #E3EAF2; }
:root[data-theme="dark"] .paClassMapSigLine { stroke: #B8892B; }
:root[data-theme="dark"] .paClassMapSigLabel { fill: #B8892B; }
:root[data-theme="dark"] .paClassMapTick,
:root[data-theme="dark"] .paClassMapAxis { fill: #8A99A9; }
:root[data-theme="dark"] .paClassMapLabel { fill: #E3EAF2; }
:root[data-theme="dark"] .paClassMapCount { fill: #A1B0C0; }
:root[data-theme="dark"] .paClassMapSummary,
:root[data-theme="dark"] .paClassMapWarn { color: #C9524D; }
:root[data-theme="dark"] .paClassMapMuted { color: #6F7F8E; }
:root[data-theme="dark"] .paKeyUp { background: #4A8CD2; }
:root[data-theme="dark"] .paKeyDown { background: #C9524D; }
:root[data-theme="dark"] .paKeyNeutral { background: #7C93AD; }
:root[data-theme="dark"] .paKeyNull { background: #35424F; }
:root[data-theme="dark"] .paKeyArea { background: #35424F; }
:root[data-theme="dark"] .paClassMapKeys li.paKeyBreak { border-left-color: #28333F; }
:root[data-theme="dark"] .paKeyRing { border-color: #E3EAF2; }
:root[data-theme="dark"] .paClassMapKeys { color: #A1B0C0; }

:root[data-theme="dark"] .paClassMapControlLabel,
:root[data-theme="dark"] .paClassMapControlNote { color: #6F7F8E; }
:root[data-theme="dark"] .paClassMapSummary.paIsFocused { color: #E3EAF2; }
:root[data-theme="dark"] .paDirUp { color: #4A8CD2; }
:root[data-theme="dark"] .paDirDown { color: #C9524D; }
:root[data-theme="dark"] .paClassMapSelect { background: #1D2731; border-color: #3A4756; color: #E3EAF2; }
:root[data-theme="dark"] .paClassMapMark:hover .paClassRankHit { fill: #1B242E; }
:root[data-theme="dark"] .paClassMapMark.paIsSelected .paClassRankHit { fill: #1E2A38; }
:root[data-theme="dark"] .paClassRankHead,
:root[data-theme="dark"] .paClassMapParent,
:root[data-theme="dark"] .paClassRankFdr { fill: #8A99A9; }
:root[data-theme="dark"] .paClassRankFdr.paIsSig { fill: #E3EAF2; }
:root[data-theme="dark"] .paClassRankStem { stroke: #7C93AD; }
:root[data-theme="dark"] .paClassRankStemBelow { stroke: #35424F; }
:root[data-theme="dark"] .paClassRankDot { fill: #E3EAF2; stroke: #151D26; }
:root[data-theme="dark"] .paClassDetail.paIsOpen { border-top-color: #28333F; }
:root[data-theme="dark"] .paClassDetailHead h4 { color: #E3EAF2; }
:root[data-theme="dark"] .paClassDetailStats,
:root[data-theme="dark"] .paClassDetailScale,
:root[data-theme="dark"] .paClassDetailClose { color: #8A99A9; }
:root[data-theme="dark"] .paClassDetailTools { color: #A1B0C0; }
:root[data-theme="dark"] .paClassDetailClose:hover { color: #E3EAF2; }
