Dark mode for the Alpaca dashboard (unofficial, 2 min)

Purely cosmetic CSS in your own browser. It doesn’t touch orders, positions, or the API, and toggles off in one click.

Setup

  1. Install Stylus (Chrome/Edge/Arc/Brave, also on Firefox) or your userstyle manager of choice
  2. Stylus icon → Write new style
  3. “Applies to” → URLs on the domainapp.alpaca.markets
  4. Paste the CSS below, name it, Save
  5. Reload

Leave “Write new style as UserCSS” unchecked, or the paste fails validation.

/* Alpaca dashboard — dark mode override  (v2: hover + accent states)
   Stylus ▸ URLs on the domain ▸ app.alpaca.markets */

:root {
  --al-bg:      #0d0d0f;   /* page ground              */
  --al-surface: #16161a;   /* cards, panels            */
  --al-raised:  #1f1f25;   /* inputs, tabs             */
  --al-hover:   #24242b;   /* neutral hover: lift, not bleach */
  --al-hover-2: #2e2e36;   /* stronger hover / pressed */
  --al-border:  #2b2b33;
  --al-text:    #e8e8ea;
  --al-muted:   #9a9aa2;
  --al-dim:     #6e6e78;
  --al-accent:      #ecb206;              /* yellow-500, the brand */
  --al-accent-soft: rgba(236,178,6,.10);  /* selected surface      */
  --al-accent-hi:   rgba(236,178,6,.18);  /* hovered surface       */
  color-scheme: dark;
}

/* ---- surfaces ------------------------------------------------ */
html, body                                    { background: var(--al-bg) !important; }
.bg-white                                     { background-color: var(--al-surface) !important; }
.bg-gray-50, .bg-gray-100, .bg-zinc-100, .bg-zinc-200, .bg-zinc-300,
.bg-cool-gray-50, .bg-cool-gray-100,
.bg-cool-gray-200, .bg-cool-gray-300,
.bg-\[rgba\(215\,215\,215\,0\.24\)\]          { background-color: var(--al-raised) !important; }

