array(
'name' => 'Ocean',
'bg1' => '#cce9fb',
'bg2' => '#a8d8f0',
'acc' => '#f57c00',
'da' => '#e65100',
'text' => '#0d2a4a',
'card' => 'rgba(255,255,255,0.45)',
'dm' => false,
),
'midnight' => array(
'name' => 'Midnight',
'bg1' => '#0f172a',
'bg2' => '#1e293b',
'acc' => '#60a5fa',
'da' => '#3b82f6',
'text' => '#e2e8f0',
'card' => 'rgba(15,23,42,0.65)',
'dm' => true,
),
'forest' => array(
'name' => 'Forest',
'bg1' => '#d1fae5',
'bg2' => '#a7f3d0',
'acc' => '#059669',
'da' => '#047857',
'text' => '#064e3b',
'card' => 'rgba(255,255,255,0.45)',
'dm' => false,
),
'sunset' => array(
'name' => 'Sunset',
'bg1' => '#fff1e6',
'bg2' => '#fde68a',
'acc' => '#ea580c',
'da' => '#c2410c',
'text' => '#7c2d12',
'card' => 'rgba(255,255,255,0.45)',
'dm' => false,
),
'slate' => array(
'name' => 'Slate',
'bg1' => '#e2e8f0',
'bg2' => '#cbd5e1',
'acc' => '#7c3aed',
'da' => '#6d28d9',
'text' => '#1e293b',
'card' => 'rgba(255,255,255,0.45)',
'dm' => false,
),
'rose' => array(
'name' => 'Rose',
'bg1' => '#fff1f2',
'bg2' => '#fecdd3',
'acc' => '#e11d48',
'da' => '#be123c',
'text' => '#881337',
'card' => 'rgba(255,255,255,0.45)',
'dm' => false,
),
'emerald' => array(
'name' => 'Emerald',
'bg1' => '#ecfdf5',
'bg2' => '#d1fae5',
'acc' => '#d97706',
'da' => '#b45309',
'text' => '#064e3b',
'card' => 'rgba(255,255,255,0.45)',
'dm' => false,
),
'violet' => array(
'name' => 'Violet',
'bg1' => '#1e1b4b',
'bg2' => '#312e81',
'acc' => '#a78bfa',
'da' => '#7c3aed',
'text' => '#ede9fe',
'card' => 'rgba(49,46,129,0.5)',
'dm' => true,
),
'charcoal' => array(
'name' => 'Charcoal',
'bg1' => '#1c1c1e',
'bg2' => '#2c2c2e',
'acc' => '#f57c00',
'da' => '#e65100',
'text' => '#e5e5ea',
'card' => 'rgba(44,44,46,0.6)',
'dm' => true,
),
'arctic' => array(
'name' => 'Arctic',
'bg1' => '#f0fdfa',
'bg2' => '#ccfbf1',
'acc' => '#0d9488',
'da' => '#0f766e',
'text' => '#134e4a',
'card' => 'rgba(255,255,255,0.45)',
'dm' => false,
),
'copper' => array(
'name' => 'Copper',
'bg1' => '#fdf6ec',
'bg2' => '#fde8c8',
'acc' => '#b45309',
'da' => '#92400e',
'text' => '#451a03',
'card' => 'rgba(255,255,255,0.45)',
'dm' => false,
),
'cosmic' => array(
'name' => 'Cosmic',
'bg1' => '#0a0015',
'bg2' => '#1a0033',
'acc' => '#e879f9',
'da' => '#d946ef',
'text' => '#fae8ff',
'card' => 'rgba(26,0,51,0.5)',
'dm' => true,
),
);
}
/** Builds inline CSS overrides for the chosen colour scheme (empty string for default). */
public static function get_404_scheme_css( string $key ): string {
$schemes = self::get_404_schemes();
if ( ! isset( $schemes[ $key ] ) || 'ocean' === $key ) {
return '';
}
$s = $schemes[ $key ];
$bg1 = esc_attr( $s['bg1'] );
$bg2 = esc_attr( $s['bg2'] );
$acc = esc_attr( $s['acc'] );
$da = esc_attr( $s['da'] );
$text = esc_attr( $s['text'] );
$card = esc_attr( $s['card'] );
$css = "body{background:linear-gradient(160deg,{$bg1} 0%,{$bg2} 100%);color:{$text};}";
$css .= ".cs404-heading{background:linear-gradient(135deg,{$acc},{$da});-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;}";
$css .= ".cs404-btn,.cs404-home-btn{background:linear-gradient(135deg,{$acc},{$da});box-shadow:0 4px 24px {$acc}44;}";
$css .= ".cs404-btn:hover,.cs404-home-btn:hover{box-shadow:0 6px 28px {$acc}66;}";
$css .= ".cs404-tab.active{background:linear-gradient(135deg,{$acc},{$da});box-shadow:0 2px 12px {$acc}44;}";
$css .= "#cs404-game{background:{$card};border-color:rgba(128,128,128,0.2);}";
$css .= ".cs404-lb-score{color:{$acc};}";
$css .= ".cs404-lb-row-gold{background:{$acc}18;}";
if ( $s['dm'] ) {
$css .= ".cs404-desc,.cs404-site-name,.cs404-tagline{color:{$text};}";
$css .= ".cs404-tab{background:rgba(255,255,255,0.08);color:{$text};border-color:rgba(255,255,255,0.1);}";
$css .= '.cs404-tab:hover{background:rgba(255,255,255,0.14);}';
$css .= ".cs404-miner-btn{background:rgba(255,255,255,0.1);color:{$text};border-color:rgba(255,255,255,0.15);}";
$css .= '#cs404-lb-panel{background:rgba(255,255,255,0.05);border-color:rgba(255,255,255,0.1);}';
$css .= ".cs404-lb-header{background:rgba(255,255,255,0.07);color:{$text};}";
$css .= ".cs404-lb-name{color:{$text};}.cs404-lb-empty{color:{$text};}";
$css .= '.cs404-lb-row{border-bottom-color:rgba(255,255,255,0.07);}';
}
return $css;
}
/**
* The colour scheme an administrator is previewing, or '' for an ordinary visitor.
*
* The preview link on the Custom 404 settings card carries a nonce created beside it
* (`csdtDevtools404.previewNonce`, action `csdt_404_preview`). Without that nonce, or
* without the capability, the query parameter is ignored and the saved scheme is used:
* a visitor cannot pick the page's palette by editing the URL.
*
* @return string Scheme key, or '' when not a valid preview request.
*/
private static function preview_scheme_key(): string {
if ( ! isset( $_GET['csdt_devtools_preview_scheme'], $_GET['_wpnonce'] ) ) {
return '';
}
if ( ! current_user_can( 'manage_options' ) ) {
return '';
}
if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_GET['_wpnonce'] ) ), 'csdt_404_preview' ) ) {
return '';
}
return sanitize_key( wp_unslash( $_GET['csdt_devtools_preview_scheme'] ) );
}
/**
* The plugin's credit on the 404 page.
*
* Empty unless the administrator ticked "Show Powered by CloudScale" (option
* csdt_show_powered_by, default off), the one opt-in that governs every credit the
* plugin can show a visitor. WordPress.org guideline 10: attribution on a public
* page only when the site owner asked for it.
*
* @return string HTML, or '' when not opted in.
*/
private static function attribution_badge(): string {
// The credit and its opt-in share one statement: the administrator's "Show Powered by
// CloudScale credit" checkbox (option csdt_show_powered_by, default off) decides it.
return CSDT_Login::credit_opted_in() ? 'Powered by CloudScale Devtools' : '';
}
/**
* Intercepts WordPress 404 responses and outputs the custom games page.
*
* Hooked on `template_redirect` at priority 1.
*/
public static function maybe_custom_404(): void {
if ( ! is_404() ) {
return; }
$preview_key = self::preview_scheme_key();
$is_preview = '' !== $preview_key;
if ( ! $is_preview && ! get_option( CSDT_DevTools::CUSTOM_404_OPTION, 0 ) ) {
return; }
status_header( 404 );
nocache_headers();
header( 'Content-Type: text/html; charset=utf-8' );
$site_name = get_bloginfo( 'name' );
$site_tagline = get_bloginfo( 'description' );
$home_url = home_url( '/' );
$logo_html = '';
if ( has_custom_logo() ) {
$logo_html = get_custom_logo();
} elseif ( $icon_url = get_site_icon_url( 64 ) ) {
$logo_html = '';
}
$root_path = plugin_dir_path( __DIR__ );
$root_url = plugin_dir_url( __DIR__ );
$css_path = $root_path . 'assets/cs-custom-404.css';
$js_path = $root_path . 'assets/cs-custom-404.js';
$js_url = $root_url . 'assets/cs-custom-404.js?ver=' . CSDT_DevTools::VERSION . '.' . filemtime( $js_path );
$all_schemes = self::get_404_schemes();
$active_scheme = ( $preview_key && isset( $all_schemes[ $preview_key ] ) ) ? $preview_key : get_option( CSDT_DevTools::SCHEME_404_OPTION, 'ocean' );
$scheme_css = self::get_404_scheme_css( $active_scheme );
?>
No scores yet, be the first!