1
0
mirror of https://github.com/flarum/core.git synced 2025-07-31 21:50:50 +02:00
* Replace gulp with webpack and npm scripts for JS compilation
* Set up Travis CI to commit compiled JS
* Restructure `js` directory; only one instance of npm, forum/admin are "submodules"
* Refactor JS initializers into Application subclasses
* Maintain partial compatibility API (importing from absolute paths) for extensions
* Remove minification responsibility from PHP asset compiler
* Restructure `less` directory
This commit is contained in:
Toby Zerner
2018-06-20 13:20:31 +09:30
committed by GitHub
parent d234badbb2
commit 3f683dd6ee
235 changed files with 9351 additions and 57639 deletions

63
less/common/Alert.less Normal file
View File

@@ -0,0 +1,63 @@
.Alert {
padding: 12px 16px;
border-radius: @border-radius;
line-height: 1.5;
.Alert--color(@alert-color, @alert-bg);
}
.Alert--error {
.Alert--color(@alert-error-color, @alert-error-bg);
}
.Alert--success {
.Alert--color(@alert-success-color, @alert-success-bg);
a, a:hover {
text-decoration: underline;
}
}
.Alert--color(@color; @background) {
background: @background;
&,
a,
a:hover,
.Button,
.Button:hover,
.Button:active,
.Button.active,
.Button:focus,
.Button.focus {
color: @color;
}
}
.Alert-controls {
list-style-type: none;
padding: 0;
margin: 0 -8px 0 8px;
display: inline-block;
> li {
display: inline-block;
margin: 0 5px;
> a, > .Button {
text-transform: uppercase;
font-size: 12px;
font-weight: bold;
&.disabled {
cursor: default;
text-decoration: none;
opacity: 0.5;
}
&:hover {
text-decoration: underline;
}
}
> .Button {
margin: -10px;
vertical-align: 0;
}
}
}

View File

@@ -0,0 +1,12 @@
.AlertManager {
position: fixed;
bottom: 20px;
left: 20px;
z-index: @zindex-alerts;
.Alert {
display: inline-block;
margin-top: 20px;
.box-shadow(0 2px 6px @shadow-color);
}
}

309
less/common/App.less Normal file
View File

@@ -0,0 +1,309 @@
.App {
position: relative !important;
padding-top: @header-height;
padding-bottom: 50px;
overflow-x: hidden;
min-height: 100vh;
@media @phone {
padding-top: @header-height-phone;
}
}
// Fix a solid white box to the top of the viewport. This toolbar's contents
// will differ depending on the device: on phones it will be content
// controls, whereas on desktops it will be the header. We will overlay
// these things on top of it later.
.App:before {
content: " ";
.header-background();
border-bottom: 0;
position: absolute;
.affix& {
position: fixed;
}
.scrolled& {
.box-shadow(0 2px 6px @shadow-color);
}
}
// PHONES: Somewhere on the page there will be a .App-backControl, a
// .App-primaryControl, and a .App-titleControl. We will position these on the
// left, right, and center of the header respectively.
@media @phone {
.App-primaryControl, .App-titleControl, .App-backControl {
position: absolute !important;
z-index: @zindex-header + 1;
top: 0 !important;
margin: 0;
.App.affix &, .Composer & {
position: fixed !important;
}
> .Button {
float: none;
background: transparent !important;
.box-shadow(~"none !important");
height: @header-height-phone;
width: auto;
padding: 13px !important;
margin: 0 !important;
&:active {
opacity: 0.5;
}
}
}
.App-primaryControl {
width: auto;
right: 0;
&.Dropdown {
.Button, .Button-caret {
display: none !important;
}
.Dropdown-toggle, .Button-icon {
display: block !important;
}
}
}
.App-primaryControl, .App-backControl {
> .Button {
color: @header-control-color !important;
.Button-icon {
display: block;
font-size: 20px;
}
.Button-label {
display: none;
}
}
}
.App-titleControl {
width: 200px;
left: 50%;
margin-left: -100px;
text-align: center;
color: @header-color !important;
&, > .Button {
font-size: 16px;
}
> .Button {
color: @header-color;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
}
.App-titleControl--text {
line-height: 46px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-weight: normal;
}
.App-backControl {
left: 0;
.Navigation-pin {
display: none;
}
}
}
// ------------------------------------
// Drawer
// On phones, the drawer is displayed in its semantic sense: as a drawer on
// the left side of the screen. On other devices, the drawer has no specific
// appearance.
@media @phone {
.drawerOpen {
overflow: hidden;
}
.App-drawer {
background: @header-bg;
width: @drawer-width;
position: fixed;
left: 0;
top: 0;
bottom: 0;
.box-shadow(0 2px 6px @shadow-color);
.translate3d(-@drawer-width - 6px, 0, 0);
.transition-transform(0.2s);
z-index: @zindex-modal;
.drawerOpen & {
-webkit-transform: none !important;
transform: none !important;
}
}
.drawer-backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: @zindex-modal-background;
background-color: @overlay-bg;
opacity: 0;
.transition(0.2s opacity);
&.in {
opacity: 0.9;
}
}
}
// ------------------------------------
// Header
.Header-controls {
margin: 0;
padding: 0;
list-style: none;
}
.Header-logo {
max-height: 30px;
vertical-align: middle;
// Prevent blurriness in Chrome
image-rendering: -webkit-optimize-contrast;
}
// On phones, the header is displayed inside of the drawer. We lay its
// contents out vertically.
@media @phone {
.App-header {
.container {
padding: 0;
}
}
.Header-navigation {
display: none;
}
.Header-title {
padding: 13px 10px;
font-size: 16px;
font-weight: normal;
margin: 0;
text-align: center;
}
.Header-controls {
margin-top: 10px;
> li {
padding: 0 10px 0;
}
.FormControl, .ButtonGroup, .Button {
width: 100%;
text-align: left;
}
.Dropdown-menu {
.ButtonGroup, .Button {
width: auto;
}
}
}
.Header-secondary .Search {
margin: 10px 0;
}
}
// On other devices, we stick the header up the top of the page, overlaying
// the page toolbar that we styled earlier. We lay its contents out
// horizontally.
@media @phone {
.App-drawer {
& when (@config-colored-header = true) {
.light-contents(@header-color, @header-control-bg, @header-control-color);
}
}
}
@media @tablet-up {
.App-navigation {
display: none;
}
.App-header {
padding: 8px;
height: @header-height;
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: @zindex-header;
.affix & {
position: fixed;
}
& when (@config-colored-header = true) {
.light-contents(@header-color, @header-control-bg, @header-control-color);
}
}
.Header-navigation {
float: left;
margin-right: 25px;
}
.Header-controls {
&, > li {
display: inline-block;
vertical-align: middle;
}
}
.Header-primary {
float: left;
}
.Header-title {
float: left;
vertical-align: top;
font-size: 18px;
font-weight: normal;
margin: 0 15px 0 0;
line-height: 34px;
}
.Header-secondary {
float: right;
.Search {
margin-right: 10px;
}
}
}
@media @tablet {
.Header-secondary .Search {
input:not(:focus) {
width: 1px;
background: transparent;
}
&:not(.active) input {
padding-right: 0;
}
}
}
// ------------------------------------
// Content Area
.App-content {
border-top: 1px solid @control-bg;
}
// On phones, the content area overlays the drawer, so we must give it a
// background and min-height so it cannot be seen through. When the drawer is
// meant to be open, we slide the content to the right to reveal the drawer.
@media @phone {
.App-content {
background: @body-bg;
width: 100%;
min-height: 100vh;
padding-bottom: 50px;
}
}

