public/backend.css
/*** Generic stuff and layout
 ****************************/
/* Always display a scrollbar; this prevents the layout from jumping around when
 * you expand or collapse something that makes a scrollbar appear. */
body       { overflow-y: scroll; }

.page      { padding: 1em; }
footer     { padding: 1em; text-align: center; display: flex; justify-content: space-between;
             background-color: var(--nav-bg); box-shadow: 0 0 4px var(--footer-shadow); }
footer a   { font-weight: bold; color: var(--text); margin: 0 .5em; }

@media (max-width: 54em) {
    footer      { text-align: left; justify-content: space-around; }
    footer a    { display: block; padding: .5em 0; }
    footer span { display: none; }
}

/* Don't make various explanatory texts too wide. */
.page > p, .page > div > p,
.page > ul, .page > div > ul,
.page > ol, .page > div > ol,
.page > table,
.form-max-width label, .form-max-width textarea, .form-max-width input {
    max-width: 50em;
}
.form-max-width label { display:inline-block; }
label.inline          { display:inline; }

#js-settings, #js-csrf, #js-i18n { display: none; }


.page, .center {
    /* .note has a width of 76mm plus 5mm margin on either side, so 86mm total
     * width. .page has a 1em padding on either side.
     * The last 10mm is needede because magic (1mm will work, this just looks
     * more even). */
    max-width: calc((1em * 2) + (86mm * 4) + 10mm);
}

nav                    { display: flex; justify-content: space-between; padding-right: .5em; }
nav #usermenu          { text-align: right; min-width: 20.5em; }
nav #signin            { white-space: nowrap; margin-left: 1em; }
nav #back              { white-space: nowrap; margin-right: 1em; }
nav .sites-list        { position: absolute; visibility: hidden; }
nav .sites-list-select { display: none; padding: 0; background-color: var(--bg); }
@media (max-width: 87rem) {
    nav { padding-left: .5em; }
}

h2               { margin-bottom:.4em; }
h2 small         { font-size:.9rem; font-weight:normal; margin-right:.1em; line-height:1rem; }
#dash-widgets h2 { margin-left:.0; margin-right:.4em; padding-right:.2em;
                   display:flex; justify-content:space-between; align-items:flex-end; }
