Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
<<importTiddlers>>
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<!--{{{-->
<div class='header' role='banner' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' role='navigation' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' role='navigation' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' role='complementary' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea' role='main'>
<div id='messageArea' class='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.txtOptionInput {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected {color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard { background:[[ColorPalette::PrimaryPale]]; }
.wizard__title    { color:[[ColorPalette::PrimaryDark]]; border:none; }
.wizard__subtitle { color:[[ColorPalette::Foreground]]; border:none; }
.wizardStep { background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]]; }
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

.messageArea { border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
.messageToolbar__button { color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none; }
.messageToolbar__button_withIcon { background:inherit; }
.messageToolbar__button_withIcon:active { background:inherit; border:none; }
.messageToolbar__icon { fill:[[ColorPalette::TertiaryDark]]; }
.messageToolbar__icon:hover { fill:[[ColorPalette::Foreground]]; }

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%; background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:alpha(opacity=60);}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0; top:0;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard { padding:0.1em 2em 0; }
.wizard__title    { font-size:2em; }
.wizard__subtitle { font-size:1.2em; }
.wizard__title, .wizard__subtitle { font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em; }
.wizardStep { padding:1em; }
.wizardFooter { padding:0.8em 0.4em 0.8em 0; }
.wizardFooter .status { padding:0.2em 0.7em; margin-left:0.3em; }
.wizardFooter .button { margin:0.5em 0 0; font-size:1.2em; padding:0.2em 0.5em; }

.messageArea { position:fixed; top:2em; right:0; margin:0.5em; padding:0.7em 1em; z-index:2000; }
.messageToolbar { text-align:right; padding:0.2em 0; }
.messageToolbar__button { text-decoration:underline; }
.messageToolbar__icon { height: 1em; }
.messageArea__text a { text-decoration:underline; }

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0 3px 0 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; box-sizing: border-box; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0; padding-bottom:0;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel { display:none; z-index:100; position:absolute; width:90%; margin-left:3em; }
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, .messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='toolbar' role='navigation' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
Background: #1e1e1e
Foreground: #d2d2d2
PrimaryPale: #438
PrimaryLight: #68c
PrimaryMid: #9bf
PrimaryDark: #cdc
SecondaryPale: #003
SecondaryLight: #017
SecondaryMid: #24b
SecondaryDark: #f87
TertiaryPale: #333
TertiaryLight: #555
TertiaryMid: #888
TertiaryDark: #bbb
Error: #077
Background: #000
Foreground: #fff
PrimaryPale: #510
PrimaryLight: #752
PrimaryMid: #c73
PrimaryDark: #fd9
SecondaryPale: #003
SecondaryLight: #017
SecondaryMid: #24b
SecondaryDark: #7be
TertiaryPale: #111
TertiaryLight: #333
TertiaryMid: #666
TertiaryDark: #999
Error: #077
Background: #fff
Foreground: #000
PrimaryPale: #aef
PrimaryLight: #8ad
PrimaryMid: #38c
PrimaryDark: #026
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
Background: #000
Foreground: #fff
PrimaryPale: #730
PrimaryLight: #e70
PrimaryMid: #fb4
PrimaryDark: #feb
SecondaryPale: #003
SecondaryLight: #017
SecondaryMid: #24b
SecondaryDark: #7be
TertiaryPale: #111
TertiaryLight: #333
TertiaryMid: #666
TertiaryDark: #999
Error: #077
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
Background: #1e1e1e
Foreground: #d2d2d2
PrimaryPale: #438
PrimaryLight: #68c
PrimaryMid: #9bf
PrimaryDark: #cdc
SecondaryPale: #003
SecondaryLight: #017
SecondaryMid: #24b
SecondaryDark: #f87
TertiaryPale: #333
TertiaryLight: #555
TertiaryMid: #888
TertiaryDark: #bbb
Error: #077
Background: #000
Foreground: #ddd
~PrimaryPale: #730
~PrimaryLight: #e70
~PrimaryMid: #fb4
~PrimaryDark: #feb
~SecondaryPale: #003
~SecondaryLight: #017
~SecondaryMid: #24b
~SecondaryDark: #7be
~TertiaryPale: #111
~TertiaryLight: #333
~TertiaryMid: #666
~TertiaryDark: #999
Error: #f44
SwitchPalettePlugin
<<external [[SwitchPalettePlugin]] file:"SwitchPalettePlugin.js" plugin:true keepInternal:true>>
SwitchPalettePlugin
switch among your color palettes!
~SwitchPalettePlugin
/*{{{*/
.viewer code,
.viewer pre { color: #0000CD; }

.darkMode code,
.darkMode pre { color: #9ACD32; }
/*}}}*/
/***
!!! Plugin info
|''Name''|{{{SwitchPalettePlugin}}}|
|''Description''|Allows you to switch among color palettes by the {{{switchPalette}}} macro|
|''Author''|Pengju Yan|
|''Version''|1.0.1|
|''Source''|https://github.com/PengjuYan/TiddlyWiki_SwitchPalettePlugin/blob/master/SwitchPalettePlugin.js|
|''Documentation''|[[SwitchPalettePlugin on github.io|https://pengjuyan.github.io/TiddlyWiki_SwitchPalettePlugin/]]|
|''License''|[[MIT|https://github.com/PengjuYan/TiddlyWiki_SwitchPalettePlugin/blob/master/LICENSE]]|
|''Acknowledgements''|Forked from and inspired by Yakov Litvin's [[DarkModePlugin|https://github.com/YakovL/TiddlyWiki_DarkModePlugin/]]|
!!! Installation
Just import or copy the plugin with the {{{systemConfig}}} tag, then reload.
!!! Usage
# ''Warning'': Your original [[ColorPalette]] will be ''overwritten'' by the {{{switchPalette}}} macro, or more precisely, by clicking any button created by the macro. So, you'll need to backup your previous [[ColorPalette]] tiddler before you try it!
# Import or create color palette tiddlers as you like. You can use any title for each tiddler.
# Use the {{{switchPalette}}} macro anywhere in your TiddlyWiki, not necessarily in this plugin tiddler. Designate the color palette title as the first argument to the macro.
# The macro just creates and displays a {{{Switch palette}}} button in the hosting tiddler.
# Click such a button then the associated color palette tiddler will be ''saved'' to the [[ColorPalette]] tiddler. The colored appearance of your TiddlyWiki will change accordingly.
!!! Color palette switch form
Follow what is shown below in your own tiddlers elsewhere.
|<<switchPalette "ColorPalette (original)">>|[[ColorPalette (original)]]|
|<<switchPalette "ColorPalette (original reversed)" true>>|[[ColorPalette (original reversed)]]|
|<<switchPalette "ColorPalette (jermolene)">>|[[ColorPalette (jermolene)]]|
|<<switchPalette "ColorPalette (jermolene reversed)" true>>|[[ColorPalette (jermolene reversed)]]|
|<<switchPalette "ColorPalette (yakovl dark)" true>>|[[ColorPalette (yakovl dark)]]|
|<<switchPalette "ColorPalette (pengju dark)" true>>|[[ColorPalette (pengju dark)]]|
!!! Syntax
The {{{switchPalette}}} macro will display a button shown as {{{Switch palette}}}. For the palette in effect in use, {{{(ON)}}} will be appended to the displayed button text.
{{{
<<switchPalette "your color palette tiddler title" "is dark mode or not">>
}}}
You can designate if a color palette is ''dark mode'' or not. See blow for more description on it.
!!! Dark mode configuration
You may want to apply some global while finer grained styles to all dark mode color palettes uniformly. Passing a boolean flag as the second argument to the macro enables the mechanism.

When the dark mode argument is {{{true}}}, the {{{darkMode}}} class is added to the {{{html}}} element. This allows you to add ''styles for dark mode'' only, like this:
{{{
.viewer code,
.viewer pre { color: #0000CD; }

.darkMode code,
.darkMode pre { color: #9ACD32; }
}}}

Ordinary styles are applied to both modes, but {{{.darkMode}}} ones have higher precedence and ''overwrite'' the ordinary ones.

The fine grained styles for the dark mode can be ''customized'' by editing [[StyleSheet]].

Note that the section {{{FollowDarkMode}}} below is part of the magic behind, so don't delete it. Of course you can modify it if you know what you are doing.
!!! Development
This work was inspired by Yakov Litvin's [[DarkModePlugin|https://github.com/YakovL/TiddlyWiki_DarkModePlugin/]] and was started by forking from it.

Learning from {{{DarkModePlugin}}}:
# The {{{TiddlerInFilePlugin.js}}} is a very nice helper for plugin development.
# I followed the {{{createTiddlyButton()}}} way for the user to interact with the macro.
# The {{{darkMode}}} mechanism was inherited.
# Release plugin document to {{{GitHub Pages}}}.

{{{SwitchPalettePlugin}}} features (c.f. {{{DarkModePlugin}}}):
|!{{{SwitchPalettePlugin}}}|!{{{DarkModePlugin}}}|
|The users takes full control. They change color palette only when they want to.|Automatically switch to dark mode on startup if the dark mode is set system wide.|
|Releases several reversed color palette, including {{{DarkModePlugin}}}'s {{{ColorPaletteDark}}} (renamed to [[ColorPalette (yakovl dark)]]).|Releases a dark mode color palette: {{{ColorPaletteDark}}}.|
!!! Code
***/
//{{{
config.macros.switchPalette = {
    getMainPaletteTitle: function () {
        return "ColorPalette";
    },

    getPaletteOrigin: function () {
        const mainPaletteTitle = this.getMainPaletteTitle();
        const mainPaletteTiddler = store.getTiddler(mainPaletteTitle);
        if (!mainPaletteTiddler) return ["", false];

        const originPaletteTitle = mainPaletteTiddler.fields['from.palette'];
        const originIsDarkMode = mainPaletteTiddler.fields['is.dark.mode'];
        return [originPaletteTitle, originIsDarkMode];
    },

    applySectionCSS: function (sectionName) {
        const sectionText = store.getRecursiveTiddlerText(this.pluginName + "##" + sectionName, "", 1);
        const css = sectionText.replace(/^\s*{{{((?:.|\n)*?)}}}\s*$/, "$1");
        return setStylesheet(css, sectionName);
    },

    applyAdjustments: function (isDarkMode) {
        if (isDarkMode) {
            jQuery('html').addClass('darkMode');
            this.applySectionCSS("FollowDarkMode");
        } else {
            jQuery('html').removeClass('darkMode');
            removeStyleSheet("FollowDarkMode");
        }
    },

    onStartup: function () {
        const [originPaletteTitle, originIsDarkMode] = this.getPaletteOrigin();
        this.applyAdjustments(originIsDarkMode);
    },

    handler: function (place, macroName, params, wikifier, paramString, sourceTiddler) {
        const args = paramString.parseParams("anon", null, null)[0];
        const pParams = args.anon || [];
        const sourcePaletteTitle = pParams[0] || null;
        const isDarkMode = pParams[1] || false;

        let label = "Switch palette";
        const tooltip = `switch to ${sourcePaletteTitle}`;

        const [originPaletteTitle, originIsDarkMode] = this.getPaletteOrigin();
        if (sourcePaletteTitle == originPaletteTitle) {
            label += " (ON)";
        }

        createTiddlyButton(place, label, tooltip, function () {
            const me = config.macros.switchPalette;
            const mainPaletteTitle = me.getMainPaletteTitle();

            const sourcePaletteTiddler = store.getTiddler(sourcePaletteTitle);
            if (!sourcePaletteTiddler) return;

            let targetPaletteTiddler = new Tiddler(mainPaletteTitle);
            targetPaletteTiddler.text = sourcePaletteTiddler.text;
            targetPaletteTiddler.creator = sourcePaletteTiddler.creator;
            targetPaletteTiddler.modifier = sourcePaletteTiddler.modifier;
            targetPaletteTiddler.created = sourcePaletteTiddler.created;
            targetPaletteTiddler.modified = sourcePaletteTiddler.modified;
            targetPaletteTiddler.links = sourcePaletteTiddler.links;
            targetPaletteTiddler.linksUpdated = sourcePaletteTiddler.linksUpdated;
            targetPaletteTiddler.tags = sourcePaletteTiddler.tags;

            Object.assign(targetPaletteTiddler.fields, sourcePaletteTiddler.fields);
            targetPaletteTiddler.fields['from.palette'] = sourcePaletteTitle;
            targetPaletteTiddler.fields['is.dark.mode'] = isDarkMode;

            store.saveTiddler(targetPaletteTiddler);
            story.refreshAllTiddlers();

            me.applyAdjustments(isDarkMode);
            refreshColorPalette();

            autoSaveChanges();
        });
    }
};

config.macros.switchPalette.onStartup();
//}}}
/***
!!! FollowDarkMode
{{{
.darkMode {
    color-scheme: dark;
}
}}}
***/
/***
|Description|Allows to store any number of tiddlers as external files and more|
|Version|1.1.2|
|Source|https://github.com/YakovL/TiddlyWiki_TiddlerInFilePlugin|
|Author|Yakov Litvin|
|License|MIT|
!!!Usage
Once the plugin is installed (copy - tag {{{systemConfig}}} - reload) storing tiddlers in files is done via 2 steps:
# list (describe) those in [[ExternalTiddlersList]] by writing {{{<<external>>}}} macros there
# if the file exists and the tiddler doesn't, reload TW (external tiddler will be loaded on startup);<br>if the tiddler exists and the file doesn't, just save your TW

Here's how the macro is used:
{{{
<<external [[MyTestTiddler]]>>
}}}
will store the tiddler's text in {{{MyTestTiddler.txt}}} in the same folder as TW. There's a number of other options:
{{{
<<external [[tiddler name]]
	[file:<relative path with or without filename and extension>]
	[format:{externalized | text}]
	[keepInternal:true]
	[plugin:true]
>>
}}}
Examples of the {{{file}}} param usage:
* {{{<<external [[MyTestTiddler]] file:"other name">>}}} makes file name different from tiddler name
* {{{<<external [[MyPlugin]] file:"MyPlugin.js" plugin:true>>}}} sets a custom file extension (see also the {{{plugin}}} option below)
* {{{<<external [[MyLog]] file:"../logs/">>}}} will store the file in another folder (note that omitted filename after {{{/}}} means "use tiddler name as filename and default extension")
* the plugin doesn't take care of forbidden characters yet ({{{*}}}, {{{?}}}, {{{"}}} etc), so be careful about those

Supported formats are
* {{{text}}} (default) – only tiddler text is stored in the file with {{{.txt}}} extension; and
* {{{externalized}}} – whole tiddler is stored in the same format as in TW store, file has {{{.tid.html}}} extension and is displayed is monospace tiddler text when opened in browser
Formats can be added by extending {{{config.macros.external.fileFormats}}}.

The {{{keepInternal}}} option makes TW save the tiddler in both external file and TW itself. This, for instance, affects tiddlers stored in {{{text}}} format: without it, all fields like creator, modified etc are destroyed on reload (since are not saved), but with it they are preserved.

The {{{plugin}}} option makes TW evaluate the tiddler like it does with plugins. Note that it doesn't handle plugin dependencies yet. @@color:red;Warning@@: TIFP doesn't currently take care of installing only once, so use {{{plugin}}} with {{{keepInternal}}} ''only'' if you understand the outcome (for instance, some plugins may create infinite loops; also remember that internal version will be always installed first).
***/
//{{{
config.macros.external = {
	fileFormats: {
		text: {
			extension: 'txt',
			externalize: function(tiddler) { return tiddler.text },
			// changes tiddler as a side-effect not to remove existing fields
			internalize: function(tiddler, source) {
				tiddler.text = source;
			}
		},
		externalized: {
			extension: 'tid.html',
			externalize: function(tiddler) {
				return store.getSaver().externalizeTiddler(store, tiddler);
			},
			// like for 'text', extends tiddler, doesn't create from scratch
			internalize: function(tiddler, source) {
				var div = createTiddlyElement(document.body, 'div');
				div.setAttribute('style','display:none;');
				div.innerHTML = source;
				store.getLoader().internalizeTiddler(store, tiddler,
					tiddler.title, div.firstChild);
				div.remove();
			}
		}/*,
		tid: { extension: 'tid' },
		json: { extension: 'tid.json' }
		externalizedWithFormatter? sane to implement?
		*/
	},
	// here and below "meta" means "info about registered external tiddler,
	// be it loaded or not"
	getExtension: function(meta) {
		const format = this.fileFormats[meta.fileFormat];
		if(!format) return; //# ok??
		return format.extension;
	},
	externalizeTiddler: function(meta) {
		const format = this.fileFormats[meta.fileFormat];
		if(!format) return; //# ok??
		return format.externalize(meta.tiddler);
	},
	internalizeTiddler: function(meta, source) {
		const format = this.fileFormats[meta.fileFormat];
		if(!format) return; //# ok??

		const tiddler = store.fetchTiddler(meta.tiddlerName) ||
			new Tiddler(meta.tiddlerName);
		format.internalize(tiddler, source); //# pass meta to tiddler?
		tiddler.doNotSave = function() { return !meta.keepInTW; };
		meta.tiddler = tiddler;

		return tiddler;
	},

	listName: "ExternalTiddlersList",
	// read files list, load
	init: function() {
		const listTiddler = store.fetchTiddler(this.listName);
		if(!listTiddler || !listTiddler.text) return;
		wikify(listTiddler.text, createTiddlyElement(null, 'div'));

		for(let meta of this.tiddlersMeta) this.loadExternal(meta);
	},
	handler: function(place, macroName, params, wikifier, paramString, tiddler) {
		// parse params, register
		const defaultParam = 'tiddler';
		const pParams = paramString.parseParams(defaultParam, null, true);
		const meta = {};
		meta.tiddlerName = getParam(pParams, defaultParam);
		if(!meta.tiddlerName) return;
		// although called .fileName, it actually can contain relative part of a path
		// fallback to meta.tiddlerName is set when calculating the full path
		meta.fileName = getParam(pParams, 'file', '');
		//# check if contains "bad" characters (like " or * ..for local paths only)
		meta.fileFormat = getParam(pParams, 'format', 'text');
		meta.isPlugin = getFlag(pParams, 'plugin'); //# allow just "plugin" instead of "plugin:true"?
		const keepInternal = getParam(pParams, 'keepInternal');
		meta.keepInTW = !!keepInternal && keepInternal !== 'false'; //# ~
		this.registerExternal(meta);

		// visual feedback
		const macroText = wikifier.source.substring(wikifier.matchStart, wikifier.nextMatch);
		createTiddlyText(place, 'external ');
		createTiddlyLink(place, meta.tiddlerName, true);
		createTiddlyText(place, ' (');
		createTiddlyElement(place, 'code', '', '', macroText.slice(2 + macroName.length + 1, -2));
		createTiddlyText(place, ')');
	},
	// describes tiddlers registered as external, not necessarily loaded
	tiddlersMeta: [],
	registerExternal: function(meta) {
		//# check if already registered, don't register twice
		this.tiddlersMeta.push(meta);
	},
	getMetaFor: function(tiddlerOrTitle) {
		var isTitle = typeof tiddlerOrTitle == "string";
		for(meta of this.tiddlersMeta)
			if(isTitle && meta.tiddlerName == tiddlerOrTitle ||
			  !isTitle && meta.tiddler == tiddlerOrTitle)
				return meta;
	},
	loadExternal: function(meta) {
		// sync loading fails on startup because TF injects new mozillaLoadFile too late
//		var tiddlerText = loadFile(getLocalPath(getFullPath(meta.fileName)));
//		onExternalTiddlerLoad(tiddlerText !== null, meta, tiddlerText);
		// so we use async instead:

		const callback = this.onExternalTiddlerLoad
		const path = getFullPath(meta.fileName, meta.tiddlerName, this.getExtension(meta));
		// httpReq("GET", path, callback, meta) uses default dataType,
		// which causes js to get evaluated on load. To avoid this, we customize the ajax call:
		jQuery.ajax({
			type: "GET",
			url: path,
			dataType: "text",
			processData: false,
			cache: false,
			complete: function(xhr, textStatus) {
				if((!xhr.status && location.protocol === "file:") || (xhr.status >= 200 && xhr.status < 300) || xhr.status === 304)
					callback(true, meta, xhr.responseText, path, xhr)
				else
					callback(false, meta, null, path, xhr)
			}
		})
		//# rename onExternalTiddlerLoad into internalizeAndRegister?
	},
	onExternalTiddlerLoad: function(success, meta, responseText) {
		if(!success) return; //# notify somehow? may fail because file is not created yet or ...
		const tiddler = config.macros.external.internalizeTiddler(meta, responseText);
		store.addTiddler(tiddler);
		//# what if tiddler already exists?
		if(meta.isPlugin) {
			// make it look normally
			if (!tiddler.tags.includes('systemConfig')) {
				tiddler.tags.push('systemConfig');
			}
			const author = store.getTiddlerText(tiddler.title + "::Author");
			if(author) {
				tiddler.creator = tiddler.creator || author;
				tiddler.modifier = tiddler.modifier || tiddler.creator;
			}

			eval(tiddler.text);
			// for plugins introducing macros, formatters etc (may be adjusted in the future)
			story.refreshAllTiddlers();
		}
		//meta.lastLoaded = responseText;
	},
	saveExternal: function(meta, callback) {
		const fullPath = getFullPath(meta.fileName, meta.tiddlerName, this.getExtension(meta));
		// we don't try to save remote files (yet)
		if(!isLocalAbsolutePath(fullPath)) {
			//# if(callback) callback(.., '[saving remote is not supported]')
			return;
		}
		const localPath = getLocalPath(fullPath);

		const contentToSave = this.externalizeTiddler(meta);
		// save only if have something to save
		//if(contentToSave != meta.lastLoaded) {
			saveFile(localPath, contentToSave);
			//# get result of saving, return it
			//# or move externalizing into a separate helper?
		//	meta.lastLoaded = contentToSave;
			//# this assumes saving didn't fail, which may be wrong
		//}

		//# if(callback) callback(.., '[...]')
	},
	saveAll: function() {
		let overallSuccess = true;
		for(let meta of this.tiddlersMeta) {
			// a tiddler may got created after registration
			if(!meta.tiddler) {
				let tiddlerInStore = store.fetchTiddler(meta.tiddlerName);
				if(tiddlerInStore) {
					meta.tiddler = tiddlerInStore;
				} else
					// tiddler doesn't exist and we do nothing
					continue;
					//# based on config, we can show a warning instead
			}
			//# if(meta.tiddler.title != meta.tiddlerName)
			//  means tiddler got renamed → change meta.tiddlerName &
			//  update this.listName . If store contains another tiddler
			//  with that name, still keep the registered one?
			overallSuccess = this.saveExternal(meta) && overallSuccess;
			//# if saving failed, do something! (.oO dirty, notifying)
		}
		return overallSuccess;
	}
};

//# see implementations in STP (share to the core?)
function isAbsolutePath(path) {
	// covers http:, https:, file:, other schemas, windows paths (D:\...)
	if(/^\w+\:/.exec(path))
		return true;
	// unix absolute paths, starting with /
	if(/^\//.exec(path))
		return true;
	return false;
}
function isLocalAbsolutePath(path) {
	//# rename? we're going to check whether an absolute path is local, not path is absolute local
	return /^\w\:/.exec(path) || /^\//.exec(path) || /^file\:/.exec(path);
}
function getFullPath(subPath, nameFallback, extension) {
	const fileNamePosition = subPath.lastIndexOf('/') + 1;
	const fileName = subPath.substr(fileNamePosition);
	if(fileName && fileName.indexOf('.') == -1)
		subPath += '.' + extension;
	if(!fileName)
		subPath += nameFallback + '.' + extension;

	if(isAbsolutePath(subPath))
		return subPath;

	const url = window.location.toString();
	const base = url.substr(0, url.lastIndexOf('/') + 1);
	return base + subPath;
}

//# ideally, don't save main store if it were not changed
if(!config.macros.external.orig_saveChanges) {
	config.macros.external.orig_saveChanges = saveChanges;
	saveChanges = function(onlyIfDirty, tiddlers) {
		config.macros.external.saveAll();
		//# should we do smth about setDirty (if saving of a tiddler failed)?

		return config.macros.external.orig_saveChanges.apply(this, arguments);
	}
}

// hijack method of store (since not present in TiddlyWiki.prototype)
if(!config.macros.external.orig_deleteTiddler) {
	config.macros.external.orig_deleteTiddler = store.deleteTiddler;
	store.deleteTiddler = function(title) {
		var registeredMeta = config.macros.external.getMetaFor(title);
		if(registeredMeta) registeredMeta.tiddler = null;

		return config.macros.external.orig_deleteTiddler.apply(this, arguments);
	}
}
//}}}