28
less/common/Avatar.less Normal file
View File

@@ -0,0 +1,28 @@
.Avatar {
display: inline-block;
box-sizing: content-box;
color: #fff;
text-align: center;
vertical-align: top;
background-color: @control-bg;
font-weight: normal;
.Avatar--size(48px);
img {
display: inline-block;
width: 100%;
height: 100%;
border-radius: 100%;
vertical-align: top;
// Prevent blurriness in Chrome
image-rendering: -webkit-optimize-contrast;
}
}
.Avatar--size(@size) {
width: @size;
height: @size;
border-radius: @size;
font-size: @size / 2;
line-height: @size;
}

38
less/common/Badge.less Normal file
View File

@@ -0,0 +1,38 @@
.Badge {
.Badge--size(22px);
background: @muted-color;
color: #fff;
display: inline-block;
vertical-align: middle;
text-align: center;
.box-shadow(0 2px 4px @shadow-color);
.Badge-label {
display: none;
}
}
.Badge--size(@size) {
width: @size;
height: @size;
border-radius: @size / 2;
line-height: @size - 1px;
&, .Badge-icon {
font-size: 0.56 * @size;
}
}
.badges {
margin: 0;
padding: 0;
list-style: none;
&, > li {
display: inline-block;
}
}
.Badge--hidden {
background: #888;
}

240
less/common/Button.less Normal file
View File

