1
0
Fork 0
mirror of https://github.com/mat-1/matdoesdev.git synced 2025-08-02 06:36:04 +00:00

add admin page

This commit is contained in:
mat 2025-03-29 01:28:40 +00:00
parent 5ca1cff55f
commit d8c016ac58
10 changed files with 2661 additions and 0 deletions

Binary file not shown.

View file

@ -18,6 +18,7 @@
--warning-color: #e6b450;
--error-color: #d95757;
--green: #aad94c;
--text-font: 'Atkinson Hyperlegible', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
}

View file

@ -0,0 +1,215 @@
<script lang="ts">
import { onMount } from 'svelte'
import AdminGraph from './AdminGraph.svelte'
import { browser } from '$app/environment'
let uptimeSeconds = $state<number | undefined>()
let memoryUsed = $state<number | undefined>()
let memoryUsedHistory = $state<number[]>([])
let memoryTotal = $state<number | undefined>()
let cpuUsage = $state<number | undefined>()
let cpuUsageHistory = $state<number[]>([])
let storageUsed = $state<number | undefined>()
let storageTotal = $state<number | undefined>()
let logs = $state<string[]>([])
function renderUptime(secs: number) {
const hours = Math.floor(secs / 3600)
const minutes = Math.floor((secs % 3600) / 60)
const seconds = secs % 60
return `${hours}h ${minutes}m ${seconds}s`
}
function reboot() {}
async function shutdown() {
await fetch('/admin/api/shutdown', { method: 'POST' })
// shutdown animation
document.body.classList.add('shutdown')
await new Promise((resolve) => setTimeout(resolve, 3000))
location.reload()
}
let logsEl: HTMLDivElement
function startEventSource() {
const es = new EventSource('/admin/api/stats')
es.addEventListener('message', (event) => {
console.log(JSON.parse(event.data))
const data = JSON.parse(event.data)
uptimeSeconds = data.uptime as number
memoryUsed = data.memory.used as number
if (memoryUsedHistory.length > 40) {
memoryUsedHistory = memoryUsedHistory.slice(1)
}
memoryUsedHistory = [...memoryUsedHistory, memoryUsed]
memoryTotal = data.memory.total as number
cpuUsage = data.cpu as number
if (cpuUsageHistory.length > 40) {
cpuUsageHistory = cpuUsageHistory.slice(1)
}
cpuUsageHistory = [...cpuUsageHistory, cpuUsage]
storageUsed = data.storage.used as number
storageTotal = data.storage.total as number
// scroll down logs
const isLogsNearBottom =
Math.abs(logsEl.scrollHeight - logsEl.clientHeight - logsEl.scrollTop) <= 10
logs = [...logs, ...data.logs]
if (logs.length > 255) {
logs = logs.slice(logs.length - 255)
}
requestAnimationFrame(() => {
if (isLogsNearBottom) {
logsEl.scrollTop = logsEl.scrollHeight
}
})
})
es.addEventListener('error', (event) => {
console.error('EventSource error', event)
// reopen
es.close()
setTimeout(startEventSource, 1000)
})
return () => es.close()
}
onMount(() => {
if (browser) {
const close = startEventSource()
return close
}
})
</script>
<h1>Admin</h1>
<div>
<section class="container danger-buttons">
<button class="danger-button" onclick={reboot}>Reboot</button>
<button class="danger-button" onclick={shutdown}>Shut down</button>
</section>
{#if uptimeSeconds !== undefined}
<section class="container">
<span class="name">Uptime</span>:
<span class="value">{renderUptime(uptimeSeconds)}</span>
</section>
{/if}
<div class="chart-sections">
<span class="left">
{#if memoryTotal !== undefined}
<section class="container">
<div>
<span class="name">Memory usage</span>:
<span class="value">{memoryUsed} GiB</span>/{memoryTotal} GiB
</div>
<AdminGraph history={memoryUsedHistory} max={memoryTotal} color="#0dc7f9aa"></AdminGraph>
</section>
{/if}
<section class="container">
<span>Logs:</span>
<div class="logs" bind:this={logsEl}>
{#each logs as log}
<div>{log}</div>
{/each}
</div>
</section>
</span>
<span class="right">
{#if cpuUsage !== undefined}
<section class="container">
<span class="name">CPU</span>: <span class="value">{Math.round(cpuUsage * 100)}%</span>
<AdminGraph history={cpuUsageHistory} max={1} color="#aad94caa"></AdminGraph>
</section>
{/if}
{#if storageUsed !== undefined && storageTotal !== undefined}
<section class="container">
<span class="name">Storage</span>:
<span class="value">{storageUsed} GiB</span>/{storageTotal}
GiB
<div class="bar-container">
<div class="bar-item" style="width: {(storageUsed / storageTotal) * 100}%"></div>
</div>
</section>
{/if}
</span>
</div>
</div>
<style>
.danger-buttons {
float: right;
}
.danger-button {
border-color: var(--error-color);
color: white;
}
.chart-sections {
display: flex;
justify-content: space-between;
width: 100%;
flex-wrap: wrap;
}
.value {
font-weight: bold;
}
.container {
margin-bottom: 1rem;
}
.logs {
background-color: #000;
font-family: monospace;
width: 360px;
height: 200px;
overflow-wrap: anywhere;
overflow: auto;
border: 1px solid var(--background-color-alt-3);
padding: 0.25rem;
}
.bar-container {
border: 1px solid var(--background-color-alt-3);
height: 20px;
width: 100%;
margin-top: 0.5rem;
}
.bar-item {
height: 100%;
background: linear-gradient(to right, hsl(0, 63%, 40%), hsl(0, 63%, 60%));
}
:global(body.shutdown) {
animation: shutdown 0.3s linear;
opacity: 0;
}
/* based on https://codepen.io/andreasantonsson/pen/OWWRGN */
@keyframes shutdown {
0% {
transform: scale(1, 1);
opacity: 1;
}
50% {
transform: scale(1, 0.02);
opacity: 0.8;
}
100% {
transform: scale(0, 0);
opacity: 0.3;
}
}
</style>

View file

@ -0,0 +1,61 @@
<script lang="ts">
interface Props {
history: number[]
max: number
color: string
}
let { history, max, color }: Props = $props()
const width = 360
const height = 200
function makePath(history: number[], max: number) {
let path = ''
for (let i = 0; i < history.length; i++) {
const value = history[i]
const x = i === 0 ? 0 : (i / (history.length - 1)) * width
const y = (1 - value / max) * height
if (i === 0) {
path += `M ${x},${y}`
} else {
path += ` L ${x},${y}`
}
}
// fill the rest
// right of end
path += ` L ${width + 10},${(1 - history[history.length - 1] / max) * height}`
// bottom right
path += ` L ${width + 10},${height + 10}`
// bottom left
path += ` L -10,${height + 10}`
// left of start
path += ` L -10,${(1 - history[0] / max) * height}`
// close
path += ` Z`
return path
}
let path = $derived(makePath(history, max))
</script>
<div class="graph" style="width: {width}px; height: {height}px">
<svg viewBox="0 0 {width} {height}" xmlns="http://www.w3.org/2000/svg">
<path d={path} stroke="var(--text-color)" stroke-width="2" fill={color}></path>
</svg>
</div>
<style>
.graph {
--line-color: var(--background-color-alt-3);
/* grid lines */
--grid-size: 20px;
background:
linear-gradient(to right, var(--line-color) 1px, transparent 1px) 0 0 / var(--grid-size) 100%,
linear-gradient(to bottom, var(--line-color) 1px, transparent 1px) 0 0/100% var(--grid-size);
box-shadow:
0 0 0 1px var(--line-color) inset,
0 0 0 1px var(--line-color) inset;
}
</style>

View file

@ -0,0 +1,118 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Log In &lsaquo; matdoes.dev &#8212; WordPress</title>
<meta name="robots" content="noindex, follow" />
<link
rel="stylesheet"
id="login-css"
href="/wp-admin/css/login.min.css?ver=6.6.2"
type="text/css"
media="all"
/>
<link
rel="stylesheet"
id="buttons-css"
href="/wp-includes/css/buttons.min.css?ver=6.6.2"
type="text/css"
media="all"
/>
<link
rel="stylesheet"
id="forms-css"
href="/wp-admin/css/forms.min.css?ver=6.6.2"
type="text/css"
media="all"
/>
<meta name="referrer" content="strict-origin-when-cross-origin" />
<meta name="viewport" content="width=device-width" />
</head>
<body class="login no-js login-action-login wp-core-ui locale-en-us">
<div id="login">
<h1><a href="https://wordpress.org/">Powered by WordPress</a></h1>
<form name="loginform" id="loginform" action="/admin" method="get">
<p>
<label for="user_login">Username or Email Address</label>
<input
type="text"
id="user_login"
class="input"
value=""
size="20"
autocapitalize="off"
autocomplete="username"
required="required"
/>
</p>
<div class="user-pass-wrap">
<label for="user_pass">Password</label>
<div class="wp-pwd">
<input
type="password"
id="user_pass"
class="input password-input"
value=""
size="20"
autocomplete="current-password"
spellcheck="false"
required="required"
/>
<button
type="button"
class="button button-secondary wp-hide-pw hide-if-no-js"
data-toggle="0"
aria-label="Show password"
>
<span class="dashicons dashicons-visibility" aria-hidden="true"></span>
</button>
</div>
</div>
<p class="forgetmenot">
<input name="rememberme" type="checkbox" id="rememberme" value="forever" />
<label for="rememberme">Remember Me</label>
</p>
<p class="submit">
<input
type="submit"
id="wp-submit"
class="button button-primary button-large"
value="Log In"
/>
</p>
</form>
<p id="nav">
<a class="wp-login-lost-password" href="/wp-login.php?action=lostpassword"
>Lost your password?</a
>
</p>
<script type="text/javascript">
/* <![CDATA[ */
function wp_attempt_focus() {
setTimeout(function () {
try {
d = document.getElementById('user_login')
d.focus()
d.select()
} catch (er) {}
}, 200)
}
wp_attempt_focus()
if (typeof wpOnload === 'function') {
wpOnload()
}
/* ]]> */
</script>
<p id="backtoblog">
<a href="/">&larr; Go to matdoes.dev</a>
</p>
<div class="privacy-policy-page-link">
<a class="privacy-policy-link" href="/privacy-policy" rel="privacy-policy">Privacy Policy</a
>
</div>
</div>
</body>
</html>

1566
static/wp-admin/css/forms.min.css vendored Normal file

File diff suppressed because it is too large Load diff

409
static/wp-admin/css/login.min.css vendored Normal file
View file

@ -0,0 +1,409 @@
/*! This file is auto-generated */
body,
html {
height: 100%;
margin: 0;
padding: 0;
}
body {
background: #f0f0f1;
min-width: 0;
color: #3c434a;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu,
Cantarell, 'Helvetica Neue', sans-serif;
font-size: 13px;
line-height: 1.4;
}
a {
color: #2271b1;
transition-property: border, background, color;
transition-duration: 0.05s;
transition-timing-function: ease-in-out;
}
a {
outline: 0;
}
a:active,
a:hover {
color: #135e96;
}
a:focus {
color: #043959;
box-shadow: 0 0 0 2px #2271b1;
outline: 2px solid transparent;
}
p {
line-height: 1.5;
}
.login .message,
.login .notice,
.login .success {
border-left: 4px solid #72aee6;
padding: 12px;
margin-left: 0;
margin-bottom: 20px;
background-color: #fff;
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
word-wrap: break-word;
}
.login .success {
border-left-color: #00a32a;
}
.login .notice-error {
border-left-color: #d63638;
}
.login .login-error-list {
list-style: none;
}
.login .login-error-list li + li {
margin-top: 4px;
}
#loginform p.submit,
.login-action-lostpassword p.submit {
border: none;
margin: -10px 0 20px;
}
.login * {
margin: 0;
padding: 0;
}
.login .input::-ms-clear {
display: none;
}
.login .pw-weak {
margin-bottom: 15px;
}
.login .button.wp-hide-pw {
background: 0 0;
border: 1px solid transparent;
box-shadow: none;
font-size: 14px;
line-height: 2;
width: 2.5rem;
height: 2.5rem;
min-width: 40px;
min-height: 40px;
margin: 0;
padding: 5px 9px;
position: absolute;
right: 0;
top: 0;
}
.login .button.wp-hide-pw:hover {
background: 0 0;
}
.login .button.wp-hide-pw:focus {
background: 0 0;
border-color: #3582c4;
box-shadow: 0 0 0 1px #3582c4;
outline: 2px solid transparent;
}
.login .button.wp-hide-pw:active {
background: 0 0;
box-shadow: none;
transform: none;
}
.login .button.wp-hide-pw .dashicons {
width: 1.25rem;
height: 1.25rem;
top: 0.25rem;
}
.login .wp-pwd {
position: relative;
}
.no-js .hide-if-no-js {
display: none;
}
.login form {
margin-top: 20px;
margin-left: 0;
padding: 26px 24px;
font-weight: 400;
overflow: hidden;
background: #fff;
border: 1px solid #c3c4c7;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.login form.shake {
animation: shake 0.2s cubic-bezier(0.19, 0.49, 0.38, 0.79) both;
animation-iteration-count: 3;
transform: translateX(0);
}
@keyframes shake {
25% {
transform: translateX(-20px);
}
75% {
transform: translateX(20px);
}
100% {
transform: translateX(0);
}
}
@media (prefers-reduced-motion: reduce) {
.login form.shake {
animation: none;
transform: none;
}
}
.login-action-confirm_admin_email #login {
width: 60vw;
max-width: 650px;
margin-top: -2vh;
}
@media screen and (max-width: 782px) {
.login-action-confirm_admin_email #login {
box-sizing: border-box;
margin-top: 0;
padding-left: 4vw;
padding-right: 4vw;
width: 100vw;
}
}
.login form .forgetmenot {
font-weight: 400;
float: left;
margin-bottom: 0;
}
.login .button-primary {
float: right;
}
.login .reset-pass-submit {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.login .reset-pass-submit .button {
display: inline-block;
float: none;
margin-bottom: 6px;
}
.login .admin-email-confirm-form .submit {
text-align: center;
}
.admin-email__later {
text-align: left;
}
.login form p.admin-email__details {
margin: 1.1em 0;
}
.login h1.admin-email__heading {
border-bottom: 1px #f0f0f1 solid;
color: #50575e;
font-weight: 400;
padding-bottom: 0.5em;
text-align: left;
}
.admin-email__actions div {
padding-top: 1.5em;
}
.login .admin-email__actions .button-primary {
float: none;
margin-left: 0.25em;
margin-right: 0.25em;
}
#login form p {
margin-bottom: 0;
}
#login #reg_passmail,
#login form .indicator-hint {
margin-bottom: 16px;
}
#login form p.submit {
margin: 0;
padding: 0;
}
.login label {
font-size: 14px;
line-height: 1.5;
display: inline-block;
margin-bottom: 3px;
}
.login .forgetmenot label,
.login .pw-weak label {
line-height: 1.5;
vertical-align: baseline;
}
.login h1 {
text-align: center;
}
.login h1 a {
background-image: url(../images/w-logo-blue.png?ver=20131202);
background-image: none, url(../images/wordpress-logo.svg?ver=20131107);
background-size: 84px;
background-position: center top;
background-repeat: no-repeat;
color: #3c434a;
height: 84px;
font-size: 20px;
font-weight: 400;
line-height: 1.3;
margin: 0 auto 25px;
padding: 0;
text-decoration: none;
width: 84px;
text-indent: -9999px;
outline: 0;
overflow: hidden;
display: block;
}
#login {
width: 320px;
padding: 5% 0 0;
margin: auto;
}
.login #backtoblog,
.login #nav {
font-size: 13px;
padding: 0 24px;
}
.login #nav {
margin: 24px 0 0;
}
#backtoblog {
margin: 16px 0;
word-wrap: break-word;
}
.login #backtoblog a,
.login #nav a {
text-decoration: none;
color: #50575e;
}
.login #backtoblog a:hover,
.login #nav a:hover,
.login h1 a:hover {
color: #135e96;
}
.login #backtoblog a:focus,
.login #nav a:focus,
.login h1 a:focus {
color: #043959;
}
.login .privacy-policy-page-link {
text-align: center;
width: 100%;
margin: 3em 0 2em;
}
.login form .input,
.login input[type='password'],
.login input[type='text'] {
font-size: 24px;
line-height: 1.33333333;
width: 100%;
border-width: 0.0625rem;
padding: 0.1875rem 0.3125rem;
margin: 0 6px 16px 0;
min-height: 40px;
max-height: none;
}
.login input.password-input {
font-family: Consolas, Monaco, monospace;
}
.js.login input.password-input {
padding-right: 2.5rem;
}
.login form .input,
.login form input[type='checkbox'],
.login input[type='text'] {
background: #fff;
}
.js.login-action-resetpass input[type='password'],
.js.login-action-resetpass input[type='text'],
.js.login-action-rp input[type='password'],
.js.login-action-rp input[type='text'] {
margin-bottom: 0;
}
.login #pass-strength-result {
font-weight: 600;
margin: -1px 5px 16px 0;
padding: 6px 5px;
text-align: center;
width: 100%;
}
body.interim-login {
height: auto;
}
.interim-login #login {
padding: 0;
margin: 5px auto 20px;
}
.interim-login.login h1 a {
width: auto;
}
.interim-login #login_error,
.interim-login.login .message {
margin: 0 0 16px;
}
.interim-login.login form {
margin: 0;
}
.screen-reader-text,
.screen-reader-text span {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
word-wrap: normal !important;
}
input::-ms-reveal {
display: none;
}
#language-switcher {
padding: 0;
overflow: visible;
background: 0 0;
border: none;
box-shadow: none;
}
#language-switcher select {
margin-right: 0.25em;
}
.language-switcher {
margin: 0 auto;
padding: 0 0 24px;
text-align: center;
}
.language-switcher label {
margin-right: 0.25em;
}
.language-switcher label .dashicons {
width: auto;
height: auto;
}
.login .language-switcher .button {
margin-bottom: 0;
}
@media screen and (max-height: 550px) {
#login {
padding: 20px 0;
}
#language-switcher {
margin-top: 0;
}
}
@media screen and (max-width: 782px) {
.interim-login input[type='checkbox'] {
width: 1rem;
height: 1rem;
}
.interim-login input[type='checkbox']:checked:before {
width: 1.3125rem;
height: 1.3125rem;
margin: -0.1875rem 0 0 -0.25rem;
}
#language-switcher label,
#language-switcher select {
margin-right: 0;
}
}
@media screen and (max-width: 400px) {
.login .language-switcher .button {
display: block;
margin: 5px auto 0;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve"><style>.style0{fill: #0073aa;}</style><g><g><path d="M4.548 31.999c0 10.9 6.3 20.3 15.5 24.706L6.925 20.827C5.402 24.2 4.5 28 4.5 31.999z M50.531 30.614c0-3.394-1.219-5.742-2.264-7.57c-1.391-2.263-2.695-4.177-2.695-6.439c0-2.523 1.912-4.872 4.609-4.872 c0.121 0 0.2 0 0.4 0.022C45.653 7.3 39.1 4.5 32 4.548c-9.591 0-18.027 4.921-22.936 12.4 c0.645 0 1.3 0 1.8 0.033c2.871 0 7.316-0.349 7.316-0.349c1.479-0.086 1.7 2.1 0.2 2.3 c0 0-1.487 0.174-3.142 0.261l9.997 29.735l6.008-18.017l-4.276-11.718c-1.479-0.087-2.879-0.261-2.879-0.261 c-1.48-0.087-1.306-2.349 0.174-2.262c0 0 4.5 0.3 7.2 0.349c2.87 0 7.317-0.349 7.317-0.349 c1.479-0.086 1.7 2.1 0.2 2.262c0 0-1.489 0.174-3.142 0.261l9.92 29.508l2.739-9.148 C49.628 35.7 50.5 33 50.5 30.614z M32.481 34.4l-8.237 23.934c2.46 0.7 5.1 1.1 7.8 1.1 c3.197 0 6.262-0.552 9.116-1.556c-0.072-0.118-0.141-0.243-0.196-0.379L32.481 34.4z M56.088 18.8 c0.119 0.9 0.2 1.8 0.2 2.823c0 2.785-0.521 5.916-2.088 9.832l-8.385 24.242c8.161-4.758 13.65-13.6 13.65-23.728 C59.451 27.2 58.2 22.7 56.1 18.83z M32 0c-17.645 0-32 14.355-32 32C0 49.6 14.4 64 32 64s32-14.355 32-32.001 C64 14.4 49.6 0 32 0z M32 62.533c-16.835 0-30.533-13.698-30.533-30.534C1.467 15.2 15.2 1.5 32 1.5 s30.534 13.7 30.5 30.532C62.533 48.8 48.8 62.5 32 62.533z" class="style0"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

290
static/wp-includes/css/buttons.min.css vendored Normal file
View file

@ -0,0 +1,290 @@
/*! This file is auto-generated */
.wp-core-ui .button,
.wp-core-ui .button-primary,
.wp-core-ui .button-secondary {
display: inline-block;
text-decoration: none;
font-size: 13px;
line-height: 2.15384615;
min-height: 30px;
margin: 0;
padding: 0 10px;
cursor: pointer;
border-width: 1px;
border-style: solid;
-webkit-appearance: none;
border-radius: 3px;
white-space: nowrap;
box-sizing: border-box;
}
.wp-core-ui button::-moz-focus-inner,
.wp-core-ui input[type='button']::-moz-focus-inner,
.wp-core-ui input[type='reset']::-moz-focus-inner,
.wp-core-ui input[type='submit']::-moz-focus-inner {
border-width: 0;
border-style: none;
padding: 0;
}
.wp-core-ui .button-group.button-large .button,
.wp-core-ui .button.button-large {
min-height: 32px;
line-height: 2.30769231;
padding: 0 12px;
}
.wp-core-ui .button-group.button-small .button,
.wp-core-ui .button.button-small {
min-height: 26px;
line-height: 2.18181818;
padding: 0 8px;
font-size: 11px;
}
.wp-core-ui .button-group.button-hero .button,
.wp-core-ui .button.button-hero {
font-size: 14px;
min-height: 46px;
line-height: 3.14285714;
padding: 0 36px;
}
.wp-core-ui .button.hidden {
display: none;
}
.wp-core-ui input[type='reset'],
.wp-core-ui input[type='reset']:active,
.wp-core-ui input[type='reset']:focus,
.wp-core-ui input[type='reset']:hover {
background: 0 0;
border: none;
box-shadow: none;
padding: 0 2px 1px;
width: auto;
}
.wp-core-ui .button,
.wp-core-ui .button-secondary {
color: #2271b1;
border-color: #2271b1;
background: #f6f7f7;
vertical-align: top;
}
.wp-core-ui p .button {
vertical-align: baseline;
}
.wp-core-ui .button-secondary:hover,
.wp-core-ui .button.hover,
.wp-core-ui .button:hover {
background: #f0f0f1;
border-color: #0a4b78;
color: #0a4b78;
}
.wp-core-ui .button-secondary:focus,
.wp-core-ui .button.focus,
.wp-core-ui .button:focus {
background: #f6f7f7;
border-color: #3582c4;
color: #0a4b78;
box-shadow: 0 0 0 1px #3582c4;
outline: 2px solid transparent;
outline-offset: 0;
}
.wp-core-ui .button-secondary:active,
.wp-core-ui .button:active {
background: #f6f7f7;
border-color: #8c8f94;
box-shadow: none;
}
.wp-core-ui .button.active,
.wp-core-ui .button.active:hover {
background-color: #dcdcde;
color: #135e96;
border-color: #0a4b78;
box-shadow: inset 0 2px 5px -3px #0a4b78;
}
.wp-core-ui .button.active:focus {
border-color: #3582c4;
box-shadow:
inset 0 2px 5px -3px #0a4b78,
0 0 0 1px #3582c4;
}
.wp-core-ui .button-disabled,
.wp-core-ui .button-secondary.disabled,
.wp-core-ui .button-secondary:disabled,
.wp-core-ui .button-secondary[disabled],
.wp-core-ui .button.disabled,
.wp-core-ui .button:disabled,
.wp-core-ui .button[disabled] {
color: #a7aaad !important;
border-color: #dcdcde !important;
background: #f6f7f7 !important;
box-shadow: none !important;
cursor: default;
transform: none !important;
}
.wp-core-ui .button-secondary[aria-disabled='true'],
.wp-core-ui .button[aria-disabled='true'] {
cursor: default;
}
.wp-core-ui .button-link {
margin: 0;
padding: 0;
box-shadow: none;
border: 0;
border-radius: 0;
background: 0 0;
cursor: pointer;
text-align: left;
color: #2271b1;
text-decoration: underline;
transition-property: border, background, color;
transition-duration: 0.05s;
transition-timing-function: ease-in-out;
}
.wp-core-ui .button-link:active,
.wp-core-ui .button-link:hover {
color: #135e96;
}
.wp-core-ui .button-link:focus {
color: #043959;
box-shadow: 0 0 0 2px #2271b1;
outline: 2px solid transparent;
}
.wp-core-ui .button-link-delete {
color: #d63638;
}
.wp-core-ui .button-link-delete:focus,
.wp-core-ui .button-link-delete:hover {
color: #d63638;
background: 0 0;
}
.wp-core-ui .button-link-delete:disabled {
background: 0 0 !important;
}
.wp-core-ui .button-primary {
background: #2271b1;
border-color: #2271b1;
color: #fff;
text-decoration: none;
text-shadow: none;
}
.wp-core-ui .button-primary.focus,
.wp-core-ui .button-primary.hover,
.wp-core-ui .button-primary:focus,
.wp-core-ui .button-primary:hover {
background: #135e96;
border-color: #135e96;
color: #fff;
}
.wp-core-ui .button-primary.focus,
.wp-core-ui .button-primary:focus {
box-shadow:
0 0 0 1px #fff,
0 0 0 3px #2271b1;
}
.wp-core-ui .button-primary.active,
.wp-core-ui .button-primary.active:focus,
.wp-core-ui .button-primary.active:hover,
.wp-core-ui .button-primary:active {
background: #135e96;
border-color: #135e96;
box-shadow: none;
color: #fff;
}
.wp-core-ui .button-primary-disabled,
.wp-core-ui .button-primary.disabled,
.wp-core-ui .button-primary:disabled,
.wp-core-ui .button-primary[disabled] {
color: #a7aaad !important;
background: #f6f7f7 !important;
border-color: #dcdcde !important;
box-shadow: none !important;
text-shadow: none !important;
cursor: default;
}
.wp-core-ui .button-primary[aria-disabled='true'] {
cursor: default;
}
.wp-core-ui .button-group {
position: relative;
display: inline-block;
white-space: nowrap;
font-size: 0;
vertical-align: middle;
}
.wp-core-ui .button-group > .button {
display: inline-block;
border-radius: 0;
margin-right: -1px;
}
.wp-core-ui .button-group > .button:first-child {
border-radius: 3px 0 0 3px;
}
.wp-core-ui .button-group > .button:last-child {
border-radius: 0 3px 3px 0;
}
.wp-core-ui .button-group > .button-primary + .button {
border-left: 0;
}
.wp-core-ui .button-group > .button:focus {
position: relative;
z-index: 1;
}
.wp-core-ui .button-group > .button.active {
background-color: #dcdcde;
color: #135e96;
border-color: #0a4b78;
box-shadow: inset 0 2px 5px -3px #0a4b78;
}
.wp-core-ui .button-group > .button.active:focus {
border-color: #3582c4;
box-shadow:
inset 0 2px 5px -3px #0a4b78,
0 0 0 1px #3582c4;
}
@media screen and (max-width: 782px) {
.wp-core-ui .button,
.wp-core-ui .button.button-large,
.wp-core-ui .button.button-small,
a.preview,
input#publish,
input#save-post {
padding: 0 14px;
line-height: 2.71428571;
font-size: 14px;
vertical-align: middle;
min-height: 40px;
margin-bottom: 4px;
}
.wp-core-ui .copy-to-clipboard-container .copy-attachment-url {
margin-bottom: 0;
}
#media-upload.wp-core-ui .button {
padding: 0 10px 1px;
min-height: 24px;
line-height: 22px;
font-size: 13px;
}
.media-frame.mode-grid .bulk-select .button {
margin-bottom: 0;
}
.wp-core-ui .save-post-status.button {
position: relative;
margin: 0 14px 0 10px;
}
.wp-core-ui.wp-customizer .button {
font-size: 13px;
line-height: 2.15384615;
min-height: 30px;
margin: 0;
vertical-align: inherit;
}
.wp-customizer .theme-overlay .theme-actions .button {
margin-bottom: 5px;
}
.media-modal-content .media-toolbar-primary .media-button {
margin-top: 10px;
margin-left: 5px;
}
.interim-login .button.button-large {
min-height: 30px;
line-height: 2;
padding: 0 12px 2px;
}
}