UNPKG

botscripten

Version:

Craft rich bot conversations using the Twine/Twee format

335 lines (296 loc) 6.5 kB
/** * 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 !important; } .proof twine, .proof twine * { display: block !important; 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); } }