@@ -0,0 +1,240 @@
//
// Button groups
// --------------------------------------------------
// Make the div behave like a button
.ButtonGroup {
position: relative;
display: inline-block;
vertical-align: middle;
> .Button {
position: relative;
float: left;
// Bring the "active" button to the front
&:hover,
&:focus,
&:active,
&.active {
z-index: 2;
}
&:not(:first-child):not(:last-child):not(.Dropdown-toggle) {
border-radius: 0;
}
&:first-child:not(:last-child):not(.Dropdown-toggle) {
margin-left: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
&:last-child:not(:first-child), &.Dropdown-toggle:not(:first-child) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
.Button + .Button {
margin-left: 1px;
}
}
//
// Buttons
// --------------------------------------------------
.Button {
display: inline-block;
margin-bottom: 0; // For input.btn
text-align: center;
vertical-align: middle;
cursor: pointer;
white-space: nowrap;
line-height: 20px;
padding: 8px 13px;
border-radius: @border-radius;
.user-select(none);
.Button--color(@control-color, @control-bg);
border: 0;
&:hover {
text-decoration: none;
}
&:active,
&.active,
.open > &.Dropdown-toggle {
.box-shadow(inset 0 3px 5px rgba(0, 0, 0, .125));
outline: none;
}
&:focus,
&.focus {
outline: none;
}
&.disabled,
&[disabled],
fieldset[disabled] & {
cursor: default;
opacity: 0.65;
.box-shadow(none);
}
a& {
&.disabled,
fieldset[disabled] & {
pointer-events: none; // Future-proof disabling of clicks on `<a>` elements
}
}
.Button-label {
.transition(margin-right 0.1s);
}
.LoadingIndicator {
color: inherit;
margin: 0 -5px 0 -15px;
}
&.loading {
.Button-label {
margin-right: 20px;
}
}
}
.Button--color(@color; @background) {
color: @color;
background: @background;
&:hover,
&:focus,
&.focus {
background-color: darken(fadein(@background, 5%), 5%);
}
&:active,
&.active,
.open > .Dropdown-toggle& {
background-color: darken(fadein(@background, 10%), 10%);
}
&.disabled,
&[disabled],
fieldset[disabled] & {
background: @background;
}
}
.Button--square {
padding-left: 9px;
padding-right: 9px;
}
.Button--rounded {
border-radius: 18px;
}
.Button--flat {
background: transparent;
border-radius: 18px;
}
.Button--link {
background: transparent !important;
&:hover {
background: transparent !important;
color: @link-color;
}
&:active,
&.active,
&:focus,
&.focus,
.open > &.Dropdown-toggle {
background: transparent !important;
.box-shadow(none);
color: @link-color;
}
}
.Button--text {
background: transparent !important;
padding: 0;
color: inherit !important;
line-height: inherit;
&:hover {
text-decoration: underline;
}
&:active,
&.active,
.open > &.Dropdown-toggle {
.box-shadow(none);
}
}
.Button--primary {
.Button--color(@body-bg, @primary-color);
font-weight: bold;
padding-left: 20px;
padding-right: 20px;
.Button-icon {
display: none;
}
}
.Button--danger {
.Button--color(@control-danger-color, @control-danger-bg);
}
.Button--more {
padding: 2px 4px;
line-height: 1;
.Button-icon {
margin: 0;
}
}
.Button--block {
display: block;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
// Vertically space out multiple block buttons
+ .Button--block {
margin-top: 5px;
}
}
// Little round icon buttons
.Button--icon {
width: 36px;
text-align: center;
padding: 8px 0;
.Button-label, .Button-caret {
display: none;
}
.Button-icon {
font-size: 16px;
vertical-align: -1px;
margin: 0;
}
}
.SessionDropdown .Dropdown-toggle {
border-radius: 18px;
.Avatar {
margin: -2px 5px -2px -6px;
.Avatar--size(24px);
}
}
.Button-icon {
margin-right: 7px;
}
.Button-icon,
.Button-caret {
font-size: 14px;
}
.Button-caret {
margin-left: 7px;
}
.Button-badge {
font-size: 12px;
font-weight: bold;
margin-left: 10px;
}

69
less/common/Checkbox.less Normal file
View File

@@ -0,0 +1,69 @@
.Checkbox {
display: block;
cursor: pointer;
margin: 0;
& input[type=checkbox] {
display: none;
}
}
.Checkbox--switch {
padding-left: 65px;
margin: 5px 0;
.Checkbox-display {
float: left;
margin-left: -65px;
margin-top: -4px;
.LoadingIndicator {
display: inline-block;
margin-left: 10px;
}
}
}
.Checkbox--switch .Checkbox-display {
width: 50px;
height: 28px;
padding: 3px;
position: relative;
border-radius: 14px;
background: @control-bg;
.transition(background-color 0.2s);
.on& {
background: #58A400;
}
&:before {
position: absolute;
width: 22px;
height: 22px;
padding: 0;
left: 3px;
.transition(~"opacity 0.2s, left 0.2s");
.on& {
left: 25px;
}
}
&:before {
content: ' ';
background: @body-bg;
border-radius: 11px;
box-shadow: 0 2px 4px @shadow-color;
}
}
.Checkbox-display {
font-size: 14px;
.on & {
color: #58A400;
}
.off & {
color: #D0021B;
}
.disabled & {
color: @muted-more-color !important;
}
}

232
less/common/Dropdown.less Normal file
View File

@@ -0,0 +1,232 @@
.Dropdown {
position: relative;
}
.Dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: @zindex-dropdown;
display: none;
min-width: 160px;
padding: 8px 0;
margin: 7px 0;
background: @body-bg;
border-radius: @border-radius;
.box-shadow(0 2px 6px @shadow-color);
list-style: none;
text-align: left;
color: @text-color;
font-size: 13px;
line-height: 1.5;
.open & {
display: block;
}
> li {
> a, > button, > span {
padding: 8px 15px;
display: block;
width: 100%;
color: @text-color;
border-radius: 0;
border: 0;
background: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.box-shadow(none);
text-align: left;
font-size: 13px;
font-weight: normal;
text-decoration: none;
&.hasIcon {
padding-left: 40px;
}
.Button-icon {
float: left;
margin-left: -25px;
margin-top: 2px;
width: 16px;
text-align: center;
}
&.disabled {
opacity: 0.4;
background: none !important;
}
}
> a, > button {
&:hover {
background: @control-bg;
}
&:focus {
outline: none;
}
}
&.active {
> a, > button {
background: @control-bg;
}
}
}
}
.Dropdown-menu--top {
top: auto;
bottom: 100%;
}
.Dropdown-menu--right {
left: auto;
right: 0;
}
.Dropdown-header {
padding: 10px 15px;
color: @heading-color;
text-transform: uppercase;
font-size: 12px;
font-weight: bold;
margin-top: 8px;
border-top: 1px solid @control-bg;
white-space: nowrap;
&:first-child {
margin-top: -8px;
border-top: 0;
}
}
.Dropdown-separator {
margin: 8px 0;
background-color: @control-bg;
height: 1px;
}
.dropdown-backdrop {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
z-index: (@zindex-dropdown - 10);
}
.Dropdown--split {
.Dropdown-toggle .Button-icon {
display: none;
}
.Dropdown-toggle .Button-caret {
display: inline;
margin: 0;
}
&.itemCount1 {
.Button {
border-radius: @border-radius !important;
}
.Dropdown-toggle {
display: none;
}
}
@media @tablet-up {
.Dropdown-menu li:first-child {
&, + li.Dropdown-separator {
display: none;
}
}
}
}
.Dropdown--expanded() {
.Dropdown-toggle {
display: none;
}
.Dropdown-menu {
display: block;
border: 0;
width: auto;
margin: 0;
padding: 0;
min-width: 0;
float: none;
position: static;
background: none;
.box-shadow(none);
}
}
@media @phone {
.Dropdown.open {
z-index: @zindex-modal;
}
.Dropdown .Dropdown-menu {
margin: 0;
position: fixed;
left: 0 !important;
right: 0 !important;
width: auto !important;
bottom: 0;
top: auto;
padding: 0;
padding-bottom: 40px !important;
display: block;
max-height: 70vh;
border-radius: 0;
.box-shadow(0 2px 6px @shadow-color);
visibility: hidden;
overflow: auto;
-webkit-overflow-scrolling: touch;
.translate3d(0, 70vh, 0);
.transition-transform(~" 0.3s, visibility 0s 0.3s");
> li {
> a, > button {
background: @body-bg;
font-size: 16px;
padding: 15px 20px;
&.hasIcon {
padding-left: 50px;
}
.Button-icon {
font-size: 16px;
margin-left: -30px;
}
&:hover {
background: @control-bg;
}
}
}
> .active {
> a, > button {
&, &:hover {
background: @primary-color !important;
color: #fff !important;
}
}
}
.open& {
-webkit-transform: none;
transform: none;
visibility: visible;
transition-delay: 0s;
}
}
.Dropdown-separator {
margin: 0;
}
.dropdown-backdrop {
background: fade(@secondary-color, 90%);
opacity: 0;
.transition(~"opacity 0.3s");
.translate3d(0, 0, 0);
.open & {
opacity: 1;
}
}
}

41
less/common/Form.less Normal file
View File

@@ -0,0 +1,41 @@
.Form-group {
margin-bottom: 24px;
&:last-child {
margin-bottom: 0 !important;
}
}
.Form--centered {
text-align: center;
.FormControl[type=text],
.FormControl[type=email],
.FormControl[type=password],
.Button {
margin: 0 auto;
text-align: center;
height: 50px;
padding: 15px 20px;
font-size: 15px;
@media @phone {
font-size: 16px; // minimum font-size required to prevent page zoom on focus in iOS 10
}
}
.Form-group {
margin-bottom: 12px;
}
.checkbox {
text-align: left;
}
}
.Form-group > label {
font-size: 14px;
font-weight: bold;
margin-bottom: 10px;
color: @text-color;
display: block;
}

View File

@@ -0,0 +1,51 @@
.FormControl {
display: block;
width: 100%;
height: 36px;
padding: 8px 13px;
font-size: 13px;
line-height: 1.5;
color: @control-color;
background-color: @control-bg;
border: 2px solid transparent;
border-radius: @border-radius;
.transition(~"border-color .15s, background .15s");
-webkit-appearance: none;
&:focus,
&.focus {
background-color: @body-bg;
color: @text-color;
border-color: @primary-color;
outline: none;
}
// Placeholder
.placeholder(@control-color);
// Disabled and read-only inputs
&[disabled],
&[readonly],
fieldset[disabled] & {
opacity: 0.5;
}
&[disabled],
fieldset[disabled] & {
cursor: disallowed;
}
textarea& {
height: auto;
}
@media @phone {
font-size: 16px; // minimum font-size required to prevent page zoom on focus in iOS 10
}
}
.helpText {
font-size: 12px;
line-height: 1.5em;
margin-bottom: 10px;
color: @muted-color;
}

View File

@@ -0,0 +1,14 @@
// ------------------------------------
// Loading Indicators
.LoadingIndicator {
position: relative;
color: @muted-color;
}
.LoadingIndicator--inline {
display: inline-block;
width: 25px;
}
.LoadingIndicator--block {
height: 100px;
}

210
less/common/Modal.less Normal file
View File

@@ -0,0 +1,210 @@
// ------------------------------------
// Modals
// Kill the scroll on the body
.modal-open {
overflow: hidden;
}
// Modal background
.modal-backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: @zindex-modal-background;
background-color: @overlay-bg;
opacity: 0;
.transition(0.2s opacity);
&.in {
opacity: 1;
}
}
// Container that the modal scrolls within
.ModalManager {
display: none;
overflow: hidden;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: @zindex-modal;
-webkit-overflow-scrolling: touch;
// When fading in the modal, animate it to slide down
.Modal {
.scale(0.9);
.transition-transform(0.2s ease-out);
}
&.in .Modal {
.scale(1);
}
}
.modal-open .ModalManager {
overflow-x: hidden;
overflow-y: auto;
}
// Shell div to position the modal with bottom padding
.Modal {
position: relative;
width: auto;
margin: 10px;
max-width: 600px;
}
// Actual modal
.Modal-content {
position: relative;
background-color: @body-bg;
background-clip: padding-box;
margin: 0 auto;
overflow: hidden;
}
// Measure scrollbar width for padding body during modal show/hide
.modal-scrollbar-measure {
position: absolute;
top: -9999px;
width: 50px;
height: 50px;
overflow: scroll;
}
.Modal-alert {
text-align: center;
.Alert {
border-radius: 0;
}
.Alert-controls {
margin: 0;
display: block;
}
}
.Modal-body {
background-color: @control-bg;
padding: 25px 30px;
color: @control-color;
.FormControl {
background-color: @body-bg;
color: @text-color;
}
.Form--centered {
.helpText {
font-size: 14px;
line-height: 1.5em;
margin-bottom: 25px;
text-align: left;
}
}
}
.Modal-footer {
border: 0;
padding: 20px;
text-align: center;
color: @muted-color;
}
.Modal-loading {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: fade(@body-bg, 90%);
opacity: 0;
pointer-events: none;
border-radius: @border-radius;
.transition(opacity 0.2s);
&.active {
opacity: 1;
pointer-events: auto;
}
}
@media @phone {
.ModalManager.fade {
opacity: 1;
}
.ModalManager {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
overflow: auto;
.transition-transform(0.2s);
.translate3d(0, 100vh, 0);
&.in {
-webkit-transform: none !important;
transform: none !important;
}
&:before {
content: " ";
.header-background();
position: absolute;
}
}
.Modal {
margin: 0;
-webkit-transform: none !important;
transform: none !important;
}
.Modal-content {
border-radius: 0;
border: 0;
min-height: 100vh;
padding-top: @header-height-phone;
.box-shadow(none);
}
.Modal-header {
padding: 0;
border: 0;
min-height: 0;
}
}
@media @tablet-up {
.Modal {
margin: 120px auto;
}
.Modal-close {
position: absolute;
right: 10px;
top: 10px;
z-index: 1;
}
.Modal-content {
border: 0;
border-radius: @border-radius;
.box-shadow(0 7px 15px @shadow-color);
}
.Modal--small {
max-width: 375px;
}
.Modal--large {
max-width: 800px;
}
.Modal-header {
text-align: center;
border: 0;
padding: 25px;
& h3 {
font-size: 20px;
font-weight: normal;
margin: 0;
}
}
}

