This is what I use for cross platform dark theme detection.
I'm comparing the colors clWindow and clWindowText, since these system colors change perfectly as it is, and they typically should contrast to keep things readable. So it doesn't use any system specific calls.
So far it has worked very reliable under macOS and Linux - please correct me if I'm wrong or if there is an even easier way to do this. 😊 
 
// t4a_IsThisDarkTheme: Detects if the Dark Theme (true) has been enabled or not (false)
function t4a_ThisIsDarkTheme:boolean;
begin
  Result := t4a_ColorToGrayScale(clWindow) < t4a_ColorToGrayScale(clWindowText); // guess dark theme
end;
{ Convert a color to grayscale, observing perception }
function t4a_ColorToGrayScale(aColor:TColor):TColor;
var
  GreyNumber:integer;
begin
  Result:=ColorToRGB(aColor);
  // Convert Color to Grayscale if not yet Grayscale
  // Grayscale   = (0.3 * Red) + (0.59 * Green) + (0.11 * Blue)
  // Alternative = (0.2126 * Red) + (0.7152 * Green) + (0.0722 * Blue)
  if (Red(Result)<>Green(Result)) and (Red(Result)<>Blue(Result)) then
    begin
      GreyNumber:= ( ( MathRound(Red(Result)   * 0.3) +
                       MathRound(Green(Result) * 0.59) +
                       MathRound(Blue(Result)  * 0.11) )  div 3);
      if GreyNumber<0 then
        GreyNumber:=0
      else if GreyNumber>255 then
        GreyNumber:=255;
      Result:=RGBToColor(GreyNumber,GreyNumber,GreyNumber);
    end;
end; 
 
And I place the detection in the Form.OnPaint event, since this seems to get fired each time a theme changes, so my applications can respond to a theme change.
 
procedure TForm1.FormPaint(Sender: TObject);
begin
  Label1.Caption := BoolToStr( t4a_ThisIsDarkTheme, 'Dark Theme', 'Light Theme' );
end;   
Â