/* ---- text ---------------------------------------------------- */
.text-black,
.text-zinc-900, .hover\:text-zinc-900:hover,
.text-gray-900, .text-gray-800, .text-gray-700, .text-zinc-800,
.text-cool-gray-900, .text-cool-gray-800,
.text-cool-gray-700                           { color: var(--al-text) !important; }
.text-gray-600, .text-gray-500, .text-zinc-500, .text-zinc-600,
.text-cool-gray-500                           { color: var(--al-muted) !important; }
.text-gray-300, .text-cool-gray-400            { color: var(--al-dim) !important; }
.text-yellow-600                              { color: #e0a800 !important; }

/* ---- ARBITRARY HEX TEXT / BORDERS ------------------------------
   Alpaca writes its primary + secondary text colors as hex literals in
   places (the symbol-search dropdown is all of these), so no named-palette
   sweep reaches them. #282828/#3B3B3B are body text — they were staying
   near-black on the dark panel. */
.text-\[\#282828\], .text-\[\#3B3B3B\]         { color: var(--al-text) !important; }
.text-\[\#565656\], .text-\[\#60676a\],
.text-\[\#696969\], .text-\[\#7A7A7A\]         { color: var(--al-muted) !important; }
.text-\[\#4F46E5\]                             { color: #818cf8 !important; }
.border-\[\#D1D5DB\]                           { border-color: var(--al-border) !important; }

/* ---- borders ------------------------------------------------- */
.border-gray-200, .border-gray-300, .border-gray-400, .border-gray-500,
.border-cool-gray-200, .border-cool-gray-300, .border-cool-gray-500,
.border-\[\#9C9C9C\], .border-\[\#565656\]    { border-color: var(--al-border) !important; }
.border-zinc-100, .border-zinc-200, .border-zinc-300
                                              { border-color: var(--al-border) !important; }
.ring-gray-200,
.focus\:ring-zinc-100:focus,
.focus\:ring-zinc-300:focus                   { --tw-ring-color: var(--al-border) !important; }

/* ---- NEUTRAL HOVER: lift off the surface, never toward white -- */
.hover\:bg-gray-50:hover, .hover\:bg-gray-100:hover,
.hover\:bg-cool-gray-50:hover, .hover\:bg-cool-gray-100:hover,
.hover\:bg-zinc-200:hover                     { background-color: var(--al-hover) !important; }
.hover\:bg-gray-200:hover, .hover\:bg-gray-300:hover,
.hover\:bg-gray-400:hover, .hover\:bg-black:hover { background-color: var(--al-hover-2) !important; }

/* ---- ACCENT SURFACES: translucent amber, not pastel fill ------ */
/* selected account card (bg-yellow-50) + its hover (bg-yellow-100) */
.bg-yellow-50, .bg-yellow-100,
.bg-yellow-100\/80                            { background-color: var(--al-accent-soft) !important; }
.hover\:bg-yellow-100:hover                   { background-color: var(--al-accent-hi) !important; }
.hover\:border-yellow-600:hover               { border-color: var(--al-accent) !important; }

/* ---- SOLID BRAND CTAs: force a near-black label ----------------
   Doubled class = specificity (0,2,0), so it beats .text-cool-gray-800
   which Alpaca puts on the SAME element (Add Funds, Apply Now, Edit
   Payment). The descendant rule catches nested spans + currentColor svg. */
.bg-yellow-200.bg-yellow-200,   .bg-yellow-300.bg-yellow-300,
.bg-yellow-400.bg-yellow-400,   .bg-yellow-500.bg-yellow-500,
.bg-yellow-200.bg-yellow-200 *, .bg-yellow-300.bg-yellow-300 *,
.bg-yellow-400.bg-yellow-400 *, .bg-yellow-500.bg-yellow-500 *,
.hover\:bg-yellow-200:hover,    .hover\:bg-yellow-200:hover *,
.hover\:bg-yellow-400:hover,    .hover\:bg-yellow-500:hover,
.focus\:bg-yellow-200:focus     { color: #101012 !important; }

/* ---- PALE STATUS / PILL FILLS → translucent tints --------------
   bg-indigo-50 = Stock Lending tab, bg-indigo-100 = Credit/Debit Card,
   bg-emerald-50 = "Paid" invoice pills, etc. All near-white in light mode. */
.bg-indigo-50, .bg-indigo-100,
.hover\:bg-indigo-50:hover                    { background-color: rgba(129,140,248,.16) !important; }
.bg-emerald-50, .bg-emerald-100, .bg-green-100 { background-color: rgba(52,211,153,.14) !important; }
.bg-red-50, .bg-red-100, .bg-rose-50, .bg-rose-100,
.hover\:bg-rose-50:hover                      { background-color: rgba(244,63,94,.15) !important; }
.bg-blue-50, .bg-blue-100                      { background-color: rgba(96,165,250,.15) !important; }
.bg-purple-100                                 { background-color: rgba(192,132,252,.15) !important; }

/* brighten semantic text so it reads on dark */
.text-emerald-600                              { color: #34d399 !important; }
.text-red-600, .text-rose-600                  { color: #fb7185 !important; }

/* ---- the plan card's white gradient ---------------------------
   bg-[linear-gradient(106deg,rgba(255,252,216,.65)_-38.69%,#FFF_97.09%)] */
[class*="bg-[linear-gradient"] {
  background-image: linear-gradient(106deg, rgba(236,178,6,.16) -38.69%, rgba(236,178,6,.03) 97.09%) !important;
}

/* ---- ARBITRARY HEX FILLS --------------------------------------
   Alpaca hardcodes some colors as Tailwind arbitrary values, which no
   named-utility sweep catches. The symbol-search dropdown is bg-[#FFF]
   with hover:bg-[#F8F8F8] rows. (bg-[#010101] and bg-[#4F46E5] are
   already dark/saturated — left alone.) */
.bg-\[\#FFF\]                                  { background-color: var(--al-surface) !important; }
.bg-\[\#F8F8F8\], .bg-\[\#e6e7ec\]             { background-color: var(--al-raised) !important; }
.hover\:bg-\[\#F8F8F8\]:hover                  { background-color: var(--al-hover) !important; }
.bg-\[\#fefce880\]                             { background-color: var(--al-accent-soft) !important; }

/* yellow CTAs expressed as hex — same near-black label treatment */
.bg-\[\#fee546\].bg-\[\#fee546\],
.bg-\[\#fee546\].bg-\[\#fee546\] *,
.hover\:bg-\[\#fde020\]:hover,
.hover\:bg-\[\#fde020\]:hover *                 { color: #101012 !important; }

/* ---- disabled states ------------------------------------------ */
.disabled\:bg-cool-gray-100:disabled           { background-color: var(--al-raised) !important; }
.disabled\:text-cool-gray-500:disabled         { color: var(--al-dim) !important; }

/* ---- focus ---------------------------------------------------- */
.ring-yellow-200, .focus\:ring-yellow-200:focus { --tw-ring-color: rgba(236,178,6,.45) !important; }
.focus\:border-yellow-50:focus                { border-color: var(--al-accent) !important; }

/* ---- form controls -------------------------------------------- */
input, select, textarea {
  background-color: var(--al-raised) !important;
  color: var(--al-text) !important;
  border-color: var(--al-border) !important;
}
input::placeholder                            { color: var(--al-dim) !important; }

/* Buy/Sell buttons already use translucent rgba tints — untouched. */

Notes

  • Covers Home, Positions, Orders, Activities, Balances, Interest Products, Transfers, Documents, the order ticket, and billing.
  • Yellow buttons stay yellow only their labels flip to near-black.
  • P/L green/red are brightened for dark backgrounds. Delete those two lines to keep Alpaca’s originals.
  • Palette is all variables at the top; change --al-surface and the rest follows.

The chart toolbar stays white. It’s TradingView in a blob: iframe whose root is data-theme="light" even though Alpaca already themed the plot inside it dark. Extensions can’t inject there, and switching it means changing an attribute, which CSS can’t do.

It’ll break occasionally these are internal class names, not a public API. If white reappears: Inspect → read the class → add a line.

Hopefully it’s helpful!