View File

@@ -0,0 +1,60 @@
.Navigation-back {
z-index: 3 !important; // z-index of an active .btn-group .btn is 2
border-radius: @border-radius !important;
.transition(border-radius 0.2s);
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
padding-left: 8px;
padding-right: 8px;
.icon {
font-size: 14px;
}
}
.Navigation-pin {
display: none;
opacity: 0;
margin-left: -5px !important;
border-radius: 0 @border-radius @border-radius 0;
.transition(~"opacity 0.2s, margin-left 0.2s");
.icon {
.rotate(45deg);
}
}
@media @desktop-hd {
.Navigation-pin {
display: block;
}
.hasPane.panePinned, .hasPane.paneShowing {
.Navigation-back {
border-radius: @border-radius 0 0 @border-radius !important;
}
.Navigation-pin {
opacity: 1;
margin-left: 1px !important;
}
}
.hasPane.panePinned .Navigation-pin .icon {
.rotate(0deg);
}
}
.Navigation-drawer.new {
position: relative;
&:after {
content: ' ';
display: block;
position: absolute;
background: @primary-color;
top: 10px;
right: 10px;
width: 14px;
height: 14px;
border-radius: 7px;
border: 2px solid @body-bg;
}
}

View File

@@ -0,0 +1,9 @@
.Placeholder {
margin-top: 40px;
p {
font-size: 1.4em;
color: @muted-more-color;
text-align: center;
}
}

81
less/common/Search.less Normal file
View File

@@ -0,0 +1,81 @@
.Search {
position: relative;
}
@media @tablet-up {
.Search {
.transition(margin-left 0.4s);
&.focused {
margin-left: -400px;
input, .Search-results {
width: 400px;
}
}
}
}
.Search-results {
max-height: 70vh;
overflow: auto;
left: auto;
right: 0;
@media @phone {
left: 0;
}
> li > a {
white-space: normal;
}
mark {
background: none;
padding: 0;
font-weight: bold;
color: inherit;
box-shadow: none;
}
}
.Search-input {
overflow: hidden;
color: @muted-color;
&:before {
.fa();
content: @fa-var-search;
float: left;
margin-right: -36px;
width: 36px;
font-size: 14px;
text-align: center;
position: relative;
padding: 7px 0;
line-height: 1.5;
pointer-events: none;
}
input {
float: left;
width: 225px;
padding-left: 32px;
padding-right: 32px;
.transition(all 0.4s);
box-sizing: inherit !important;
}
.Button {
float: left;
margin-left: -36px;
width: 36px !important;
outline: none;
}
}
.DiscussionSearchResult-excerpt {
margin-top: 3px;
color: @muted-color;
font-size: 11px;
}
.UserSearchResult .Avatar {
.Avatar--size(24px);
margin: -2px 10px -2px 0;
}

20
less/common/Select.less Normal file
View File

@@ -0,0 +1,20 @@
.Select {
display: inline-block;
vertical-align: middle;
select {
display: inline-block;
width: auto;
-webkit-appearance: none;
-moz-appearance: none;
padding-right: 30px;
cursor: pointer;
line-height: 1;
}
}
.Select-caret {
margin-left: -30px;
pointer-events: none;
color: @control-color;
.fa-fw();
}

72
less/common/Tooltip.less Normal file
View File

