diff --git a/doc/plugin/NumPad.md b/doc/plugin/NumPad.md
new file mode 100644
index 00000000..83bc5629
--- /dev/null
+++ b/doc/plugin/NumPad.md
@@ -0,0 +1,39 @@
+# Kaleidoscope-NumPad
+
+This is a plugin for [Kaleidoscope][fw], that adds a NumPad-specific LED
+effect, along with a way to toggle to a numpad layer, and apply the effect.
+
+## Using the extension
+
+To use the plugin, include the header, and tell the firmware to use it:
+
+```c++
+#include "Kaleidoscope-NumPad.h"
+
+KALEIDOSCOPE_INIT_PLUGINS(NumPad);
+
+void setup() {
+ Kaleidoscope.setup();
+
+ NumPad.color = CRGB(0, 0, 160); // a blue color
+ NumPad.lock_hue = 85; // green
+}
+```
+
+## Plugin methods
+
+The plugin provides the `NumPad` object, with the following properties:
+
+### `.color`
+
+> This property sets the color that the NumPad keys are highlighted in.
+>
+> The default is `CRGB(160, 0, 0)`, a red color.
+
+### `.lock_hue`
+
+> This property sets the color hue that the NumLock LED breathes in.
+>
+> The default is `170`, a blue hue.
+
+ [fw]: https://github.com/keyboardio/Kaleidoscope
diff --git a/src/Kaleidoscope-NumPad.h b/src/Kaleidoscope-NumPad.h
new file mode 100644
index 00000000..be0c76f6
--- /dev/null
+++ b/src/Kaleidoscope-NumPad.h
@@ -0,0 +1,19 @@
+/* Kaleidoscope-NumPad - A NumPad plugin for Kaleidoscope.
+ * Copyright (C) 2017-2018 Keyboard.io, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+
+#pragma once
+
+#include "kaleidoscope/plugin/NumPad.h"
diff --git a/src/kaleidoscope/plugin/NumPad.cpp b/src/kaleidoscope/plugin/NumPad.cpp
new file mode 100644
index 00000000..6b49ae05
--- /dev/null
+++ b/src/kaleidoscope/plugin/NumPad.cpp
@@ -0,0 +1,105 @@
+/* Kaleidoscope-NumPad - A NumPad plugin for Kaleidoscope.
+ * Copyright (C) 2017-2018 Keyboard.io, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+
+#include "Kaleidoscope-NumPad.h"
+
+namespace kaleidoscope {
+namespace plugin {
+
+byte NumPad::numpadLayerToggleKeyRow = 255, NumPad::numpadLayerToggleKeyCol = 255;
+uint8_t NumPad::numPadLayer;
+bool NumPad::numlockUnsynced = false;
+bool NumPad::originalNumLockState = false;
+cRGB NumPad::color = CRGB(160, 0, 0);
+uint8_t NumPad::lock_hue = 170;
+
+EventHandlerResult NumPad::onSetup(void) {
+ originalNumLockState = getNumlockState();
+ return EventHandlerResult::OK;
+}
+
+bool NumPad::getNumlockState() {
+ return !!(kaleidoscope::hid::getKeyboardLEDs() & LED_NUM_LOCK);
+}
+
+void NumPad::syncNumlockState(bool state) {
+ bool numLockLEDState = getNumlockState();
+ if (numLockLEDState != state) {
+ kaleidoscope::hid::pressKey(Key_KeypadNumLock);
+ }
+}
+
+
+
+void NumPad::cleanupNumlockState() {
+ if (!numlockUnsynced) {
+ bool numLockLEDState = getNumlockState();
+ ::LEDControl.set_mode(::LEDControl.get_mode_index());
+ if (!originalNumLockState) {
+ syncNumlockState(false);
+ numLockLEDState = false;
+ }
+ originalNumLockState = numLockLEDState;
+ numlockUnsynced = true;
+ }
+
+}
+
+void NumPad::setKeyboardLEDColors(void) {
+ ::LEDControl.set_mode(::LEDControl.get_mode_index());
+
+ for (uint8_t r = 0; r < ROWS; r++) {
+ for (uint8_t c = 0; c < COLS; c++) {
+ Key k = Layer.lookupOnActiveLayer(r, c);
+ Key layer_key = Layer.getKey(numPadLayer, r, c);
+
+ if (k == LockLayer(numPadLayer)) {
+ numpadLayerToggleKeyRow = r;
+ numpadLayerToggleKeyCol = c;
+ }
+
+ if ((k != layer_key) || (k == Key_NoKey) || (k.flags != KEY_FLAGS)) {
+ ::LEDControl.refreshAt(r, c);
+ } else {
+ ::LEDControl.setCrgbAt(r, c, color);
+ }
+ }
+ }
+
+ if ((numpadLayerToggleKeyRow <= ROWS) && (numpadLayerToggleKeyCol <= COLS)) {
+ cRGB lock_color = breath_compute(lock_hue);
+ ::LEDControl.setCrgbAt(numpadLayerToggleKeyRow, numpadLayerToggleKeyCol, lock_color);
+ }
+}
+
+EventHandlerResult NumPad::afterEachCycle() {
+ if (!Layer.isOn(numPadLayer)) {
+ cleanupNumlockState();
+ } else {
+ if (numlockUnsynced) {
+ // If it's the first time we're in this loop after toggling the Numpad mode on
+ syncNumlockState(true);
+ numlockUnsynced = false;
+ }
+ setKeyboardLEDColors();
+ }
+ return EventHandlerResult::OK;
+}
+
+}
+}
+
+kaleidoscope::plugin::NumPad NumPad;
diff --git a/src/kaleidoscope/plugin/NumPad.h b/src/kaleidoscope/plugin/NumPad.h
new file mode 100644
index 00000000..8735cd84
--- /dev/null
+++ b/src/kaleidoscope/plugin/NumPad.h
@@ -0,0 +1,50 @@
+/* Kaleidoscope-NumPad - A NumPad plugin for Kaleidoscope.
+ * Copyright (C) 2017-2018 Keyboard.io, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+
+#pragma once
+
+#include "Kaleidoscope-LEDControl.h"
+
+namespace kaleidoscope {
+namespace plugin {
+
+class NumPad : public kaleidoscope::Plugin {
+ public:
+ NumPad(void) {}
+
+ static uint8_t numPadLayer;
+ static cRGB color;
+ static uint8_t lock_hue;
+
+ EventHandlerResult onSetup(void);
+ EventHandlerResult afterEachCycle();
+
+ private:
+
+ void cleanupNumlockState(void);
+ void setKeyboardLEDColors(void);
+ bool getNumlockState(void);
+ void syncNumlockState(bool);
+
+ static uint8_t numpadLayerToggleKeyRow;
+ static uint8_t numpadLayerToggleKeyCol;
+ static bool numlockUnsynced;
+ static bool originalNumLockState;
+};
+}
+}
+
+extern kaleidoscope::plugin::NumPad NumPad;