h3, h4           { margin-bottom:0; }
h3+p, h4+p       { margin-top:0; }
h3.border        { border-bottom:1px solid #666; margin-bottom:.2em; }

form .err        { color:var(--form-error-text); display:block; }
form .disabled,
form *[disabled] { color:var(--pageviews-text); cursor:not-allowed;}

span.red  { color: var(--form-error-text); }
input.red { border: 1px solid var(--input-error-border) !important; }

/* TODO: replace with .side-by-side? */
@media (min-width: 55rem) {
    .form-wrap form          { display: flex; flex-wrap: wrap; }
    .form-wrap form fieldset { width: 48%; }

    .flex-form          { display: flex; flex-wrap: wrap; }
    .flex-form form     { width: 48%; }
    .flex-form fieldset { height: 100%; }
}

.flash     { padding: 10px; text-align: center; border: 2px solid var(--bg); margin: calc(-1em - 2px); margin-bottom: 1em; }
.flash p   { max-width: none !important; }
.flash pre { text-align: left; margin: 0 auto; display: inline-block; }
.flash-i   { background-color: var(--info-bg); border-color: var(--info-border); }
.flash-e   { background-color: var(--error-bg); border-color: var(--error-border); }
.onetime   { display:none; }

.screen-reader { display: none; }
.hide          { display: none; }
.show-mobile   { display: none; }
@media (max-width: 55rem) {
    .hide-mobile { display: none; }
    .show-mobile { display: block; }
}

/* Using display: none means it's ignored by Safary when pressing Enter. */
button.hide-btn { overflow: visible; height: 0; width: 0; margin: 0; border: 0; padding: 0; display: block; }

fieldset               { margin-bottom: 1em; border: 1px solid var(--fieldset-border); }
legend                 { font-weight: bold; }
fieldset:target legend { background-color: var(--target-bg); }

select#timezone { max-width: 20rem; }

.active { font-weight: bold; text-decoration: underline; }

/* Break to new flexbox row. */
.flex-break { flex-basis: 100%; height: 0; }

table.auto { width: auto; }

/* Otherwise .page-title has different vertical alignment? Hmmm... */
.show-mobile .page-title { vertical-align: top; }

.rlink { display: inline-block; overflow: hidden;
         max-width: 17.5rem; text-overflow: ellipsis; white-space: nowrap; }
.rlink { min-width: 3em; } /* Make very short paths (like just /) easier to click/touch. */
.page-title b, .rlink b { background-color: var(--target-bg); }
input.value             { background-color: var(--target-bg); }

/* Hide "Go to [..]" link unless we loaded the page details. */
small.go           { display: none; }
.go { word-break: normal; }


/*** Pages and totals list/charts
 ********************************/
.pages-list h2           { margin-top: .5em; }
.count-list              { margin-top: 15px; }
.count-list tr           { border: none; }
.count-list td           { vertical-align: top; }
.count-list th           { text-align: left; }
.count-list .col-count   { width: 5rem; text-align: right; }
.count-list .col-count-diff { font-size:.9rem; }
.count-list .col-path    { width: 20rem; }
.label-event             { background-color: var(--event-bg); border-radius: 1em; padding: .1em .3em; }
.count-list td[colspan="3"] {  /* "nothing to display" */
    text-align: left;
    width: auto;
}
.pages-list >.load-btns                  { display:block; margin-top:-.7em; width:max-content; }
.pages-list.pages-list-text >.load-btns  { margin-top:0; }
.plus      { color: var(--plus); }
.minus     { color: var(--minus); }
.load-less { display:none; margin-left: 1rem; }

.count-list tr:target,
.count-list tr.target             { background-color: inherit; }
.count-list tr:target .load-refs,
.count-list tr.target .load-refs  { font-weight: bold; border-bottom: 4px solid var(--target-bg); }
tr.target small.go                { display: inline-block; }

/* Border doesn't affect layout. */
.count-list:not(.count-list-text) .load-refs { border-bottom: 4px solid transparent; margin-bottom: -4px; }

.count-list-text .refs { margin-top: 1em; }

.chart { position: relative; height: 50px; width: 100%; margin-bottom: 1em; }

.chart-left {
    position: absolute; left: -1.2em; top: -.1em; padding: 0 .1em; font-size: 1.2rem; text-align: center;
    display: none; margin-right: 0;
}
.chart-left a:hover { text-decoration: none; }

tr:hover .chart-left,
tr.target .chart-left { display: block; }

.chart-right { position: absolute; right: .4em; top: -.8em; padding: 0 .1em; font-size: 1.2rem;
               line-height: 1; text-align: center; }
.page-n      { color: #555; font-size: .8em; }

.chart-line canvas { display: block; height: 50px; width: 100%; }
.chart-bar canvas  { display: block; height: 50px; width: 100%; }

.chart.chart-line, .chart.chart-bar { border: unset; }


/*** Text pageviews
 ******************/
.count-list-text .rlink { white-space: normal; overflow: inherit; }
.count-list-text td     { padding: .5em; }

.count-list-text tbody tr           { border-bottom: 1px solid var(--text-table-border); border-top: 1px solid var(--text-table-border); }
.count-list-text tr:nth-child(even) { background-color: var(--text-table-even-bg); }

.count-list-text .col-idx    { width: 1em; color: var(--text-table-rank-text); }
.count-list-text .col-n      { text-align: right; width: 1em; } /* Hint to make the column as small as possible */
.count-list-text .col-diff   { text-align: right; width: 1em; } /* Hint to make the column as small as possible */
.count-list-text .col-d      { width: 12em; font-size: 1.2em; padding: 0; text-align: center; }
.count-list-text .col-d      { vertical-align: top; }
.count-list-text .col-d span { display: inline-block; margin-top: .8em; padding-top: 2px; line-height: 1em;
                               font-family: monospace; letter-spacing: 3px; padding-right: 3px;
                               border: 1px solid var(--text-table-chart-border); border-radius: 2px; color: var(--chart-line); background-color: var(--text-table-chart-bg); }

/*** Horizontal charts
 ********************/
.hcharts            { display: flex; flex-wrap: wrap; justify-content: space-between; }
.hcharts > div      { width: 49%; }
@media (max-width: 45rem) {
    .hcharts       { display: block; }
    .hcharts > div { width: auto; }
}

.hchart .rows >div   { position: relative; margin-bottom: .8em; }
.hchart .generated .col-name { font-style: italic; }
.hchart .col-name    { display: inline-block; width: calc(100% - 8.5rem); position: relative; }
.hchart .cutoff      { word-break: break-all; max-width: calc(100% - 2em); }
.hchart .bar         { position: absolute; top: 0; bottom: 0; background-color: var(--chart-fill);
                       border: 1px solid var(--hchart-border); border-radius: 5px; transition: background-color .2s; }
.hchart .bar-c       { position: relative; z-index: 1; padding-left: .5rem; display: block; }
.hchart .col-count   { display: inline-block; width: 4.5rem; text-align: right; vertical-align: top; }
.hchart .col-perc    { width: 2.5em; margin-right: .5rem; vertical-align: top; }
.hchart .load-more   { display: inline-block; margin-left: .2em; margin-top: .2em; }
.hchart .load-detail { display: block; color: var(--text); }
.hchart .detail      { padding: 0 3em; border-bottom: 1px solid #bbb; }
.load-detail:hover      { text-decoration: none; color: var(--link); }
.load-detail:hover .bar { background-color: var(--hchart-bar-hover); }
.hchart .not-collected  { text-align: center; padding-bottom: .4em; font-style: italic; }


/*** Dashboard form (filter, time period select, etc.)
 ******************************************************/
#dash-move        { display: flex; justify-content: space-between; align-items: start; padding: .2em; margin: 0 1em; }
#dash-form        { display: block; padding-bottom: .4em; margin: -1em; margin-bottom: 1em; }
#dash-form span   { margin-left: 0; } /* Reset from hello-css */

#dash-saved-views       { position: absolute; top: 0em; right: -1em; z-index: 5; max-width: 30em; text-align: right; }
#dash-saved-views >span { font-size: 20px; padding: .2em; cursor: pointer;
                          user-select: none; -webkit-user-select: none; color: var(--link-text); transition: opacity .2s; }
#dash-saved-views >div  { display: none; margin-right: .5em; padding: .5em; text-align: left;
                          background-color: var(--tooltip-bg); color: var(--tooltip-text);
                          border: 1px solid var(--tooltip-border); box-shadow: 0 0 2px var(--tooltip-shadow); }
#dash-saved-views >span:hover { opacity: .5; }

/* Tweak icon for narrow screens; fixes #725 */
@media (max-width: 89rem)   { #dash-saved-views { right:-.5rem; top:-.2rem; } }
@media (max-width: 87.5rem) { #dash-saved-views { right:0; top:-.6rem; } }

@media (max-width: 36.5rem) {
    #dash-move span           { display: block; }
    #dash-move div:last-child { display: flex; flex-direction: column-reverse; text-align: right; align-items: end; }
}

#dash-main { display: flex; justify-content: space-between; padding: .5em 1em;
             background-color: var(--nav-bg); border-bottom: 1px solid var(--nav-border); border-radius: 2px; }
#dash-main input[type="text"]     { padding: .3em; }
#dash-main input[type="checkbox"] { vertical-align: middle; }
#filter-paths                     { width: 18.5em; display: block; margin-left: auto; }
#dash-main .date-input            { width: 9em; text-align: center; }

.filter-wrap                 { position: relative; text-align: right; }
.filter-wrap .loading::after { position: absolute; bottom: 0; right: .5em; }

#dash-main label { text-align: right; margin-right: .4em; }

#dash-select-period           { display: block; padding-left: .3em; }
#dash-select-period span+span { margin-left: .5em; }

#dash-timerange { background-color: var(--nav-bg); border: 1px solid var(--nav-border); text-align: center;
                  padding: 0 .4em; padding-top: 2px; border-top: 0; margin-top: -4px;
                  border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; }

@media (max-width: 56.5rem) {
    /* Break "current [..]" to new line to make more space. */
    #dash-select-period span+span { display: block; margin-left: 0em; }
    #dash-main label              { display: block; }
}

@media (max-width: 41rem) {
    #filter-paths  { width: 10em;  }
}

@media (max-width: 33.5rem) {
    #dash-main       { display: block; }
    #filter-paths    { width: 100%; margin-top: .5em; }
    #dash-main label { text-align: left; }
}

.period-day [value=day],
.period-week [value=week],
.period-month [value=month],
.period-quarter [value=quarter],
.period-half-year [value=half-year],
.period-year [value=year],
.period-week-cur [value=week-cur],
.period-month-cur [value=month-cur],
.period-year-cur [value=year-cur],
.group-hour [value=hour],
.group-day [value=day],
.group-week [value=week] {
    font-weight: bold;
    text-decoration: underline;
}

/* Widget settings button for every widget. */
.widget-header          { position: relative; margin-left: -1em; padding-left: 1em; }
.widget-header:hover .configure-widget { display: block; }
.configure-widget       { position: absolute; font-size: 14px; left: 0; top: 0; display: none; color: inherit; }
.configure-widget:hover { color: inherit; opacity: .7; text-decoration: none; }
#page-dashboard .widget-settings { position: absolute; z-index: 2; padding: .5em;
    background-color: var(--tooltip-bg); color: var(--tooltip-text);
    border: 1px solid var(--tooltip-border); box-shadow: 0 0 2px var(--tooltip-shadow); }