@@ -0,0 +1,72 @@
// ------------------------------------
// Tooltips
// Base class
.tooltip {
position: absolute;
z-index: @zindex-tooltip;
display: block;
font-size: 12px;
font-weight: normal;
line-height: 1.4;
opacity: 0;
.transition(0.15s opacity linear);
&.in { opacity: 1; }
&.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }
&.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }
&.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }
&.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }
}
// Wrapper for the tooltip content
.tooltip-inner {
max-width: 200px;
padding: 7px 12px;
color: @tooltip-color;
text-align: center;
text-decoration: none;
background-color: @tooltip-bg;
border-radius: @border-radius;
}
// Arrows
@tooltip-arrow-width: 5px;
.tooltip-arrow {
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.tooltip {
&.top .tooltip-arrow {
bottom: 0;
left: 50%;
margin-left: -@tooltip-arrow-width;
border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
border-top-color: @tooltip-bg;
}
&.right .tooltip-arrow {
top: 50%;
left: 0;
margin-top: -@tooltip-arrow-width;
border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;
border-right-color: @tooltip-bg;
}
&.left .tooltip-arrow {
top: 50%;
right: 0;
margin-top: -@tooltip-arrow-width;
border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;
border-left-color: @tooltip-bg;
}
&.bottom .tooltip-arrow {
top: 0;
left: 50%;
margin-left: -@tooltip-arrow-width;
border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;
border-bottom-color: @tooltip-bg;
}
}

31
less/common/common.less Normal file
View File

@@ -0,0 +1,31 @@
@import "fontawesome";
@import "fa-brands";
@import "fa-regular";
@import "fa-solid";
@fa-font-path: "./fonts";
@import "normalize";
@import "print";
@import "scaffolding";
@import "sideNav";
@import "mixins";
@import "App";
@import "Alert";
@import "AlertManager";
@import "Avatar";
@import "Badge";
@import "Button";
@import "Checkbox";
@import "Dropdown";
@import "Form";
@import "FormControl";
@import "LoadingIndicator";
@import "Modal";
@import "Navigation";
@import "Placeholder";
@import "Search";
@import "Select";
@import "Tooltip";
@import "variables";

5
less/common/mixins.less Normal file
View File

@@ -0,0 +1,5 @@
@import "mixins/border-radius.less";
@import "mixins/clearfix.less";
@import "mixins/light-contents.less";
@import "mixins/header-background.less";
@import "mixins/vendor-prefixes.less";

View File

@@ -0,0 +1,18 @@
// Single side border-radius
.border-top-radius(@radius) {
border-top-right-radius: @radius;
border-top-left-radius: @radius;
}
.border-right-radius(@radius) {
border-bottom-right-radius: @radius;
border-top-right-radius: @radius;
}
.border-bottom-radius(@radius) {
border-bottom-right-radius: @radius;
border-bottom-left-radius: @radius;
}
.border-left-radius(@radius) {
border-bottom-left-radius: @radius;
border-top-left-radius: @radius;
}

View File

@@ -0,0 +1,22 @@
// Clearfix
//
// For modern browsers
// 1. The space content is one way to avoid an Opera bug when the
// contenteditable attribute is included anywhere else in the document.
// Otherwise it causes space to appear at the top and bottom of elements
// that are clearfixed.
// 2. The use of `table` rather than `block` is only necessary if using
// `:before` to contain the top-margins of child elements.
//
// Source: http://nicolasgallagher.com/micro-clearfix-hack/
.clearfix() {
&:before,
&:after {
content: " "; // 1
display: table; // 2
}
&:after {
clear: both;
}
}

View File

@@ -0,0 +1,18 @@
.header-background() {
background: fade(@header-bg, 98%);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: @zindex-header;
border-bottom: 1px solid @control-bg;
.translate3d(0, 0, 0);
.transition(~"box-shadow 0.2s, -webkit-transform 0.2s");
@media @phone {
height: @header-height-phone;
}
@media @tablet-up {
height: @header-height;
}
}

View File

@@ -0,0 +1,36 @@
// This is a mixin which styles components (buttons, inputs, etc.) for use on
// dark backgrounds.
.light-contents(@color: #fff, @control-bg: fade(#000, 10%), @control-color: #fff) {
&, a {
color: @color;
}
.Button--link, .Search-input {
color: @control-color;
}
.FormControl {
background: @control-bg;
border: 0;
color: @control-color;
.placeholder(@control-color);
&:focus {
color: @color;
background: fadein(darken(@control-bg, 5%), 10%);
}
}
.Button, .Button:hover {
color: @control-color;
background: @control-bg;
}
.Button--flat {
background: transparent;
}
.Button:active,
.Button.active,
.Button:focus,
.Button.focus,
.open > .Dropdown-toggle.Button {
background: fadein(@control-bg, 5%);
color: @control-color;
}
}

View File

@@ -0,0 +1,227 @@
// Vendor Prefixes
//
// All vendor mixins are deprecated as of v3.2.0 due to the introduction of
// Autoprefixer in our Gruntfile. They will be removed in v4.
// - Animations
// - Backface visibility
// - Box shadow
// - Box sizing
// - Content columns
// - Hyphens
// - Placeholder text
// - Transformations
// - Transitions
// - User Select
// Animations
.animation(@animation) {
-webkit-animation: @animation;
-o-animation: @animation;
animation: @animation;
}
.animation-name(@name) {
-webkit-animation-name: @name;
animation-name: @name;
}
.animation-duration(@duration) {
-webkit-animation-duration: @duration;
animation-duration: @duration;
}
.animation-timing-function(@timing-function) {
-webkit-animation-timing-function: @timing-function;
animation-timing-function: @timing-function;
}
.animation-delay(@delay) {
-webkit-animation-delay: @delay;
animation-delay: @delay;
}
.animation-iteration-count(@iteration-count) {
-webkit-animation-iteration-count: @iteration-count;
animation-iteration-count: @iteration-count;
}
.animation-direction(@direction) {
-webkit-animation-direction: @direction;
animation-direction: @direction;
}
.animation-fill-mode(@fill-mode) {
-webkit-animation-fill-mode: @fill-mode;
animation-fill-mode: @fill-mode;
}
// Backface visibility
// Prevent browsers from flickering when using CSS 3D transforms.
// Default value is `visible`, but can be changed to `hidden`
.backface-visibility(@visibility){
-webkit-backface-visibility: @visibility;
-moz-backface-visibility: @visibility;
backface-visibility: @visibility;
}
// Drop shadows
//
// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
// supported browsers that have box shadow capabilities now support it.
.box-shadow(@shadow) {
-webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1
box-shadow: @shadow;
}
// Box sizing
.box-sizing(@boxmodel) {
-webkit-box-sizing: @boxmodel;
-moz-box-sizing: @boxmodel;
box-sizing: @boxmodel;
}
// CSS3 Content Columns
.content-columns(@column-count; @column-gap: @grid-gutter-width) {
-webkit-column-count: @column-count;
-moz-column-count: @column-count;
column-count: @column-count;
-webkit-column-gap: @column-gap;
-moz-column-gap: @column-gap;
column-gap: @column-gap;
}
// Optional hyphenation
.hyphens(@mode: auto) {
word-wrap: break-word;
-webkit-hyphens: @mode;
-moz-hyphens: @mode;
-ms-hyphens: @mode; // IE10+
-o-hyphens: @mode;
hyphens: @mode;
}
// Placeholder text
.placeholder(@color) {
// Firefox
&::-moz-placeholder {
color: @color;
opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
}
&:-ms-input-placeholder { color: @color; } // Internet Explorer 10+
&::-webkit-input-placeholder { color: @color; } // Safari and Chrome
}
// Transformations
.scale(@ratio) {
-webkit-transform: scale(@ratio);
-ms-transform: scale(@ratio); // IE9 only
-o-transform: scale(@ratio);
transform: scale(@ratio);
}
.scale(@ratioX; @ratioY) {
-webkit-transform: scale(@ratioX, @ratioY);
-ms-transform: scale(@ratioX, @ratioY); // IE9 only
-o-transform: scale(@ratioX, @ratioY);
transform: scale(@ratioX, @ratioY);
}
.scaleX(@ratio) {
-webkit-transform: scaleX(@ratio);
-ms-transform: scaleX(@ratio); // IE9 only
-o-transform: scaleX(@ratio);
transform: scaleX(@ratio);
}
.scaleY(@ratio) {
-webkit-transform: scaleY(@ratio);
-ms-transform: scaleY(@ratio); // IE9 only
-o-transform: scaleY(@ratio);
transform: scaleY(@ratio);
}
.skew(@x; @y) {
-webkit-transform: skewX(@x) skewY(@y);
-ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
-o-transform: skewX(@x) skewY(@y);
transform: skewX(@x) skewY(@y);
}
.translate(@x; @y) {
-webkit-transform: translate(@x, @y);
-ms-transform: translate(@x, @y); // IE9 only
-o-transform: translate(@x, @y);
transform: translate(@x, @y);
}
.translate3d(@x; @y; @z) {
-webkit-transform: translate3d(@x, @y, @z);
transform: translate3d(@x, @y, @z);
}
.rotate(@degrees) {
-webkit-transform: rotate(@degrees);
-ms-transform: rotate(@degrees); // IE9 only
-o-transform: rotate(@degrees);
transform: rotate(@degrees);
}
.rotateX(@degrees) {
-webkit-transform: rotateX(@degrees);
-ms-transform: rotateX(@degrees); // IE9 only
-o-transform: rotateX(@degrees);
transform: rotateX(@degrees);
}
.rotateY(@degrees) {
-webkit-transform: rotateY(@degrees);
-ms-transform: rotateY(@degrees); // IE9 only
-o-transform: rotateY(@degrees);
transform: rotateY(@degrees);
}
.perspective(@perspective) {
-webkit-perspective: @perspective;
-moz-perspective: @perspective;
perspective: @perspective;
}
.perspective-origin(@perspective) {
-webkit-perspective-origin: @perspective;
-moz-perspective-origin: @perspective;
perspective-origin: @perspective;
}
.transform-origin(@origin) {
-webkit-transform-origin: @origin;
-moz-transform-origin: @origin;
-ms-transform-origin: @origin; // IE9 only
transform-origin: @origin;
}
// Transitions
.transition(@transition) {
-webkit-transition: @transition;
-o-transition: @transition;
transition: @transition;
}
.transition-property(@transition-property) {
-webkit-transition-property: @transition-property;
transition-property: @transition-property;
}
.transition-delay(@transition-delay) {
-webkit-transition-delay: @transition-delay;
transition-delay: @transition-delay;
}
.transition-duration(@transition-duration) {
-webkit-transition-duration: @transition-duration;
transition-duration: @transition-duration;
}
.transition-timing-function(@timing-function) {
-webkit-transition-timing-function: @timing-function;
transition-timing-function: @timing-function;
}
.transition-transform(@transition) {
-webkit-transition: -webkit-transform @transition;
-moz-transition: -moz-transform @transition;
-o-transition: -o-transform @transition;
transition: transform @transition;
}
// User select
// For selecting text on the page
.user-select(@select) {
-webkit-user-select: @select;
-moz-user-select: @select;
-ms-user-select: @select; // IE10+
user-select: @select;
}

427
less/common/normalize.less vendored Normal file
View File

@@ -0,0 +1,427 @@
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
//
// 1. Set default font family to sans-serif.
// 2. Prevent iOS text size adjust after orientation change, without disabling
// user zoom.
//
html {
font-family: sans-serif; // 1
-ms-text-size-adjust: 100%; // 2
-webkit-text-size-adjust: 100%; // 2
}
//
// Remove default margin.
//
body {
margin: 0;
}
// HTML5 display definitions
// ==========================================================================
//
// Correct `block` display not defined for any HTML5 element in IE 8/9.
// Correct `block` display not defined for `details` or `summary` in IE 10/11
// and Firefox.
// Correct `block` display not defined for `main` in IE 11.
//
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
//
// 1. Correct `inline-block` display not defined in IE 8/9.
// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
//
audio,
canvas,
progress,
video {
display: inline-block; // 1
vertical-align: baseline; // 2
}
//
// Prevent modern browsers from displaying `audio` without controls.
// Remove excess height in iOS 5 devices.
//
audio:not([controls]) {
display: none;
height: 0;
}
//
// Address `[hidden]` styling not present in IE 8/9/10.
// Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
//
[hidden],
template {
display: none;
}
// Links
// ==========================================================================
//
// Remove the gray background color from active links in IE 10.
//
a {
background-color: transparent;
}
//
// Improve readability when focused and also mouse hovered in all browsers.
//
a:active,
a:hover {
outline: 0;
}
// Text-level semantics
// ==========================================================================
//
// Address styling not present in IE 8/9/10/11, Safari, and Chrome.
//
abbr[title] {
border-bottom: 1px dotted;
}
//
// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
//
b,
strong {
font-weight: bold;
}
//
// Address styling not present in Safari and Chrome.
//
dfn {
font-style: italic;
}
//
// Address variable `h1` font-size and margin within `section` and `article`
// contexts in Firefox 4+, Safari, and Chrome.
//
h1 {
font-size: 2em;
margin: 0.67em 0;
}
//
// Address styling not present in IE 8/9.
//
mark {
background: #ff0;
color: #000;
}
//
// Address inconsistent and variable font size in all browsers.
//
small {
font-size: 80%;
}
//
// Prevent `sub` and `sup` affecting `line-height` in all browsers.
//
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
// Embedded content
// ==========================================================================
//
// Remove border when inside `a` element in IE 8/9/10.
//
img {
border: 0;
}
//
// Correct overflow not hidden in IE 9/10/11.
//
svg:not(:root) {
overflow: hidden;
}
// Grouping content
// ==========================================================================
//
// Address margin not present in IE 8/9 and Safari.
//
figure {
margin: 1em 40px;
}
//
// Address differences between Firefox and other browsers.
//
hr {
-moz-box-sizing: content-box;
box-sizing: content-box;
height: 0;
}
//
// Contain overflow in all browsers.
//
pre {
overflow: auto;
}
//
// Address odd `em`-unit font size rendering in all browsers.
//
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
// Forms
// ==========================================================================
//
// Known limitation: by default, Chrome and Safari on OS X allow very limited
// styling of `select`, unless a `border` property is set.
//
//
// 1. Correct color not being inherited.
// Known issue: affects color of disabled elements.
// 2. Correct font properties not being inherited.
// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
//
button,
input,
optgroup,
select,
textarea {
color: inherit; // 1
font: inherit; // 2
margin: 0; // 3
}
//
// Address `overflow` set to `hidden` in IE 8/9/10/11.
//
button {
overflow: visible;
}
//
// Address inconsistent `text-transform` inheritance for `button` and `select`.
// All other form control elements do not inherit `text-transform` values.
// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
// Correct `select` style inheritance in Firefox.
//
button,
select {
text-transform: none;
}
//
// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
// and `video` controls.
// 2. Correct inability to style clickable `input` types in iOS.
// 3. Improve usability and consistency of cursor style between image-type
// `input` and others.
//
button,
html input[type="button"], // 1
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; // 2
cursor: pointer; // 3
}
//
// Re-set default cursor for disabled elements.
//
button[disabled],
html input[disabled] {
cursor: default;
}
//
// Remove inner padding and border in Firefox 4+.
//
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
//
// Address Firefox 4+ setting `line-height` on `input` using `!important` in
// the UA stylesheet.
//
input {
line-height: normal;
}
//
// It's recommended that you don't attempt to style these elements.
// Firefox's implementation doesn't respect box-sizing, padding, or width.
//
// 1. Address box sizing set to `content-box` in IE 8/9/10.
// 2. Remove excess padding in IE 8/9/10.
//
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; // 1
padding: 0; // 2
}
//
// Fix the cursor style for Chrome's increment/decrement buttons. For certain
// `font-size` values of the `input`, it causes the cursor style of the
// decrement button to change from `default` to `text`.
//
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
//
// 1. Address `appearance` set to `searchfield` in Safari and Chrome.
// 2. Address `box-sizing` set to `border-box` in Safari and Chrome
// (include `-moz` to future-proof).
//
input[type="search"] {
-webkit-appearance: textfield; // 1
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; // 2
box-sizing: content-box;
}
//
// Remove inner padding and search cancel button in Safari and Chrome on OS X.
// Safari (but not Chrome) clips the cancel button when the search input has
// padding (and `textfield` appearance).
//
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
//
// Define consistent border, margin, and padding.
//
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
//
// 1. Correct `color` not being inherited in IE 8/9/10/11.
// 2. Remove padding so people aren't caught out if they zero out fieldsets.
//
legend {
border: 0; // 1
padding: 0; // 2
}
//
// Remove default vertical scrollbar in IE 8/9/10/11.
//
textarea {
overflow: auto;
}
//
// Don't inherit the `font-weight` (applied by a rule above).
// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
//
optgroup {
font-weight: bold;
}
// Tables
// ==========================================================================
//
// Remove most spacing between table cells.
//
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}

