diff --git a/NAMESPACE b/NAMESPACE
index cd7937e..3652cd3 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -1,10 +1,15 @@
# Generated by roxygen2: do not edit by hand
+export(alucard_tibble)
export(dracula_brand)
export(dracula_tibble)
+export(scale_color_alucard)
export(scale_color_dracula)
+export(scale_colour_alucard)
export(scale_colour_dracula)
+export(scale_fill_alucard)
export(scale_fill_dracula)
+export(theme_alucard)
export(theme_dracula)
importFrom(dplyr,pull)
importFrom(ggplot2,'%+replace%')
diff --git a/R/alucard_palette.R b/R/alucard_palette.R
new file mode 100644
index 0000000..a8da505
--- /dev/null
+++ b/R/alucard_palette.R
@@ -0,0 +1,65 @@
+#' @title Alucard Tibble
+#'
+#' @description A Tibble of Alucard data that includes the palette specification.
+#' See https://spec.draculatheme.com for details.
+#'
+#' @importFrom tibble tribble
+#'
+#' @return Alucard Tibble
+#'
+#' @export
+alucard_tibble <- tribble(
+ ~palette, ~hex, ~rgb, ~hsl,
+ "green", "#14710A", "RGB(20, 113, 10)", "HSL(114, 84, 24)",
+ "cyan", "#036A96", "RGB(3, 106, 150)", "HSL(198, 96, 30)",
+ "purple", "#644AC9", "RGB(100, 74, 201)", "HSL(252, 54, 54)",
+ "pink", "#A3144D", "RGB(163, 20, 77)", "HSL(336, 78, 36)",
+ "red", "#CB3A2A", "RGB(203, 58, 42)", "HSL(6, 66, 48)",
+ "orange", "#A34D14", "RGB(163, 77, 20)", "HSL(24, 78, 36)",
+ "yellow", "#846E15", "RGB(132, 110, 21)", "HSL(48, 73, 30)"
+)
+
+
+#' @title Alucard Bright Palette
+#'
+#' @description Used in conjunction with `alucard_discrete_bright_palette` as an
+#' internal closure for interfacing with `scale_fill_alucard` and `scale_color_alucard`.
+#'
+#' @noRd
+#'
+#' @importFrom dplyr pull
+alucard_bright_palette <- function() {
+ function(n) {
+ pull(alucard_tibble, "hex")[1:n]
+ }
+}
+
+
+#' @title Alucard Discrete Bright Palette
+#'
+#' @description Used in conjunction with `alucard_bright_palette` as an
+#' internal closure for interfacing with `scale_fill_alucard` and `scale_color_alucard`
+#'
+#' @param n Number of colors to return.
+#' If missing, defaults to the length of the entire palette
+#'
+#' @noRd
+#'
+#' @return Function for interfacing with scale functions
+alucard_discrete_bright_palette <- function(n) {
+ if (missing(n)) {
+ n <- 7
+ }
+
+ if (n > 7) {
+ stop("WARNING: Cannot use n > 7")
+ }
+
+ alucard <- alucard_bright_palette()(n)
+
+ structure(
+ alucard,
+ name = "alucard",
+ class = "palette"
+ )
+}
diff --git a/R/scales.R b/R/scales.R
index e5b3542..7ed75c8 100644
--- a/R/scales.R
+++ b/R/scales.R
@@ -34,3 +34,39 @@ scale_color_dracula <- function(..., discrete = FALSE, aesthetics = "color") {
#' @aliases scale_color_dracula
#' @export
scale_colour_dracula <- scale_color_dracula
+
+#' @title Alucard Theme Scales for `ggplot2`
+#'
+#' @param ... Parameters passed on to [ggplot2::discrete_scale()] if
+#' `discrete == TRUE`, or to [ggplot2::scale_fill_gradientn()] if `discrete == FALSE`.
+#' @param discrete Whether the scale is discrete. Defaults to `FALSE`.
+#' @param aesthetics The aesthetics for the plot.
+#'
+#' @rdname scale_alucard
+#'
+#' @importFrom ggplot2 scale_fill_gradientn scale_color_gradientn discrete_scale
+#'
+#' @export
+scale_fill_alucard <- function(..., discrete = FALSE, aesthetics = "fill") {
+ if (discrete) {
+ discrete_scale(aesthetics, palette = alucard_discrete_bright_palette, ...)
+ } else {
+ scale_fill_gradientn(colors = pull(alucard_tibble, "hex"), aesthetics = aesthetics, ...)
+ }
+}
+
+#' @rdname scale_alucard
+#'
+#' @export
+scale_color_alucard <- function(..., discrete = FALSE, aesthetics = "color") {
+ if (discrete) {
+ discrete_scale(aesthetics, palette = alucard_discrete_bright_palette, ...)
+ } else {
+ scale_color_gradientn(colors = pull(alucard_tibble, "hex"), aesthetics = aesthetics, ...)
+ }
+}
+
+#' @rdname scale_alucard
+#' @aliases scale_color_alucard
+#' @export
+scale_colour_alucard <- scale_color_alucard
diff --git a/R/theme_alucard.R b/R/theme_alucard.R
new file mode 100644
index 0000000..50b48af
--- /dev/null
+++ b/R/theme_alucard.R
@@ -0,0 +1,48 @@
+#' @title Theme Alucard
+#'
+#' @description Provides a minimal `ggplot2` theme with a Alucard, light backdrop.
+#'
+#' @importFrom ggplot2 '%+replace%' theme element_text element_rect element_line element_blank theme_minimal
+#'
+#' @examples
+#' # Set the current `ggplot2` theme with `ggplot2::theme_set`:
+#' library(ggplot2)
+#' theme_set(theme_alucard())
+#'
+#' # Or set it for the plot in the pipeline:
+#' library(dplyr)
+#' library(dRacula)
+#' library(ggplot2)
+#'
+#' mpg %>%
+#' filter(manufacturer %in% c("honda", "ford", "dodge", "audi")) %>%
+#' group_by(manufacturer) %>%
+#' summarize(mean_hwy = mean(hwy)) %>%
+#' ggplot(aes(x = manufacturer, y = mean_hwy, fill = manufacturer)) +
+#' theme(legend.position = "none") +
+#' coord_flip() + geom_col() +
+#' scale_fill_alucard(discrete = TRUE) +
+#' theme_alucard()
+#' @export
+theme_alucard <- function() {
+ theme_minimal(base_size = 12) %+replace%
+ theme(
+ axis.text = element_text(color = "#1F1F1F"),
+ axis.title = element_text(face = "bold", color = "#6C664B"),
+
+ strip.text = element_text(face = "bold", colour = "#6C664B"),
+
+ legend.background = element_rect(fill = "transparent", color = NA),
+ legend.box.background = element_rect(fill = "transparent", color = "#1F1F1F", linewidth = 0.25),
+ legend.key = element_rect(fill = "transparent", color = NA),
+ legend.text = element_text(color = "#1F1F1F"),
+ legend.title = element_text(face = "bold", color = "#6C664B"),
+
+ panel.background = element_blank(),
+ panel.grid = element_line(color = "#CFCFDE"),
+
+ plot.background = element_rect(fill = "#FFFBEB", color = "#CFCFDE"),
+
+ title = element_text(face = "bold", color = "#1F1F1F")
+ )
+}
diff --git a/man/alucard_tibble.Rd b/man/alucard_tibble.Rd
new file mode 100644
index 0000000..1fc3c0f
--- /dev/null
+++ b/man/alucard_tibble.Rd
@@ -0,0 +1,20 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/alucard_palette.R
+\docType{data}
+\name{alucard_tibble}
+\alias{alucard_tibble}
+\title{Alucard Tibble}
+\format{
+An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 7 rows and 4 columns.
+}
+\usage{
+alucard_tibble
+}
+\value{
+Alucard Tibble
+}
+\description{
+A Tibble of Alucard data that includes the palette specification.
+See https://spec.draculatheme.com for details.
+}
+\keyword{datasets}
diff --git a/man/scale_alucard.Rd b/man/scale_alucard.Rd
new file mode 100644
index 0000000..a9edc3b
--- /dev/null
+++ b/man/scale_alucard.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/scales.R
+\name{scale_fill_alucard}
+\alias{scale_fill_alucard}
+\alias{scale_color_alucard}
+\alias{scale_colour_alucard}
+\title{Alucard Theme Scales for \code{ggplot2}}
+\usage{
+scale_fill_alucard(..., discrete = FALSE, aesthetics = "fill")
+
+scale_color_alucard(..., discrete = FALSE, aesthetics = "color")
+
+scale_colour_alucard(..., discrete = FALSE, aesthetics = "color")
+}
+\arguments{
+\item{...}{Parameters passed on to \code{\link[ggplot2:discrete_scale]{ggplot2::discrete_scale()}} if
+\code{discrete == TRUE}, or to \code{\link[ggplot2:scale_gradient]{ggplot2::scale_fill_gradientn()}} if \code{discrete == FALSE}.}
+
+\item{discrete}{Whether the scale is discrete. Defaults to \code{FALSE}.}
+
+\item{aesthetics}{The aesthetics for the plot.}
+}
+\description{
+Alucard Theme Scales for \code{ggplot2}
+}
diff --git a/man/theme_alucard.Rd b/man/theme_alucard.Rd
new file mode 100644
index 0000000..2a5c990
--- /dev/null
+++ b/man/theme_alucard.Rd
@@ -0,0 +1,31 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/theme_alucard.R
+\name{theme_alucard}
+\alias{theme_alucard}
+\title{Theme Alucard}
+\usage{
+theme_alucard()
+}
+\description{
+Provides a minimal \code{ggplot2} theme with a Alucard, light backdrop.
+}
+\examples{
+# Set the current `ggplot2` theme with `ggplot2::theme_set`:
+library(ggplot2)
+theme_set(theme_alucard())
+
+# Or set it for the plot in the pipeline:
+library(dplyr)
+library(dRacula)
+library(ggplot2)
+
+mpg \%>\%
+ filter(manufacturer \%in\% c("honda", "ford", "dodge", "audi")) \%>\%
+ group_by(manufacturer) \%>\%
+ summarize(mean_hwy = mean(hwy)) \%>\%
+ ggplot(aes(x = manufacturer, y = mean_hwy, fill = manufacturer)) +
+ theme(legend.position = "none") +
+ coord_flip() + geom_col() +
+ scale_fill_alucard(discrete = TRUE) +
+ theme_alucard()
+}
diff --git a/tests/testthat/_snaps/scales/diamonds-point-plot-alucard.svg b/tests/testthat/_snaps/scales/diamonds-point-plot-alucard.svg
new file mode 100644
index 0000000..e258904
--- /dev/null
+++ b/tests/testthat/_snaps/scales/diamonds-point-plot-alucard.svg
@@ -0,0 +1,13747 @@
+
+
diff --git a/tests/testthat/_snaps/scales/mtcars-lm-plot-alucard.svg b/tests/testthat/_snaps/scales/mtcars-lm-plot-alucard.svg
new file mode 100644
index 0000000..db2e9d7
--- /dev/null
+++ b/tests/testthat/_snaps/scales/mtcars-lm-plot-alucard.svg
@@ -0,0 +1,112 @@
+
+
diff --git a/tests/testthat/_snaps/scales/rnorm-hex-plot-alucard.svg b/tests/testthat/_snaps/scales/rnorm-hex-plot-alucard.svg
new file mode 100644
index 0000000..759beff
--- /dev/null
+++ b/tests/testthat/_snaps/scales/rnorm-hex-plot-alucard.svg
@@ -0,0 +1,636 @@
+
+
diff --git a/tests/testthat/test-alucard_palette.R b/tests/testthat/test-alucard_palette.R
new file mode 100644
index 0000000..9bc0134
--- /dev/null
+++ b/tests/testthat/test-alucard_palette.R
@@ -0,0 +1,8 @@
+test_that("palette is correct number of colors", {
+ expect_length(alucard_discrete_bright_palette(), 7)
+ expect_length(alucard_discrete_bright_palette(1), 1)
+})
+
+test_that("alucard_discrete_bright_palette() cannot return more than 7", {
+ expect_error(alucard_discrete_bright_palette(8))
+})
diff --git a/tests/testthat/test-scales.R b/tests/testthat/test-scales.R
index cd1f442..7d25e67 100644
--- a/tests/testthat/test-scales.R
+++ b/tests/testthat/test-scales.R
@@ -46,3 +46,45 @@ test_that("mtcars-lm-plot", {
expect_doppelganger("mtcars-lm-plot", test_plot)
})
+
+test_that("rnorm-hex-plot alucard", {
+ set.seed(1)
+
+ test_plot <- ggplot(data.frame(x = rnorm(10000), y = rnorm(10000)), aes(x = x, y = y)) +
+ geom_hex() +
+ coord_fixed() +
+ ggtitle("rnorm-hex-plot alucard") +
+ scale_fill_alucard(discrete = FALSE) +
+ theme_alucard()
+
+ expect_doppelganger("rnorm-hex-plot_alucard", test_plot)
+})
+
+
+test_that("diamonds-point-plot alucard", {
+ dsub <- subset(diamonds, x > 5 & x < 6 & y > 5 & y < 6)
+ dsub$diff <- with(dsub, sqrt(abs(x - y)) * sign(x - y))
+
+ test_plot <- ggplot(dsub, aes(x, y, colour = diff)) +
+ geom_point() +
+ ggtitle("scale_color_alucard(discrete = FALSE)") +
+ scale_color_alucard(discrete = FALSE) +
+ theme_alucard()
+
+ expect_doppelganger("diamonds-point-plot_alucard", test_plot)
+})
+
+
+test_that("mtcars-lm-plot alucard", {
+ lm <- lm(mpg ~ wt, data = mtcars)
+
+ test_plot <- ggplot(mtcars %>% mutate(resid = abs(resid(lm)), fitted = fitted(lm))) +
+ geom_line(aes(wt, fitted)) +
+ geom_point(aes(wt, mpg, color = resid)) +
+ scale_color_alucard(discrete = FALSE) +
+ theme_alucard() +
+ ggtitle("mtcars-lm-plot alucard") +
+ labs(x = "Weight", y = "MPG", color = "Residuals")
+
+ expect_doppelganger("mtcars-lm-plot_alucard", test_plot)
+})
diff --git a/tests/testthat/test-theme_alucard.R b/tests/testthat/test-theme_alucard.R
new file mode 100644
index 0000000..6dddef6
--- /dev/null
+++ b/tests/testthat/test-theme_alucard.R
@@ -0,0 +1,3 @@
+test_that("no errors setting theme_alucard()", {
+ expect_no_error(theme_alucard())
+})