botscripten
Version:
Craft rich bot conversations using the Twine/Twee format
335 lines (296 loc) • 6.5 kB
CSS
/**
* Global styles
*/
:root {
--nav-height: 46px;
--nav-buffer: 10px;
--max-width: 768px;
--bg-color: #4d5263; /*global chat bg color*/
--user-color: #7aaebb; /*user name & placeholder avatar bg*/
--speaker-color: rgb(
136,
136,
136
); /*default color for speaker name & placeholder avatar bg*/
--directive-border: #c3c3c3;
--navbar-bg-color: #fff;
--passage-bg-color: #fff;
--passage-text-color: #222;
}
body {
font-family: "Lucida Sans", "Lucida Sans Regular", "Lucida Grande",
"Lucida Sans Unicode", Geneva, Verdana, sans-serif;
font-size: 16px;
margin: 0;
padding: 0;
}
body.proof twine {
padding: 50px;
font-size: 12px;
}
#twine-user-stylesheet,
#twine-user-script,
twine,
.proof #runtime main,
.proof #user-response-panel {
display: none ;
}
.proof twine,
.proof twine * {
display: block ;
font-family: monospace;
white-space: pre;
}
/**
* Nav (available in all modes)
*/
nav {
position: fixed;
z-index: 1;
height: var(--nav-height);
background: var(--navbar-bg-color);
width: 100vw;
max-width: var(--max-width);
top: 0;
border: 5px solid var(--speaker-color);
border-top: 0;
border-left: 0;
border-right: 0;
}
nav h1 {
margin: 0;
font-size: 26px;
padding: 10px 1em 0 1em;
line-height: 26px;
}
#nav-reset {
position: relative;
}
#toggles {
position: absolute;
right: 1em;
top: 50%;
}
#toggles label {
margin-left: 1em;
}
twine,
#runtime {
margin-top: var(--nav-height);
}
/*
* Proofing styles
* Set when body has a .proof class. Hides the majority of runtime
* and uses pseudoclasses to display the information in a twee-like
* format
*/
.proof tw-storydata::before {
content: ":: StoryTitle\A"attr(name);
color: green;
}
.proof tw-passagedata::before {
content: ":: " attr(name) " [" attr(tags) "]";
color: blue;
margin: 1em 0 0 0;
display: block;
font-weight: bold;
}
.proof tw-passagedata.start::before {
content: "🚀 :: " attr(name) " [" attr(tags) "]";
}
.proof tw-passagedata + tw-passagedata {
border-top: 1pt dashed black;
padding: 1em 0;
margin: 1em 0 0 0;
}
.proof #runtime {
position: absolute;
top: 0;
}
/**
* Runtime (interactive) code
* All runtime items are in the section#runtime
*/
#runtime {
display: flex;
flex-direction: column;
height: calc(100vh - var(--nav-height));
max-height: calc(100% - var(--nav-height));
max-width: var(--max-width);
}
#runtime main {
flex: 1 1 auto;
background-color: var(--bg-color);
padding: var(--nav-buffer) 15px 15px 15px;
}
/**
* Chat passages
* These are repeatable passages added in the interactive code.
* They are the "chat lines" and appear in the history, the
* passage, and are also used as part of the "wave"
*/
.chat-passage-reset {
position: relative;
}
.chat-passage:before {
content: attr(data-speaker);
display: block;
font-size: 0.75rem;
text-transform: capitalize;
color: var(--speaker-color);
}
.chat-passage {
background: var(--passage-bg-color);
margin: 0 0 1em 0;
padding: 0.33em;
}
.chat-passage p {
margin: 0;
}
.chat-passage-wrapper {
display: flex;
flex-direction: row;
}
.chat-passage-wrapper[data-speaker="you"] {
flex-direction: row-reverse;
}
.chat-passage-wrapper .chat-passage {
margin-left: 45px;
}
.chat-passage-wrapper[data-speaker="you"] .chat-passage {
margin-right: 45px;
}
.chat-passage-wrapper:before {
margin-right: 5px;
position: absolute;
vertical-align: top;
content: "";
width: 30px;
height: 30px;
background-size: 30px 30px;
border-radius: 15px;
background-color: var(--speaker-color);
}
.chat-passage-wrapper[data-speaker="you"]:before {
display: none;
}
.chat-passage-wrapper[data-speaker="you"]:after {
margin-left: -30px;
position: absolute;
top: 0;
right: 0;
vertical-align: top;
content: "";
width: 30px;
height: 30px;
background-size: 30px 30px;
border-radius: 15px;
background-color: var(--user-color);
}
/**
* Directives
* When enabled, directives show the "behind the scenes" items that would
* have been otherwise called as part of a given step. They are inserted
* **first** in a conversation to simulate how they are handled in a
* botscripten engine.
*/
body.show-directives .directives {
display: block;
}
.directives {
display: none;
font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console",
"Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono",
"Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier,
monospace;
font-size: 12px;
}
.directive {
white-space: pre;
border: 1px dashed var(--directive-border);
position: relative;
overflow-x: auto;
padding-top: 20px;
color: var(--passage-bg-color);
margin-bottom: 1em;
}
.directive::after {
content: attr(name);
position: absolute;
right: 2px;
top: 2px;
font-weight: bold;
font-size: 14px;
letter-spacing: 0.2em;
color: var(--passage-bg-color);
}
/**
* User response panel
* When presented with a choice, the user will select
* a response from this panel to continue the conversation
*/
#user-response-wrapper {
padding-right: 15px;
padding-left: 15px;
flex: 1 1 auto;
display: flex;
flex-direction: column;
justify-content: end;
border-top: 3px solid var(--directive-border);
}
#user-response-panel {
height: 100px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
#user-response-panel .user-response {
display: inline-block;
padding: 0.5rem;
margin: 0.25rem;
background-color: white;
color: #333;
border-top: 2px solid transparent;
transition: border-color 0.15s ease-in;
}
#user-response-panel .user-response:hover {
text-decoration: none;
border-color: var(--user-color);
}
/**
* Typing animation
* Always active, the wave shows typing dots and its visibility
* is controlled by the chat system
*/
#animation-container .wave {
position: relative;
text-align: center;
margin-left: auto;
margin-right: auto;
}
#animation-container .dot {
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
margin-right: 2px;
background: var(--passage-text-color);
animation: wave 1.2s ease-in-out infinite;
}
#animation-container .dot:nth-child(2) {
animation-delay: 0.1s;
}
#animation-container .dot:nth-child(3) {
animation-delay: 0.2s;
}
@keyframes wave {
0%,
50%,
100% {
transform: initial;
}
25% {
transform: translateY(-15px);
}
}