68
less/common/print.less Normal file
View File

@@ -0,0 +1,68 @@
/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
// ==========================================================================
// Print styles.
// Inlined to avoid the additional HTTP request: h5bp.com/r
// ==========================================================================
@media print {
*,
*:before,
*:after {
background: transparent !important;
color: #000 !important; // Black prints faster: h5bp.com/s
box-shadow: none !important;
text-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]:after {
content: " (" attr(href) ")";
}
abbr[title]:after {
content: " (" attr(title) ")";
}
// Don't show links that are fragment identifiers,
// or use the `javascript:` pseudo protocol
a[href^="#"]:after,
a[href^="javascript:"]:after {
content: "";
}
pre,
blockquote {
border: 1px solid #999;
page-break-inside: avoid;
}
thead {
display: table-header-group; // h5bp.com/t
}
tr,
img {
page-break-inside: avoid;
}
img {
max-width: 100% !important;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
}

View File

@@ -0,0 +1,150 @@
* {
&,
&:before,
&:after {
.box-sizing(border-box);
}
}
body {
background: @body-bg;
color: @text-color;
font-family: "Open Sans", Helvetica, Arial, sans-serif;
font-size: 13px;
line-height: 1.5;
overflow-y: scroll;
}
h1, h2, h3, h4, h5, h6 {
line-height: 1.3;
}
input,
button,
select,
textarea {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
a {
cursor: pointer;
color: @link-color;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
hr {
margin-top: 15px;
margin-bottom: 15px;
border: 0;
border-top: 2px solid @control-bg;
}
p {
margin: 0 0 10px;
}
.container {
margin-right: auto;
margin-left: auto;
padding-left: 15px;
padding-right: 15px;
.clearfix();
@media @tablet {
width: @screen-tablet;
}
@media @desktop {
width: @screen-desktop;
}
@media @desktop-hd {
width: @screen-desktop-hd;
}
}
.containerNarrow {
max-width: 600px;
margin: 0 auto;
}
mark {
background: #FFE300;
padding: 1px;
border-radius: @border-radius;
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
}
fieldset {
padding: 0;
margin: 0;
border: 0;
> ul > li {
margin-bottom: 10px;
}
}
legend {
font-size: 14px;
font-weight: bold;
margin-bottom: 10px;
color: @text-color;
}
input[type="search"] {
-webkit-appearance: none;
}
.checkbox {
display: block;
padding-left: 20px;
margin-bottom: 5px;
cursor: pointer;
input[type=checkbox],
input[type=radio] {
margin-left: -20px;
margin-top: 2px;
float: left;
}
}
.fade {
opacity: 0;
.transition(opacity .15s linear);
&.in {
opacity: 1;
}
}
.darkenBackground {
background: @shadow-color;
}
blockquote p:last-child,
blockquote ul:last-child,
blockquote ol:last-child {
margin-bottom: 0;
}
@media @tablet-up {
.affix {
position: fixed;
}
}
.RequestErrorModal {
pre {
white-space: pre-wrap;
margin: 0;
}
}
#flarum-loading {
text-align: center;
padding: 50px 0;
font-size: 18px;
color: @muted-more-color;
}

129
less/common/sideNav.less Normal file
View File

@@ -0,0 +1,129 @@
.sideNav > ul {
margin: 0;
padding: 0;
list-style: none;
}
// On phones, the index sidebar will pretty much take care of itself. The
// navigation list is a .dropdown-select and will be shown as the title-
// control; the new discussion button is the primary-control. On anything
// larger than a phone, however, we need to affix the sidebar and expand the
// .dropdown-select into a plain list.
@media @expand-side-nav {
.sideNav {
// Expand the dropdown-select component into a normal nav list.
& .Dropdown--select {
display: block;
.Dropdown--expanded();
& .Dropdown-menu {
& > li > a {
padding: 8px 0 8px 30px;
color: @muted-color;
&:hover {
background: none;
color: @link-color;
text-decoration: none;
}
& .Button-icon {
float: left;
margin-left: -30px;
margin-top: 1px;
font-size: 15px;
}
}
& > li.active > a {
background: none;
color: @primary-color;
font-weight: bold;
}
& > .Dropdown-separator {
background: none;
}
}
}
}
}
.sideNav--horizontal {}
@media @expand-side-nav {
.sideNav--horizontal {
padding: 15px 0;
white-space: nowrap;
overflow: auto;
-webkit-overflow-scrolling: touch;
&:after {
content: " ";
position: absolute;
left: 0;
right: 0;
margin-top: 15px;
border-bottom: 1px solid @control-bg;
}
> ul > li, .Dropdown-menu > li {
display: inline-block;
margin: 0 20px 0 0;
vertical-align: top;
}
.Dropdown-separator {
display: none;
}
.Dropdown--select .Dropdown-menu > li > a {
padding-left: 25px;
.icon {
margin-left: -25px;
}
}
.affix {
position: static;
}
}
@media @tablet {
.sideNav {
.sideNav--horizontal();
}
}
}
@media @desktop-up {
.sideNav {
float: left;
&, > ul {
width: 190px;
}
> ul {
margin-top: 30px;
&.affix {
top: @header-height;
}
> li {
margin-bottom: 10px;
}
}
}
}
@media @phone, @tablet {
.sideNavOffset {
margin-top: 15px;
}
}
@media @desktop-up {
.sideNavOffset {
margin-top: 30px;
margin-left: 240px;
}
}

142
less/common/variables.less Normal file
View File

@@ -0,0 +1,142 @@
// ---------------------------------
// CONFIG
@config-primary-color: #536F90;
@config-secondary-color: #536F90;
@config-dark-mode: false;
@config-colored-header: false;
// ---------------------------------
// COLORS
@primary-hue: hue(@primary-color);
@primary-sat: saturation(@primary-color);
@secondary-hue: hue(@secondary-color);
@secondary-sat: saturation(@secondary-color);
// Derive the primary/secondary colors from the config variables. In dark mode,
// we make the user-set colors a bit darker, otherwise they will stand out too
// much.
.define-colors(@config-dark-mode);
.define-colors(false) {
@primary-color: @config-primary-color;
@secondary-color: @config-secondary-color;
@body-bg: #fff;
@text-color: #111;
@link-color: saturate(@primary-color, 10%);
@heading-color: @text-color;
@muted-color: hsl(@secondary-hue, min(20%, @secondary-sat), 50%);
@muted-more-color: #aaa;
@shadow-color: rgba(0, 0, 0, 0.35);
@control-bg: hsl(@secondary-hue, min(50%, @secondary-sat), 93%);
@control-color: @muted-color;
@control-danger-bg: #fdd;
@control-danger-color: #d66;
@overlay-bg: fade(@secondary-color, 90%);
@code-bg: darken(@body-bg, 3%);
@code-color: lighten(@text-color, 30%);
}
.define-colors(true) {
@primary-color: @config-primary-color;
@secondary-color: @config-secondary-color;
@body-bg: hsl(@secondary-hue, min(20%, @secondary-sat), 10%);
@text-color: #ddd;
@link-color: saturate(@primary-color, 10%);
@heading-color: @text-color;
@muted-color: hsl(@secondary-hue, min(15%, @secondary-sat), 50%);
@muted-more-color: hsl(@secondary-hue, min(10%, @secondary-sat), 40%);
@shadow-color: rgba(0, 0, 0, 0.5);
@control-bg: hsl(@secondary-hue, min(20%, @secondary-sat), 13%);
@control-color: @muted-color;
@control-danger-bg: #411;
@control-danger-color: #a88;
@overlay-bg: fade(darken(@body-bg, 5%), 90%);
@code-bg: darken(@body-bg, 3%);
@code-color: #fff;
}
@hero-bg: @control-bg;
@hero-color: @control-color;
@hero-muted-color: @control-color;
@alert-bg: #fff2ae;
@alert-color: #ad6c00;
@alert-error-bg: #d83e3e;
@alert-error-color: #fff;
@alert-success-bg: #B4F1AF;
@alert-success-color: #33722D;
.define-header(@config-colored-header);
.define-header(false) {
@header-bg: @body-bg;
@header-color: @primary-color;
@header-control-bg: @control-bg;
@header-control-color: @control-color;
}
.define-header(true) {
@header-bg: @primary-color;
@header-color: @body-bg;
@header-control-bg: mix(#000, @header-bg, 10%);
@header-control-color: mix(@body-bg, @header-bg, 60%);
}
// ---------------------------------
// LAYOUT
@drawer-width: 270px;
@pane-width: 400px;
@header-height: 52px;
@header-height-phone: 46px;
@border-radius: 4px;
@zindex-header: 1000;
@zindex-pane: 1010;
@zindex-composer: 1020;
@zindex-dropdown: 1030;
@zindex-modal-background: 1040;
@zindex-modal: 1050;
@zindex-alerts: 1060;
@zindex-tooltip: 1070;
@expand-side-nav: @tablet-up;
// ---------------------------------
// BREAKPOINTS
@screen-phone-max: (@screen-tablet - 1);
@screen-tablet: 768px;
@screen-tablet-max: (@screen-desktop - 1);
@screen-desktop: 992px;
@screen-desktop-max: (@screen-desktop-hd - 1);
@screen-desktop-hd: 1100px;
@phone: ~"(max-width: @{screen-phone-max})";
@tablet: ~"(min-width: @{screen-tablet}) and (max-width: @{screen-tablet-max})";
@desktop: ~"(min-width: @{screen-desktop}) and (max-width: @{screen-desktop-max})";
@desktop-hd: ~"(min-width: @{screen-desktop-hd})";
@tablet-up: ~"(min-width: @{screen-tablet})";
@desktop-up: ~"(min-width: @{screen-desktop})";
// ---------------------------------
// COMPONENTS
@tooltip-bg: rgba(0, 0, 0, 0.9);
@tooltip-color: #fff;
@online-user-circle-color: #7FBA00;