/*** Tooltip
 ************/
#tooltip { position: absolute; left: 0; top: 0; padding: .2em .5em; font-size: 14px; z-index: 100;
           font-family: sans-serif; color: var(--tooltip-text); background-color: var(--tooltip-bg); box-shadow: 0 0 2px var(--tooltip-shadow); }
#tooltip .views { color: var(--pageviews-text); } /* Grey out "pageviews" in tooltip. */


/*** Settings tabs
 ******************/
.tab-nav               { padding: 1em; margin: -1em; margin-bottom: 1em; justify-content: left; border-radius: 2px;
                         background-color: var(--nav-bg); border-bottom: 1px solid var(--nav-border); }
.tab-nav a             { padding: 0 .9em; border-right: 1px solid #aaa; }
.tab-nav a:first-child { padding-left: 0; }
.tab-nav a:last-child  { border-right: none; padding-right: 0; }
@media (max-width: 40rem) {
    .tab-nav   { flex-wrap: wrap; justify-content: center; }
    .tab-nav a { line-height: 2.5em; }
}

/*** Settings page
 *******************/
#page-settings-main #secret { display:none; margin-left:1em; padding-left:1em; border-left:1px solid #aaa; }
.purge-err                  { margin-left:1em; margin-top:1em; }
.user-api-key               { width:100%; }
.user-api-key td            { vertical-align:top; }
.user-api-key ul            { margin:0; padding-left:1em; }

/*** Widget settings
 *******************/
.widget                 { position: relative; margin-bottom: .5em; padding-left: 2em; border-top: 1px solid var(--widget-border); box-shadow: 2px 2px 2px rgba(0,0,0,.2); }
.widget .header         { display: flex; justify-content: space-between; padding: .5em; }
.widget .header strong  { display: inline-block; width: 12em; }
.widget .show-s         { display: inline-block; width: 2em; text-align: center; }
.widget-save            { display: flex; justify-content: space-between; }
.widget-settings label  { display: inline-block; min-width: 9em; margin-bottom: 1em; }
.widget-settings button { margin-left: 0; }
.widget-settings select, .widget-settings input:not([type="checkbox"]) { background-color: var(--bg); width: 14em; }
.widget-settings        { margin-top: .5em; margin-left: 2em; }
.widget-settings .help  { margin-left: 1em;  }
.widget-settings br:last-child { display: none; }
.widget-add-new         { margin: 1em 0 1.5em 2.1em; }
#page-user-dashboard .widget-settings { display: none; }

@media (max-width: 46rem) {
    .widget-settings label { display: block; margin-bottom: 0; }
    .widget-settings .help { display: block; margin-left: .2em; }
}

/* Dragula */
.gu-mirror       { position: fixed !important; z-index: 9999 !important; opacity: 0 !important; }
.gu-hide         { display: none !important; }
.gu-unselectable { user-select: none; -webkit-user-select: none; }
.gu-transit      { outline: 3px dashed var(--widget-dragging-border); background-color: var(--widget-dragging-bg); }

.drag-handle        { position: absolute; top: 0; left: 0; width: 2em; height: 100%; padding: 4px 0 0 2px;
                      font-size: 12px; font-weight: bold; line-height: 6px; letter-spacing: 3px; margin-left: 0;
                      content: '....'; text-align: center; cursor: move;
                      background-color: var(--widget-handle-bg); color: var(--widget-handle-text); }
.drag-handle::after { content: '··· ··· ··· ··· ···'; }
.drag-handle:hover  { background-color: var(--widget-handle-hover-bg); }


/*** noscript
 *************/
noscript   { display: block; padding: .4em; text-align: center; background-color: #ffcfcf; border-bottom: 1px solid #f88; }
noscript p { margin: .5em; }


/*** Loading indicator
 *********************/
@keyframes loading {
  0%   { content: "."; }
  50%  { content: ".."; }
  100% { content: "..."; }
}
/* TODO: See if we can have it sit in the margin */
.loading        { color: var(--loading-text); }
.loading:hover  { color: var(--loading-text); text-decoration: none; }
.loading::after { content: ""; animation: loading 500ms linear infinite; }

/* Force inputs to be 16px, so that iPhone won't zoom on select, which is
 * super annoying and 100% pointless.
 * https://stackoverflow.com/a/16255670/660921 */
@supports (-webkit-overflow-scrolling: touch) {
    input, select, textarea { font-size: 16px !important; }
}

dl { max-width: 50em; }
dt { font-weight: bold; margin-top: 1em; }

.input-prefix input   { padding-left: 1.8em !important; }
.input-prefix         { position: relative; }
.input-prefix .prefix { position: absolute; left: 0; top: 0; line-height: 2.55em; padding: 0 .3em 0 .5em; }

/* Work around Firefox mobile not displaying validation errors :-/ This at least
 * gives *some* hint something has gone wrong. This is so broken that I'm not
 * going to bother writing a JS thing.
 * https://github.com/arp242/goatcounter/issues/529 */
input:user-invalid { outline: 1px solid #f00 !important; box-shadow: 0 0 .2em #f00 !important; background-color: #feeaea; }

/* Basic print styles, for dashboard only. */
#print-header { display:none; }
@media print {
    nav,
    #dash-main,
    #dash-move,
    #dash-saved-views,
    footer,
    .load-more    { display:none !important; }
    html, .page   { background:transparent; }
    .page         { max-width:unset; box-shadow:unset; margin:0; }
    #print-header { display:block; text-align:center; font-size:1.2rem; font-weight:bold; }
    /* Print background colours for charts */
    canvas, .hchart .bar { -webkit-print-color-adjust:exact !important; print-color-adjust:exact !important; }
}
