/** * elFinder transport to support old protocol. * * @example * $('selector').elfinder({ * .... * transport : new elFinderSupportVer1() * }) * * @author Dmitry (dio) Levashov **/ window.elFinderSupportVer1 = function(upload) { "use strict"; var self = this, dateObj, today, yesterday, getDateString = function(date) { return date.replace('Today', today).replace('Yesterday', yesterday); }; dateObj = new Date(); today = dateObj.getFullYear() + '/' + (dateObj.getMonth() + 1) + '/' + dateObj.getDate(); dateObj = new Date(Date.now() - 86400000); yesterday = dateObj.getFullYear() + '/' + (dateObj.getMonth() + 1) + '/' + dateObj.getDate(); this.upload = upload || 'auto'; this.init = function(fm) { this.fm = fm; this.fm.parseUploadData = function(text) { var data; if (!$.trim(text)) { return {error : ['errResponse', 'errDataEmpty']}; } try { data = JSON.parse(text); } catch (e) { return {error : ['errResponse', 'errDataNotJSON']}; } return self.normalize('upload', data); }; }; this.send = function(opts) { var self = this, fm = this.fm, dfrd = $.Deferred(), cmd = opts.data.cmd, args = [], _opts = {}, data, xhr; dfrd.abort = function() { if (xhr.state() == 'pending') { xhr.quiet = true; xhr.abort(); } }; switch (cmd) { case 'open': opts.data.tree = 1; break; case 'parents': case 'tree': return dfrd.resolve({tree : []}); case 'get': opts.data.cmd = 'read'; opts.data.current = fm.file(opts.data.target).phash; break; case 'put': opts.data.cmd = 'edit'; opts.data.current = fm.file(opts.data.target).phash; break; case 'archive': case 'rm': opts.data.current = fm.file(opts.data.targets[0]).phash; break; case 'extract': case 'rename': case 'resize': opts.data.current = fm.file(opts.data.target).phash; break; case 'duplicate': _opts = $.extend(true, {}, opts); $.each(opts.data.targets, function(i, hash) { $.ajax(Object.assign(_opts, {data : {cmd : 'duplicate', target : hash, current : fm.file(hash).phash}})) .fail(function(error) { fm.error(fm.res('error', 'connect')); }) .done(function(data) { data = self.normalize('duplicate', data); if (data.error) { fm.error(data.error); } else if (data.added) { fm.trigger('add', {added : data.added}); } }); }); return dfrd.resolve({}); case 'mkdir': case 'mkfile': opts.data.current = opts.data.target; break; case 'paste': opts.data.current = opts.data.dst; if (! opts.data.tree) { $.each(opts.data.targets, function(i, h) { if (fm.file(h) && fm.file(h).mime === 'directory') { opts.data.tree = '1'; return false; } }); } break; case 'size': return dfrd.resolve({error : fm.res('error', 'cmdsupport')}); case 'search': return dfrd.resolve({error : fm.res('error', 'cmdsupport')}); case 'file': opts.data.cmd = 'open'; opts.data.current = fm.file(opts.data.target).phash; break; } // cmd = opts.data.cmd xhr = $.ajax(opts) .fail(function(error) { dfrd.reject(error); }) .done(function(raw) { data = self.normalize(cmd, raw); dfrd.resolve(data); }); return dfrd; }; // fix old connectors errors messages as possible // this.errors = { // 'Unknown command' : 'Unknown command.', // 'Invalid backend configuration' : 'Invalid backend configuration.', // 'Access denied' : 'Access denied.', // 'PHP JSON module not installed' : 'PHP JSON module not installed.', // 'File not found' : 'File not found.', // 'Invalid name' : 'Invalid file name.', // 'File or folder with the same name already exists' : 'File named "$1" already exists in this location.', // 'Not allowed file type' : 'Not allowed file type.', // 'File exceeds the maximum allowed filesize' : 'File exceeds maximum allowed size.', // 'Unable to copy into itself' : 'Unable to copy "$1" into itself.', // 'Unable to create archive' : 'Unable to create archive.', // 'Unable to extract files from archive' : 'Unable to extract files from "$1".' // } this.normalize = function(cmd, data) { var self = this, fm = this.fm, files = {}, filter = function(file) { return file && file.hash && file.name && file.mime ? file : null; }, getDirs = function(items) { return $.grep(items, function(i) { return i && i.mime && i.mime === 'directory'? true : false; }); }, getTreeDiff = function(files) { var dirs = getDirs(files); treeDiff = fm.diff(dirs, null, ['date', 'ts']); if (treeDiff.added.length) { treeDiff.added = getDirs(treeDiff.added); } if (treeDiff.changed.length) { treeDiff.changed = getDirs(treeDiff.changed); } if (treeDiff.removed.length) { var removed = []; $.each(treeDiff.removed, function(i, h) { var item; if ((item = fm.file(h)) && item.mime === 'directory') { removed.push(h); } }); treeDiff.removed = removed; } return treeDiff; }, phash, diff, isCwd, treeDiff; if ((cmd == 'tmb' || cmd == 'get')) { return data; } // if (data.error) { // $.each(data.error, function(i, msg) { // if (self.errors[msg]) { // data.error[i] = self.errors[msg]; // } // }); // } if (cmd == 'upload' && data.error && data.cwd) { data.warning = Object.assign({}, data.error); data.error = false; } if (data.error) { return data; } if (cmd == 'put') { phash = fm.file(data.target.hash).phash; return {changed : [this.normalizeFile(data.target, phash)]}; } phash = data.cwd.hash; isCwd = (phash == fm.cwd().hash); if (data.tree) { $.each(this.normalizeTree(data.tree), function(i, file) { files[file.hash] = file; }); } $.each(data.cdc||[], function(i, file) { var hash = file.hash, mcts; if (files[hash]) { if (file.date) { mcts = Date.parse(getDateString(file.date)); if (mcts && !isNaN(mcts)) { files[hash].ts = Math.floor(mcts / 1000); } else { files[hash].date = file.date || fm.formatDate(file); } } files[hash].locked = file.hash == phash ? true : file.rm === void(0) ? false : !file.rm; } else { files[hash] = self.normalizeFile(file, phash, data.tmb); } }); if (!data.tree) { $.each(fm.files(), function(hash, file) { if (!files[hash] && file.phash != phash && file.mime == 'directory') { files[hash] = file; } }); } if (cmd == 'open') { return { cwd : files[phash] || this.normalizeFile(data.cwd), files : $.map(files, function(f) { return f; }), options : self.normalizeOptions(data), init : !!data.params, debug : data.debug }; } if (isCwd) { diff = fm.diff($.map(files, filter)); } else { if (data.tree && cmd !== 'paste') { diff = getTreeDiff(files); } else { diff = { added : [], removed : [], changed : [] }; if (cmd === 'paste') { diff.sync = true; } } } return Object.assign({ current : data.cwd.hash, error : data.error, warning : data.warning, options : {tmb : !!data.tmb} }, diff); }; /** * Convert old api tree into plain array of dirs * * @param Object root dir * @return Array */ this.normalizeTree = function(root) { var self = this, result = [], traverse = function(dirs, phash) { var i, dir; for (i = 0; i < dirs.length; i++) { dir = dirs[i]; result.push(self.normalizeFile(dir, phash)); dir.dirs.length && traverse(dir.dirs, dir.hash); } }; traverse([root]); return result; }; /** * Convert file info from old api format into new one * * @param Object file * @param String parent dir hash * @return Object */ this.normalizeFile = function(file, phash, tmb) { var mime = file.mime || 'directory', size = mime == 'directory' && !file.linkTo ? 0 : file.size, mcts = file.date? Date.parse(getDateString(file.date)) : void 0, info = { url : file.url, hash : file.hash, phash : phash, name : file.name, mime : mime, ts : file.ts, size : size, read : file.read, write : file.write, locked : !phash ? true : file.rm === void(0) ? false : !file.rm }; if (! info.ts) { if (mcts && !isNaN(mcts)) { info.ts = Math.floor(mcts / 1000); } else { info.date = file.date || this.fm.formatDate(file); } } if (file.mime == 'application/x-empty' || file.mime == 'inode/x-empty') { info.mime = 'text/plain'; } if (file.linkTo) { info.alias = file.linkTo; } if (file.linkTo) { info.linkTo = file.linkTo; } if (file.tmb) { info.tmb = file.tmb; } else if (info.mime.indexOf('image/') === 0 && tmb) { info.tmb = 1; } if (file.dirs && file.dirs.length) { info.dirs = true; } if (file.dim) { info.dim = file.dim; } if (file.resize) { info.resize = file.resize; } return info; }; this.normalizeOptions = function(data) { var opts = { path : data.cwd.rel, disabled : $.merge((data.disabled || []), [ 'search', 'netmount', 'zipdl' ]), tmb : !!data.tmb, copyOverwrite : true }; if (data.params) { opts.api = 1; opts.url = data.params.url; opts.archivers = { create : data.params.archives || [], extract : data.params.extract || [] }; } if (opts.path.indexOf('/') !== -1) { opts.separator = '/'; } else if (opts.path.indexOf('\\') !== -1) { opts.separator = '\\'; } return opts; }; }; /** * FrontEdit - Live Frontend Block Editor - Complete Styles * Reorganized with CSS Variables for Better Maintainability */ /* * Varela Round is bundled with this plugin under the SIL Open Font License 1.1. * See ../fonts/OFL.txt for the complete license and attribution. */ @font-face { font-family: 'Varela Round'; font-style: normal; font-weight: 400; font-display: swap; src: url('../fonts/VarelaRound-Regular.ttf') format('truetype'); } /* ============================================ CSS VARIABLES ============================================ */ :root { /* ===== COLORS ===== */ /* Backgrounds */ --mwp-sfe-bg-darkest: #1a1a1a; --mwp-sfe-bg-dark: #2a2a2a; --mwp-sfe-bg-medium: #333; --mwp-sfe-bg-light: #444; /* Borders */ --mwp-sfe-border-dark: #333; --mwp-sfe-border-medium: #444; /* Brand Colors */ --mwp-sfe-primary: #2196F3; --mwp-sfe-primary-dark: #1976D2; --mwp-sfe-primary-darker: #1565C0; /* Status Colors */ --mwp-sfe-success: #00a32a; --mwp-sfe-success-dark: #008a20; --mwp-sfe-warning: #f56e28; --mwp-sfe-warning-dark: #d95f20; --mwp-sfe-failure: #dc3232; --mwp-sfe-failure-dark: #b52828; /* Text Colors */ --mwp-sfe-text-light: white; --mwp-sfe-text-muted: #999; /* Alpha Colors */ --mwp-sfe-primary-alpha-10: rgba(33, 150, 243, 0.1); --mwp-sfe-primary-alpha-20: rgba(33, 150, 243, 0.2); --mwp-sfe-primary-alpha-25: rgba(33, 150, 243, 0.25); --mwp-sfe-primary-alpha-40: rgba(33, 150, 243, 0.4); --mwp-sfe-warning-alpha-10: rgba(245, 110, 40, 0.1); --mwp-sfe-warning-alpha-40: rgba(245, 110, 40, 0.4); --mwp-sfe-success-alpha-10: rgba(0, 163, 42, 0.1); --mwp-sfe-success-alpha-40: rgba(0, 163, 42, 0.4); --mwp-sfe-failure-alpha-40: rgba(220, 50, 50, 0.4); --mwp-sfe-black-alpha-10: rgba(0, 0, 0, 0.1); --mwp-sfe-black-alpha-25: rgba(0, 0, 0, 0.25); --mwp-sfe-black-alpha-40: rgba(0, 0, 0, 0.4); --mwp-sfe-black-alpha-80: rgba(0, 0, 0, 0.8); --mwp-sfe-white-alpha-10: rgba(255, 255, 255, 0.1); --mwp-sfe-white-alpha-20: rgba(255, 255, 255, 0.2); --mwp-sfe-white-alpha-30: rgba(255, 255, 255, 0.3); /* ===== SPACING ===== */ --mwp-sfe-gap-tiny: 2px; --mwp-sfe-gap-small: 4px; --mwp-sfe-gap-medium: 10px; --mwp-sfe-gap-large: 20px; --mwp-sfe-padding-small: 4px; --mwp-sfe-padding-medium: 10px; --mwp-sfe-padding-large: 20px; --mwp-sfe-padding-button-v: 7px; --mwp-sfe-padding-button-h: 14px; --mwp-sfe-padding-editor-btn: 3px; /* ===== SIZING ===== */ --mwp-sfe-button-height: 30px; --mwp-sfe-button-size: 30px; --mwp-sfe-button-inner-size: 28px; --mwp-sfe-icon-size: 18px; --mwp-sfe-spinner-size: 14px; --mwp-sfe-success-icon-size: 24px; /* ===== BORDER RADIUS ===== */ --mwp-sfe-radius-small: 3px; --mwp-sfe-radius-medium: 4px; --mwp-sfe-radius-large: 6px; --mwp-sfe-radius-xlarge: 8px; /* ===== TRANSITIONS ===== */ --mwp-sfe-transition-instant: 0.1s ease; --mwp-sfe-transition-fast: 0.2s ease; --mwp-sfe-transition-medium: 0.3s ease; --mwp-sfe-transition-slow: 0.6s linear infinite; --mwp-sfe-transition-position: top 0.2s ease, left 0.2s ease; --mwp-sfe-transition-size: width 0.2s ease, height 0.2s ease; /* ===== Z-INDEX ===== */ --mwp-sfe-z-dropdown: 1; --mwp-sfe-z-element-active: 1234; --mwp-sfe-z-tooltip: 1234; --mwp-sfe-z-overlay: 12345; --mwp-sfe-z-preview: 123456; --mwp-sfe-z-actions: 123456; --mwp-sfe-z-toolbar: 123456; --mwp-sfe-z-success: 1234567; --mwp-sfe-z-mode-toggle: 12345678; /* ===== TYPOGRAPHY ===== */ --mwp-sfe-font-size-tiny: 10px; --mwp-sfe-font-size-small: 12px; --mwp-sfe-font-size-medium: 14px; --mwp-sfe-font-size-large: 16px; --mwp-sfe-font-family: 'Varela Round', sans-serif; /* ===== SHADOWS ===== */ --mwp-sfe-shadow-light: 0 0 12px var(--mwp-sfe-black-alpha-10); --mwp-sfe-shadow-medium: 0 0 12px var(--mwp-sfe-black-alpha-40); --mwp-sfe-shadow-dark: 0 0 12px var(--mwp-sfe-black-alpha-80); --mwp-sfe-shadow-elevated: 0 4px 12px var(--mwp-sfe-black-alpha-40), 0 0 0 1px var(--mwp-sfe-white-alpha-10); --mwp-sfe-shadow-success: 0 4px 12px var(--mwp-sfe-success-alpha-40), 0 0 0 1px var(--mwp-sfe-success-alpha-10); --mwp-sfe-shadow-comment: 0 4px 20px var(--mwp-sfe-primary-alpha-40); --mwp-sfe-shadow-warning: 0 4px 20px var(--mwp-sfe-warning-alpha-40); --mwp-sfe-shadow-failure: 0 4px 20px var(--mwp-sfe-failure-alpha-40); } /* ============================================ BODY STATES ============================================ */ body.mwp-sfe-editing-in-progress { position: relative; } /* ============================================ OVERLAY SYSTEM ============================================ */ .mwp-sfe-overlay-container { position: absolute; pointer-events: none; opacity: 1; overflow: visible; z-index: var(--mwp-sfe-z-overlay); transition: opacity var(--mwp-sfe-transition-fast); } .mwp-sfe-overlay { border-radius: var(--mwp-sfe-radius-xlarge); box-sizing: border-box; } /* No border radius when element is active */ .mwp-sfe-overlay.mwp-sfe-overlay-active { border-radius: unset; } /* Status Overlays (Always Visible) */ .mwp-sfe-overlay-status { position: absolute; pointer-events: none; opacity: 1; outline: 3px dotted var(--mwp-sfe-success); transition: opacity var(--mwp-sfe-transition-fast), outline-color var(--mwp-sfe-transition-fast); } .mwp-sfe-overlay-status[data-status="pending"] { outline-color: var(--mwp-sfe-warning); } .mwp-sfe-overlay-status[data-status="comment-only"] { outline-color: var(--mwp-sfe-primary); } /* Keep standard green status outlines fully suppressed during any live editor session so preview/edit toggles cannot flash them back on via inline opacity. */ body.mwp-sfe-is-editing .mwp-sfe-overlay-status:not([data-status="pending"]):not([data-status="comment-only"]) { opacity: 0 !important; transition: none !important; } /* Comment and draft active sessions should suppress every background status outline so preview toggles cannot briefly reveal blue/orange overlays. */ body.mwp-sfe-is-editing.mwp-sfe-mode-commenting .mwp-sfe-overlay-status, body.mwp-sfe-is-editing.mwp-sfe-mode-draft .mwp-sfe-overlay-status { opacity: 0 !important; transition: none !important; } /* Hover Overlay (Moving Blue Outline) */ .mwp-sfe-overlay-hover { position: absolute; pointer-events: none; opacity: 0; outline: 3px solid var(--mwp-sfe-primary); outline-offset: 4px; border-radius: var(--mwp-sfe-radius-xlarge); transition: top var(--mwp-sfe-transition-fast), left var(--mwp-sfe-transition-fast), width var(--mwp-sfe-transition-fast), height var(--mwp-sfe-transition-fast), opacity var(--mwp-sfe-transition-fast); } /* Active Overlays (Editing States) */ .mwp-sfe-overlay-active { position: absolute; pointer-events: none; opacity: 0; transition: opacity var(--mwp-sfe-transition-fast), box-shadow var(--mwp-sfe-transition-fast); } .mwp-sfe-overlay-active[data-mode="editing"] { box-shadow: var(--mwp-sfe-shadow-success), inset 0 0 0 9999px transparent; } /* Commenting always uses blue - whether the element also has an edit handler or not. */ .mwp-sfe-overlay-active[data-mode="commenting"] { box-shadow: 0 4px 12px var(--mwp-sfe-primary-alpha-40), 0 0 0 1px var(--mwp-sfe-primary-alpha-20), inset 0 0 0 9999px transparent; } .mwp-sfe-overlay-active[data-mode="draft-editing"], .mwp-sfe-overlay-active[data-mode="draft-preview"] { box-shadow: 0 4px 12px var(--mwp-sfe-warning-alpha-40), 0 0 0 1px var(--mwp-sfe-warning-alpha-10), inset 0 0 0 9999px transparent; } @media print { .mwp-sfe-overlay-container { display: none !important; } } /* ============================================ ELEMENT STATES ============================================ */ [data-mwp-sfe-bound="1"], [data-mwp-sfe-bound="1"] * { cursor: pointer !important; } [data-mwp-sfe-bound="1"].mwp-sfe-element-active, [data-mwp-sfe-bound="1"].mwp-sfe-element-active * { cursor: auto !important; pointer-events: auto !important; } /* Hide all children in collapsed core/details */ .wp-block-details:not([open]) > :not(summary) { display: none !important; } /* ============================================ EDITING INTERACTION LOCK mwp-sfe-is-editing is added to body for ANY active mode: regular editing, comment mode, and draft preview. This prevents page links and other non-plugin content from being interactable while the user is in any mode. ============================================ */ body.mwp-sfe-is-editing * { pointer-events: none; } /* Always restore the active element and plugin chrome. */ body.mwp-sfe-is-editing .mwp-sfe-element-active, body.mwp-sfe-is-editing .mwp-sfe-element-active *, body.mwp-sfe-is-editing .mwp-sfe-inline-toolbar, body.mwp-sfe-is-editing .mwp-sfe-inline-toolbar *, body.mwp-sfe-is-editing .mwp-sfe-inline-actions, body.mwp-sfe-is-editing .mwp-sfe-inline-actions *, body.mwp-sfe-is-editing .mwp-sfe-mode-toggle-bar, body.mwp-sfe-is-editing .mwp-sfe-mode-toggle-bar *, body.mwp-sfe-is-editing .mwp-abe-shadow-host, body.mwp-sfe-is-editing .mwp-abe-global-modal, body.mwp-sfe-is-editing .mwp-abe-global-modal *, body.mwp-sfe-is-editing .mwp-sfe-grip-bar, body.mwp-sfe-is-editing .mwp-sfe-grip-bar * { pointer-events: auto; } /* The post-lock modal can open while an editor remains active. It is its own interactive surface, so the page-wide edit lock must not swallow its buttons. */ body.mwp-sfe-is-editing .mwp-sfe-post-lock-modal, body.mwp-sfe-is-editing .mwp-sfe-post-lock-modal * { pointer-events: auto !important; cursor: auto !important; } body.mwp-sfe-is-editing .mwp-sfe-post-lock-modal button { cursor: pointer !important; } /* When an ABE modal is open, it becomes the only interactive surface. This keeps the page, editor chrome, and drawer locked underneath the modal while still letting the modal close button and panel content work. */ body.mwp-abe-modal-open * { pointer-events: none; } body.mwp-abe-modal-open .mwp-abe-global-modal, body.mwp-abe-modal-open .mwp-abe-global-modal * { pointer-events: auto !important; } /* ============================================ POST LOCK MODAL Mirrors the shared frontend modal treatment while staying independent from ABE branding and feature-specific markup. ============================================ */ .mwp-sfe-post-lock-modal { position: fixed; inset: 0; z-index: var(--mwp-sfe-z-mode-toggle); opacity: 0; pointer-events: none; transition: opacity var(--mwp-sfe-transition-fast); } .mwp-sfe-post-lock-modal, .mwp-sfe-post-lock-modal * { box-sizing: border-box; font-family: var(--mwp-sfe-font-family) !important; font-weight: normal !important; } .mwp-sfe-post-lock-modal.is-open { opacity: 1; pointer-events: auto; } .mwp-sfe-post-lock-backdrop { position: absolute; inset: 0; background: rgba(7, 11, 18, 0.58); backdrop-filter: blur(10px); } .mwp-sfe-post-lock-dialog { position: relative; z-index: 1; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; padding: 24px; } .mwp-sfe-post-lock-panel { width: min(400px, 95vw); border: 1px solid var(--mwp-sfe-border-dark); border-radius: var(--mwp-sfe-radius-xlarge); background: var(--mwp-sfe-bg-darkest); box-shadow: var(--mwp-sfe-shadow-elevated); overflow: hidden; transform: translateY(24px) scale(0.98); transition: transform var(--mwp-sfe-transition-fast); } .mwp-sfe-post-lock-modal.is-open .mwp-sfe-post-lock-panel { transform: translateY(0) scale(1); } .mwp-sfe-post-lock-header { padding: 18px var(--mwp-sfe-padding-large); border-bottom: 1px solid var(--mwp-sfe-border-dark); } .mwp-sfe-post-lock-title { margin: 0; color: var(--mwp-sfe-text-light); font-size: 24px; line-height: 1.15; } .mwp-sfe-post-lock-body { display: flex; flex-direction: column; gap: var(--mwp-sfe-gap-large); padding: 24px var(--mwp-sfe-padding-large); } .mwp-sfe-post-lock-copy { margin: 0; color: var(--mwp-sfe-text-muted); font-size: var(--mwp-sfe-font-size-medium); line-height: 1.6; } .mwp-sfe-post-lock-actions { display: flex; justify-content: flex-end; gap: var(--mwp-sfe-gap-medium); } /* Batch editing (regular editor active, NOT comment or draft mode): restore pointer-events for switchable bound elements so users can switch targets. Pending drafts (.mwp-sfe-status-pending) and comment-only elements (.mwp-sfe-status-comment-only) are excluded - their status overlays own the cursor and click behavior (see overlay rules below). */ body.mwp-sfe-is-editing.mwp-sfe-batch-session-active:not(.mwp-sfe-active-preview):not(.mwp-sfe-mode-commenting):not(.mwp-sfe-mode-draft) [data-mwp-sfe-bound="1"]:not(.mwp-sfe-status-pending):not(.mwp-sfe-status-comment-only), body.mwp-sfe-is-editing.mwp-sfe-batch-session-active:not(.mwp-sfe-active-preview):not(.mwp-sfe-mode-commenting):not(.mwp-sfe-mode-draft) [data-mwp-sfe-bound="1"]:not(.mwp-sfe-status-pending):not(.mwp-sfe-status-comment-only) * { pointer-events: auto; } /* Lift the active batch-edit block above unrelated overlapping page blocks so later DOM siblings cannot steal hover/click hit-testing inside the active block's painted area. This remains narrow to regular batch editing only and preserves inner block/component interaction because the full active subtree stays inside the lifted stacking context. */ body.mwp-sfe-is-editing.mwp-sfe-batch-session-active:not(.mwp-sfe-active-preview):not(.mwp-sfe-mode-commenting):not(.mwp-sfe-mode-draft) [data-mwp-sfe-bound="1"].mwp-sfe-element-active { position: relative; z-index: var(--mwp-sfe-z-element-active) !important; } /* Nested switchable elements inside the currently-active element (e.g. a text block visually on top of a Cover block) need cursor:pointer restored, because .mwp-sfe-element-active * { cursor: auto !important } is broad enough to reach those inner nodes via descendant matching. Locked types are still excluded. */ body.mwp-sfe-is-editing.mwp-sfe-batch-session-active:not(.mwp-sfe-active-preview):not(.mwp-sfe-mode-commenting):not(.mwp-sfe-mode-draft) [data-mwp-sfe-bound="1"].mwp-sfe-element-active [data-mwp-sfe-bound="1"]:not(.mwp-sfe-element-active):not(.mwp-sfe-status-pending):not(.mwp-sfe-status-comment-only), body.mwp-sfe-is-editing.mwp-sfe-batch-session-active:not(.mwp-sfe-active-preview):not(.mwp-sfe-mode-commenting):not(.mwp-sfe-mode-draft) [data-mwp-sfe-bound="1"].mwp-sfe-element-active [data-mwp-sfe-bound="1"]:not(.mwp-sfe-element-active):not(.mwp-sfe-status-pending):not(.mwp-sfe-status-comment-only) * { cursor: pointer !important; } /* Locked element overlays (pending draft, comment-only) in a batch edit session. The overlay must absorb the cursor and block clicks so the active editor is not accidentally closed. IMPORTANT: status overlays are created with pointer-events:none as an inline style (JS constructor), so !important is required here to override it - this is intentional and must not be removed. The underlying element stays pointer-events:none from the body rule above, so no element click handler fires. Clicks on the overlay land on data-mwp-sfe-control territory and are silently swallowed by the global click handler. */ body.mwp-sfe-is-editing.mwp-sfe-batch-session-active:not(.mwp-sfe-active-preview):not(.mwp-sfe-mode-commenting):not(.mwp-sfe-mode-draft) [data-mwp-sfe-bound="1"].mwp-sfe-status-pending, body.mwp-sfe-is-editing.mwp-sfe-batch-session-active:not(.mwp-sfe-active-preview):not(.mwp-sfe-mode-commenting):not(.mwp-sfe-mode-draft) [data-mwp-sfe-bound="1"].mwp-sfe-status-comment-only { pointer-events: auto; cursor: not-allowed !important; } body.mwp-sfe-is-editing.mwp-sfe-batch-session-active:not(.mwp-sfe-active-preview):not(.mwp-sfe-mode-commenting):not(.mwp-sfe-mode-draft) .mwp-sfe-overlay-status[data-status="pending"], body.mwp-sfe-is-editing.mwp-sfe-batch-session-active:not(.mwp-sfe-active-preview):not(.mwp-sfe-mode-commenting):not(.mwp-sfe-mode-draft) .mwp-sfe-overlay-status[data-status="comment-only"] { pointer-events: none !important; cursor: not-allowed !important; } /* ============================================ GLOBAL TYPOGRAPHY & SELECTION ============================================ */ .mwp-sfe-inline-toolbar *, .mwp-sfe-inline-actions *, .mwp-sfe-mode-toggle-bar * { font-family: var(--mwp-sfe-font-family) !important; } .mwp-sfe-inline-toolbar *::selection, .mwp-sfe-inline-actions *::selection, .mwp-sfe-inline-editor *::selection, .mwp-sfe-editing-active *::selection, .mwp-sfe-inline-comment-textarea *::selection { background-color: var(--mwp-sfe-primary) !important; color: var(--mwp-sfe-text-light) !important; } /* ============================================ TOOLBAR & ACTION BAR - CORE STYLES ============================================ */ .mwp-sfe-inline-toolbar, .mwp-sfe-inline-actions, .mwp-sfe-inline-preview, .mwp-sfe-inline-success, .mwp-sfe-inline-pending-wrapper { position: fixed; } .mwp-sfe-inline-toolbar, .mwp-sfe-inline-actions, .mwp-sfe-inline-preview, .mwp-sfe-inline-pending-wrapper { opacity: 1; transition: opacity var(--mwp-sfe-transition-fast); } .mwp-sfe-inline-toolbar { display: inline-flex; flex-wrap: wrap; background: var(--mwp-sfe-bg-darkest); border: 1px solid var(--mwp-sfe-border-dark); border-radius: var(--mwp-sfe-radius-xlarge); padding: var(--mwp-sfe-padding-medium); box-shadow: var(--mwp-sfe-shadow-elevated); animation: mwp-sfe-slide-down var(--mwp-sfe-transition-fast); user-select: none; -webkit-user-select: none; -moz-user-select: none; z-index: var(--mwp-sfe-z-toolbar) !important; } .mwp-sfe-inline-actions { display: flex; flex-wrap: wrap; gap: var(--mwp-sfe-gap-medium); padding: var(--mwp-sfe-padding-medium); background: var(--mwp-sfe-bg-darkest); border: 1px solid var(--mwp-sfe-border-dark); border-radius: var(--mwp-sfe-radius-xlarge); box-shadow: var(--mwp-sfe-shadow-elevated); animation: mwp-sfe-slide-up var(--mwp-sfe-transition-fast); z-index: var(--mwp-sfe-z-actions) !important; } /* ============================================ TRANSITION CONTROL ============================================ */ /* Default: Always transition position, size, and opacity */ .mwp-sfe-inline-actions, .mwp-sfe-inline-toolbar { transition: var(--mwp-sfe-transition-size), var(--mwp-sfe-transition-position), opacity var(--mwp-sfe-transition-fast), pointer-events 0s ease 0.2s; } /* Suppress position transitions during scroll/resize tracking. */ .mwp-sfe-inline-actions.mwp-sfe-no-position-transition, .mwp-sfe-inline-toolbar.mwp-sfe-no-position-transition { transition: var(--mwp-sfe-transition-size), opacity var(--mwp-sfe-transition-fast), pointer-events 0s ease 0.2s; } /* ============================================ TOOLBAR & ACTION BAR - ANIMATIONS ============================================ */ .mwp-sfe-inline-toolbar.mwp-sfe-closing { animation: mwp-sfe-slide-up-reverse var(--mwp-sfe-transition-fast) forwards; } .mwp-sfe-inline-actions.mwp-sfe-closing { animation: mwp-sfe-slide-down-reverse var(--mwp-sfe-transition-fast) forwards; } @keyframes mwp-sfe-slide-down { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } @keyframes mwp-sfe-slide-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @keyframes mwp-sfe-slide-down-reverse { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(10px); } } @keyframes mwp-sfe-slide-up-reverse { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-10px); } } /* ============================================ BUTTONS ============================================ */ .mwp-sfe-inline-editor .mwp-sfe-btn { cursor: pointer; } .mwp-sfe-btn { position: relative; color: var(--mwp-sfe-text-light); flex: 1; font-size: var(--mwp-sfe-font-size-medium); width: auto; height: var(--mwp-sfe-button-height); line-height: 1; border-radius: var(--mwp-sfe-radius-medium); padding: var(--mwp-sfe-padding-button-v) var(--mwp-sfe-padding-button-h); cursor: pointer; transition: background var(--mwp-sfe-transition-fast); text-wrap: nowrap; z-index: 0; } .mwp-sfe-btn::before { content: ""; position: absolute; inset: 0; background: transparent; border-radius: var(--mwp-sfe-radius-small); z-index: -1; } /* Button States */ .mwp-sfe-btn:disabled { cursor: not-allowed; color: var(--mwp-sfe-text-muted); } .mwp-sfe-btn:disabled:not([mwp-sfe-btn-loading="true"])::before { background: var(--mwp-sfe-black-alpha-25); pointer-events: none; } /* Animated Border for Loading State */ @supports (background: conic-gradient(from 0deg, red, blue)) { .mwp-sfe-btn[mwp-sfe-btn-loading="true"] { color: var(--mwp-sfe-text-muted); border-color: transparent !important; background: var(--mwp-sfe-bg-light) !important; isolation: isolate; /* Create new stacking context */ z-index: 0; } .mwp-sfe-btn[mwp-sfe-btn-loading="true"]::before { content: ''; position: absolute; inset: 0; background: conic-gradient( from calc(var(--angle) - (var(--spread) * 0.5)), transparent 0deg, var(--mwp-sfe-primary-dark), var(--mwp-sfe-primary), var(--mwp-sfe-primary-darker), transparent var(--spread) ); animation: syncRotate 1s linear infinite; z-index: -2; border-radius: inherit; } .mwp-sfe-btn[mwp-sfe-btn-loading="true"]::after { content: ''; position: absolute; inset: 2px; /* Inner thick border spacing */ background: var(--mwp-sfe-bg-light) !important; border-radius: var(--mwp-sfe-radius-small); z-index: -1; } /* Inner backgrounds based on button type to preserve button styles */ .mwp-sfe-btn-primary-inline[mwp-sfe-btn-loading="true"]::after, .mwp-sfe-btn-save-inline[mwp-sfe-btn-loading="true"]::after, .mwp-sfe-btn-submit-inline[mwp-sfe-btn-loading="true"]::after { background: linear-gradient(135deg, var(--mwp-sfe-primary-dark) 0%, var(--mwp-sfe-primary-darker) 100%); } .mwp-sfe-btn-secondary-inline[mwp-sfe-btn-loading="true"]::after, .mwp-sfe-btn-cancel-inline[mwp-sfe-btn-loading="true"]::after, .mwp-sfe-btn-back-edit[mwp-sfe-btn-loading="true"]::after, .mwp-sfe-btn-close-pending[mwp-sfe-btn-loading="true"]::after { background: var(--mwp-sfe-bg-light); } } /* Primary Buttons */ @property --mwp-sfe-btn-grad-start { syntax: ""; inherits: false; initial-value: #2196F3; } @property --mwp-sfe-btn-grad-end { syntax: ""; inherits: false; initial-value: #1976D2; } /* Primary Buttons */ .mwp-sfe-btn-primary-inline, .mwp-sfe-btn-save-inline, .mwp-sfe-btn-submit-inline { --mwp-sfe-btn-grad-start: var(--mwp-sfe-primary); --mwp-sfe-btn-grad-end: var(--mwp-sfe-primary-dark); background: linear-gradient( 135deg, var(--mwp-sfe-btn-grad-start) 0%, var(--mwp-sfe-btn-grad-end) 100% ); border: 1px solid var(--mwp-sfe-primary-darker); transition: --mwp-sfe-btn-grad-start var(--mwp-sfe-transition-fast), --mwp-sfe-btn-grad-end var(--mwp-sfe-transition-fast); } .mwp-sfe-btn-primary-inline:hover, .mwp-sfe-btn-save-inline:hover, .mwp-sfe-btn-submit-inline:hover { --mwp-sfe-btn-grad-start: var(--mwp-sfe-primary-dark); --mwp-sfe-btn-grad-end: var(--mwp-sfe-primary-darker); } .mwp-sfe-btn-primary-inline:disabled, .mwp-sfe-btn-save-inline:disabled, .mwp-sfe-btn-submit-inline:disabled { --mwp-sfe-btn-grad-start: var(--mwp-sfe-primary-dark); --mwp-sfe-btn-grad-end: var(--mwp-sfe-primary-darker); } /* Secondary Buttons */ .mwp-sfe-btn-secondary-inline, .mwp-sfe-btn-cancel-inline, .mwp-sfe-btn-back-edit, .mwp-sfe-btn-close-pending { background: var(--mwp-sfe-bg-medium); border: 1px solid var(--mwp-sfe-border-medium); } .mwp-sfe-btn-secondary-inline:hover, .mwp-sfe-btn-cancel-inline:hover, .mwp-sfe-btn-back-edit:hover, .mwp-sfe-btn-close-pending:hover { background: var(--mwp-sfe-bg-light); border: 1px solid var(--mwp-sfe-border-medium); } .mwp-sfe-btn-secondary-inline:disabled, .mwp-sfe-btn-cancel-inline:disabled, .mwp-sfe-btn-back-edit:disabled, .mwp-sfe-btn-close-pending:disabled { background: var(--mwp-sfe-bg-light); } .mwp-sfe-inline-actions .mwp-sfe-btn:focus { outline: 2px solid var(--mwp-sfe-primary); outline-offset: 2px; } /* ============================================ SUCCESS MESSAGE ============================================ */ .mwp-sfe-inline-success { position: fixed !important; top: 25% !important; left: 50% !important; transform: translate(-50%, -50%) !important; width: min(600px, 95vw) !important; z-index: var(--mwp-sfe-z-success) !important; margin: 0 !important; display: flex; justify-content: center; align-items: center; width: auto; padding: 16px 24px; background: linear-gradient(135deg, var(--mwp-sfe-success) 0%, var(--mwp-sfe-success-dark) 100%); border-radius: var(--mwp-sfe-radius-xlarge); box-shadow: var(--mwp-sfe-shadow-success); animation: mwp-sfe-success-in 0.25s ease; transition: none !important; } /* Discard / deny variant */ .mwp-sfe-inline-discard { background: linear-gradient(135deg, var(--mwp-sfe-failure) 0%, var(--mwp-sfe-failure-dark) 100%) !important; box-shadow: var(--mwp-sfe-shadow-failure) !important; } /* Draft submit / warning variant */ .mwp-sfe-inline-warning { background: linear-gradient(135deg, var(--mwp-sfe-warning) 0%, var(--mwp-sfe-warning-dark) 100%) !important; box-shadow: var(--mwp-sfe-shadow-warning) !important; } /* Comment submit / comment variant */ .mwp-sfe-inline-comment { background: linear-gradient(135deg, var(--mwp-sfe-primary-dark) 0%, var(--mwp-sfe-primary-darker) 100%) !important; box-shadow: var(--mwp-sfe-shadow-comment) !important; } .mwp-sfe-inline-success-message, .mwp-sfe-inline-preview, .mwp-sfe-inline-pending-wrapper { z-index: var(--mwp-sfe-z-success) !important; } @keyframes mwp-sfe-success-in { from { opacity: 0; transform: translateY(-10px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } .mwp-sfe-inline-success-message { display: flex; justify-content: center; align-items: center; gap: var(--mwp-sfe-gap-medium); } .mwp-sfe-inline-success-message svg { width: var(--mwp-sfe-success-icon-size); height: var(--mwp-sfe-success-icon-size); stroke: var(--mwp-sfe-text-light); animation: mwp-sfe-check-draw 0.5s ease 0.2s; flex-shrink: 0; } .mwp-sfe-inline-success-message span { font-family: var(--mwp-sfe-font-family) !important; width: 100%; color: var(--mwp-sfe-text-light); font-size: var(--mwp-sfe-font-size-medium); } @keyframes mwp-sfe-check-draw { from { stroke-dasharray: 100; stroke-dashoffset: 100; } to { stroke-dasharray: 100; stroke-dashoffset: 0; } } /* ============================================ SINGLE-ELEMENT SELECTION ============================================ */ .mwp-sfe-single-element-row { display: flex; flex-direction: column; gap: var(--mwp-sfe-gap-small); } .mwp-sfe-single-element-header { font-size: var(--mwp-sfe-font-size-tiny); color: var(--mwp-sfe-text-muted); margin-bottom: var(--mwp-sfe-gap-tiny); line-height: 1.2; } .mwp-sfe-single-element-buttons { display: flex; gap: var(--mwp-sfe-gap-medium); flex-wrap: wrap; } /* ============================================ MULTI-ELEMENT SELECTION ============================================ */ .mwp-sfe-multi-element-wrapper { display: flex; flex-direction: column; gap: var(--mwp-sfe-gap-medium); width: 100%; } .mwp-sfe-multi-element-container { display: flex; flex-direction: column; gap: var(--mwp-sfe-gap-small); width: 100%; } .mwp-sfe-multi-element-row { display: flex; flex-direction: column; gap: var(--mwp-sfe-gap-small); padding: var(--mwp-sfe-padding-small); border: 2px solid transparent; border-radius: var(--mwp-sfe-radius-large); transition: border-color var(--mwp-sfe-transition-fast), background-color var(--mwp-sfe-transition-fast); cursor: pointer; } .mwp-sfe-multi-element-row:hover { background-color: var(--mwp-sfe-primary-alpha-10); } .mwp-sfe-multi-element-row.mwp-sfe-focused { border-color: var(--mwp-sfe-primary); background-color: var(--mwp-sfe-primary-alpha-10); } .mwp-sfe-multi-element-header { font-size: var(--mwp-sfe-font-size-tiny); color: var(--mwp-sfe-text-muted); margin-bottom: var(--mwp-sfe-gap-tiny); line-height: 1.2; } .mwp-sfe-multi-element-buttons { display: flex; gap: var(--mwp-sfe-gap-medium); flex-wrap: wrap; } .mwp-sfe-multi-element-instructions { font-size: var(--mwp-sfe-font-size-tiny); color: var(--mwp-sfe-text-muted); text-align: center; padding-top: var(--mwp-sfe-gap-small); border-top: 1px solid var(--mwp-sfe-border-dark); line-height: 1.4; } /* ============================================ COMMENT FORM ============================================ */ .mwp-sfe-inline-actions .mwp-sfe-inline-comment-form { display: flex; flex-direction: column; gap: var(--mwp-sfe-gap-medium); width: 300px; } .mwp-sfe-inline-actions .mwp-sfe-inline-comment-textarea { width: auto; resize: vertical; height: 120px; min-height: 60px; max-height: 360px; } .mwp-sfe-inline-actions .mwp-sfe-inline-comment-actions, .mwp-sfe-inline-actions .mwp-sfe-inline-media-upload-actions { display: flex; gap: var(--mwp-sfe-gap-medium); } .mwp-sfe-inline-actions .mwp-sfe-text-entry { line-height: 1.5; background: var(--mwp-sfe-bg-dark); border: 1px solid var(--mwp-sfe-border-medium); outline: none !important; color: var(--mwp-sfe-text-light); padding: var(--mwp-sfe-padding-medium); border-radius: var(--mwp-sfe-radius-medium); font-size: var(--mwp-sfe-font-size-medium); box-shadow: inset var(--mwp-sfe-shadow-light); transition: background var(--mwp-sfe-transition-instant), box-shadow var(--mwp-sfe-transition-instant), border-color var(--mwp-sfe-transition-fast); } .mwp-sfe-inline-actions .mwp-sfe-text-entry:focus { border-color: var(--mwp-sfe-primary); background: var(--mwp-sfe-bg-light); color: var(--mwp-sfe-text-light); box-shadow: inset var(--mwp-sfe-shadow-medium); } /* ============================================ MEDIA EDITOR ============================================ */ .mwp-sfe-inline-actions .mwp-sfe-inline-media-editor { display: flex; flex-direction: column; gap: var(--mwp-sfe-gap-medium); width: 300px; } /* Drop Zone */ .mwp-sfe-inline-actions .mwp-sfe-media-upload-drop-zone { display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; cursor: pointer; line-height: 1.5; text-align: center; height: 150px; background: var(--mwp-sfe-bg-dark); border: 2px dashed var(--mwp-sfe-border-medium); color: var(--mwp-sfe-text-light); padding: var(--mwp-sfe-gap-large); border-radius: var(--mwp-sfe-radius-large); font-size: var(--mwp-sfe-font-size-large); z-index: 0; isolation: isolate; overflow: hidden; box-shadow: inset var(--mwp-sfe-shadow-light); transition: background var(--mwp-sfe-transition-instant), box-shadow var(--mwp-sfe-transition-instant), border-color var(--mwp-sfe-transition-fast); } .mwp-sfe-inline-actions .mwp-sfe-media-upload-drop-zone:focus, .mwp-sfe-inline-actions .mwp-sfe-media-upload-drop-zone:hover { border-color: var(--mwp-sfe-primary); background: var(--mwp-sfe-bg-light); box-shadow: inset var(--mwp-sfe-shadow-medium); transition: background var(--mwp-sfe-transition-instant), box-shadow var(--mwp-sfe-transition-instant), border-color var(--mwp-sfe-transition-fast); } .mwp-sfe-media-upload-drop-zone.mwp-sfe-is-dragging:hover, .mwp-sfe-media-upload-drop-zone.mwp-sfe-is-uploading:hover { border-style: solid; background: var(--mwp-sfe-bg-light) !important; box-shadow: inset var(--mwp-sfe-shadow-medium); cursor: default; } .mwp-sfe-media-upload-drop-zone.mwp-sfe-is-dragging, .mwp-sfe-media-upload-drop-zone.mwp-sfe-is-uploading { border-style: solid; background: var(--mwp-sfe-bg-light); box-shadow: inset var(--mwp-sfe-shadow-medium); animation: pulseBorder 1.5s infinite; } @keyframes pulseBorder { 0% { border-color: var(--mwp-sfe-border-medium); } 50% { border-color: var(--mwp-sfe-primary); } 100% { border-color: var(--mwp-sfe-border-medium); } } /* Animated Upload Border */ @supports (background: conic-gradient(from 0deg, red, blue)) { .mwp-sfe-media-upload-drop-zone.mwp-sfe-is-uploading { border: none; pointer-events: none; padding: 22px; } @property --spread { syntax: ''; initial-value: 270deg; inherits: false; } @property --angle { syntax: ''; initial-value: 0deg; inherits: false; } .mwp-sfe-media-upload-drop-zone.mwp-sfe-is-uploading::before { content: ''; position: absolute; inset: 0; background: conic-gradient( from calc(var(--angle) - (var(--spread) * 0.5)), transparent 0deg, var(--mwp-sfe-primary-dark), var(--mwp-sfe-primary), var(--mwp-sfe-primary-darker), transparent var(--spread) ); animation: syncRotate 1.5s linear infinite; z-index: -2; } .mwp-sfe-media-upload-drop-zone.mwp-sfe-is-uploading::after { content: ''; position: absolute; inset: 2px; background: var(--mwp-sfe-bg-light); border-radius: var(--mwp-sfe-radius-small); z-index: -1; } @keyframes syncRotate { 0% { --angle: 0deg; --spread: 270deg; } 25% { --angle: 90deg; --spread: 180deg; } 50% { --angle: 180deg; --spread: 270deg; } 75% { --angle: 270deg; --spread: 180deg; } 100% { --angle: 360deg; --spread: 270deg; } } } /* ============================================ MEDIA LIBRARY ============================================ */ .mwp-sfe-inline-media-library { display: flex; flex-direction: column; gap: var(--mwp-sfe-gap-medium); width: 300px; } .mwp-sfe-media-library-header { font-size: var(--mwp-sfe-font-size-medium); color: var(--mwp-sfe-text-light); } .mwp-sfe-media-library-message { grid-column: 1 / -1; display: flex; align-items: center; justify-content: center; text-align: center; height: 300px; color: var(--mwp-sfe-text-muted); padding: var(--mwp-sfe-gap-large); } .mwp-sfe-media-library-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); grid-auto-rows: max-content; gap: var(--mwp-sfe-gap-medium); overflow-y: auto; background: var(--mwp-sfe-bg-dark); border: 1px solid var(--mwp-sfe-border-medium); border-radius: var(--mwp-sfe-radius-large); min-height: 300px; max-height: 301px; padding: var(--mwp-sfe-padding-medium); scrollbar-color: var(--mwp-sfe-bg-darkest) var(--mwp-sfe-bg-light); } .mwp-sfe-media-library-item { position: relative; width: 100%; aspect-ratio: 1; background: var(--mwp-sfe-bg-darkest); border: 2px solid var(--mwp-sfe-border-medium); border-radius: var(--mwp-sfe-radius-medium); cursor: pointer; overflow: hidden; transition: all var(--mwp-sfe-transition-fast); display: flex; flex-direction: column; } .mwp-sfe-media-library-item:hover, .mwp-sfe-media-library-item:focus { border-color: var(--mwp-sfe-primary); transform: scale(1.05); outline: none; } .mwp-sfe-media-library-item img { width: 100%; height: 100%; object-fit: cover; } .mwp-sfe-media-library-placeholder { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: var(--mwp-sfe-bg-darkest); } .mwp-sfe-media-library-item-title { position: absolute; bottom: 0; left: 0; right: 0; background: var(--mwp-sfe-black-alpha-80); color: var(--mwp-sfe-text-light); font-size: var(--mwp-sfe-font-size-tiny); padding: var(--mwp-sfe-padding-small); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* ============================================ RICH TEXT EDITOR TOOLBAR ============================================ */ .mwp-sfe-editor-toolbar { display: flex; flex-wrap: wrap; gap: var(--mwp-sfe-gap-medium); } .mwp-sfe-editor-content { outline: none; word-break: break-word; } .mwp-sfe-list-item-text { display: inline; min-width: 1px; } .mwp-sfe-ghost-component { display: none !important; } .mwp-sfe-editable-component.mwp-sfe-ghost-component { cursor: text; display: block !important; } body.mwp-sfe-preview-mode .mwp-sfe-ghost-component, body.mwp-sfe-active-preview .mwp-sfe-ghost-component { display: none !important; } /* Preview should reflect front-end output: never render placeholder UI/text. */ body.mwp-sfe-preview-mode .mwp-sfe-rich-text-placeholder, body.mwp-sfe-active-preview .mwp-sfe-rich-text-placeholder { display: none !important; } body.mwp-sfe-preview-mode .mwp-sfe-rich-text-placeholder::after, body.mwp-sfe-active-preview .mwp-sfe-rich-text-placeholder::after { content: none !important; } .mwp-sfe-rich-text-has-placeholder > .mwp-sfe-rich-text-placeholder, .mwp-sfe-rich-text-has-placeholder li > .mwp-sfe-rich-text-placeholder, .mwp-sfe-editable-component > .mwp-sfe-rich-text-placeholder, .mwp-sfe-editor-content > .mwp-sfe-rich-text-placeholder, body.mwp-sfe-is-editing .mwp-sfe-element-active .mwp-sfe-rich-text-placeholder { pointer-events: none !important; user-select: none !important; -webkit-user-select: none !important; -moz-user-select: none !important; -ms-user-select: none !important; } .mwp-sfe-rich-text-has-placeholder > .mwp-sfe-rich-text-placeholder::after, .mwp-sfe-rich-text-has-placeholder li > .mwp-sfe-rich-text-placeholder::after, .mwp-sfe-editable-component > .mwp-sfe-rich-text-placeholder::after, .mwp-sfe-editor-content > .mwp-sfe-rich-text-placeholder::after, body.mwp-sfe-is-editing .mwp-sfe-element-active .mwp-sfe-rich-text-placeholder::after { content: attr(data-rich-text-placeholder); opacity: 0.62; } /* ============================================ BUTTON GROUPS ============================================ */ .mwp-sfe-editor-toolbar .mwp-sfe-btn-group { display: flex; vertical-align: middle; gap: var(--mwp-sfe-gap-tiny); } /* ============================================ EDITOR BUTTONS ============================================ */ .mwp-sfe-editor-toolbar .mwp-sfe-editor-btn { display: inline-block; width: var(--mwp-sfe-button-size); height: var(--mwp-sfe-button-size); padding: var(--mwp-sfe-padding-editor-btn); background: transparent; border: 1px solid transparent; border-radius: var(--mwp-sfe-radius-medium); cursor: pointer; transition: opacity var(--mwp-sfe-transition-instant), background var(--mwp-sfe-transition-fast), border-color var(--mwp-sfe-transition-fast); } .mwp-sfe-editor-toolbar .mwp-sfe-editor-btn svg { float: left; margin: -1px; } .mwp-sfe-editor-toolbar .mwp-sfe-editor-btn:hover { background: var(--mwp-sfe-primary-alpha-25); border-color: transparent; } .mwp-sfe-editor-toolbar .mwp-sfe-editor-btn.mwp-sfe-editor-btn-active { background: var(--mwp-sfe-primary-alpha-25); border-color: var(--mwp-sfe-primary-alpha-25); } .mwp-sfe-editor-toolbar .mwp-sfe-editor-btn:disabled { opacity: 0.5; background: none; cursor: auto; } /* Text-Based Buttons */ .mwp-sfe-editor-toolbar .mwp-sfe-editor-btn-text { color: var(--mwp-sfe-text-light); font-size: var(--mwp-sfe-font-size-medium); line-height: 1; white-space: nowrap; width: 100%; padding: 0 6px; } /* ============================================ DROPDOWNS ============================================ */ .mwp-sfe-editor-toolbar .mwp-sfe-dropdown { position: relative; display: block; width: var(--mwp-sfe-button-size); height: var(--mwp-sfe-button-size); z-index: var(--mwp-sfe-z-dropdown); } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-content { display: none; position: absolute; font-size: var(--mwp-sfe-font-size-medium); margin-top: -1px; top: 100%; left: 0; background: var(--mwp-sfe-bg-darkest); border: 1px solid var(--mwp-sfe-border-dark); border-radius: var(--mwp-sfe-radius-medium); box-shadow: 0 4px 12px var(--mwp-sfe-black-alpha-40); padding: var(--mwp-sfe-padding-small); } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-content.mwp-sfe-show { display: block; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-content button { height: var(--mwp-sfe-button-inner-size); width: var(--mwp-sfe-button-inner-size); padding: 2px var(--mwp-sfe-padding-small); border-radius: var(--mwp-sfe-radius-small); cursor: pointer; } /* Heading Level Dropdown */ .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level { width: 96px; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level .mwp-sfe-dropdown-content.mwp-sfe-show { min-width: 100%; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level .mwp-sfe-dropdown-toggle { position: absolute; display: flex; align-items: center; width: 100%; padding-left: 6px; cursor: pointer; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level button { display: block; color: var(--mwp-sfe-text-light); font-size: var(--mwp-sfe-font-size-medium); line-height: 1.65; white-space: nowrap; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level .mwp-sfe-dropdown-content button { width: 100%; height: 100%; min-height: var(--mwp-sfe-button-inner-size); text-align: left; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level .mwp-sfe-dropdown-toggle span { display: flex; flex-wrap: nowrap; align-items: center; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level .mwp-sfe-dropdown-toggle svg { position: relative; width: var(--mwp-sfe-icon-size); } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level [data-format="Heading 1"] { font-size: 2em !important; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level [data-format="Heading 2"] { font-size: 1.7em !important; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level [data-format="Heading 3"] { font-size: 1.4em !important; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level [data-format="Heading 4"] { font-size: 1.2em !important; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level [data-format="Heading 5"] { font-size: 1em !important; } .mwp-sfe-editor-toolbar .mwp-sfe-dropdown-heading-level [data-format="Heading 6"] { font-size: .8em !important; } /* ============================================ LINK TOOLTIP / UI ============================================ */ .mwp-sfe-link-ui-wrapper *::selection { background-color: var(--mwp-sfe-primary); color: var(--mwp-sfe-text-light); } .mwp-sfe-link-ui-wrapper span.mwp-sfe-link-preview-wrap { align-content: center; } .mwp-sfe-link-ui-wrapper a { color: var(--mwp-sfe-primary); } .mwp-sfe-link-ui-wrapper a:hover { color: var(--mwp-sfe-primary-dark); } .mwp-sfe-link-ui-wrapper { width: auto; } .mwp-sfe-link-edit { flex-wrap: wrap; gap: var(--mwp-sfe-gap-medium); } .mwp-sfe-link-view { flex-wrap: wrap; color: var(--mwp-sfe-text-light); font-size: var(--mwp-sfe-font-size-medium); gap: var(--mwp-sfe-gap-medium); height: min-content; } .mwp-sfe-link-view span { line-height: 1; } .mwp-sfe-link-preview { line-height: 1; align-self: center; } .mwp-sfe-link-actions { display: flex; gap: var(--mwp-sfe-gap-medium); } .mwp-sfe-link-url { display: flex; flex-direction: column; width: 180px; } .mwp-sfe-inline-actions .mwp-sfe-link-url-entry { line-height: 1 !important; height: auto !important; width: auto !important; background: var(--mwp-sfe-bg-dark) !important; border: 1px solid var(--mwp-sfe-border-medium) !important; outline: none !important; color: var(--mwp-sfe-text-light) !important; padding: var(--mwp-sfe-padding-small) !important; border-radius: var(--mwp-sfe-radius-medium) !important; padding-right: 0 !important; } .mwp-sfe-inline-actions .mwp-sfe-link-url-entry:focus { border-color: var(--mwp-sfe-primary) !important; background: var(--mwp-sfe-bg-light) !important; color: var(--mwp-sfe-text-light) !important; } .mwp-sfe-inline-actions .mwp-sfe-link-url-entry *::selection { background-color: var(--mwp-sfe-primary) !important; color: var(--mwp-sfe-text-light) !important; } .mwp-sfe-link-options { display: flex; flex-direction: row; gap: var(--mwp-sfe-gap-medium); margin-top: var(--mwp-sfe-gap-medium); font-size: var(--mwp-sfe-font-size-small); color: var(--mwp-sfe-text-light); } .mwp-sfe-link-options label { line-height: 1; margin: 0; } /* ============================================ SVG ICON STYLES ============================================ */ .mwp-sfe-fill { fill: var(--mwp-sfe-text-light); } .mwp-sfe-stroke { stroke: var(--mwp-sfe-text-light); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2; fill: none; } .mwp-sfe-thin { stroke-width: 1; } /* ============================================ MODE TOGGLE BAR ============================================ */ .mwp-sfe-mode-toggle-bar { position: fixed; top: 42px; right: 10px; z-index: var(--mwp-sfe-z-mode-toggle); display: flex; flex-direction: column; gap: var(--mwp-sfe-gap-small); padding: var(--mwp-sfe-padding-medium); background: var(--mwp-sfe-bg-darkest); border: 1px solid var(--mwp-sfe-border-dark); border-radius: var(--mwp-sfe-radius-xlarge); box-shadow: var(--mwp-sfe-shadow-elevated); font-family: var(--mwp-sfe-font-family) !important; animation: mwp-sfe-slide-up var(--mwp-sfe-transition-fast); user-select: none; -webkit-user-select: none; overflow: visible; } .mwp-sfe-mode-toggle-header { font-size: var(--mwp-sfe-font-size-tiny); color: var(--mwp-sfe-text-muted); line-height: 1.2; margin-bottom: var(--mwp-sfe-gap-tiny); } .mwp-sfe-mode-toggle-buttons { display: flex; gap: var(--mwp-sfe-gap-medium); } /* Make toggle bar buttons non-flex-grow so they size to content */ .mwp-sfe-mode-toggle-buttons .mwp-sfe-btn { flex: 0 0 auto; } /* ============================================ GRIP BAR ============================================ */ .mwp-sfe-grip-bar { position: fixed; display: inline-grid; grid-auto-flow: column; align-items: center; justify-content: center; gap: var(--mwp-sfe-gap-small); width: 52px; height: 18px; padding: 0 8px; opacity: 0; transform: translate(-50%, 0); transform-origin: center bottom; transition: opacity var(--mwp-sfe-transition-fast) 0.5s, transform var(--mwp-sfe-transition-fast) 0.5s; cursor: grab; touch-action: none; z-index: calc(var(--mwp-sfe-z-mode-toggle) - 1); } .mwp-sfe-grip-bar-dot { width: 4px; height: 4px; border-radius: 50%; background: var(--mwp-sfe-text-muted); } .mwp-sfe-grip-bar[data-mwp-sfe-grip-owner="mode-toggle-bar"] { border: 1px solid var(--mwp-sfe-border-dark); border-bottom: none; border-radius: var(--mwp-sfe-radius-xlarge) var(--mwp-sfe-radius-xlarge) 0 0; background: var(--mwp-sfe-bg-darkest); box-shadow: var(--mwp-sfe-shadow-elevated); } .mwp-sfe-grip-bar.mwp-sfe-is-visible { opacity: 1; transform: translate(-50%, -100%); transition-delay: 0s; } .mwp-sfe-grip-bar.mwp-sfe-is-dragging { cursor: grabbing; } .mwp-sfe-grip-bar.mwp-sfe-is-dragging:hover { transition: none; } /* ============================================ ACTION BAR DOCK STATE ============================================ */ .mwp-sfe-inline-actions.mwp-sfe-state-dock { /* Sit on the same z-layer as the mode-toggle bar so it visually groups with it and renders above page content. */ z-index: var(--mwp-sfe-z-mode-toggle) !important; transition: opacity var(--mwp-sfe-transition-fast); } /* ============================================ PREVIEW MODE (global - no active editor) ============================================ */ body.mwp-sfe-preview-mode .mwp-sfe-overlay-container, body.mwp-sfe-preview-mode .mwp-sfe-inline-preview, body.mwp-sfe-preview-mode .mwp-sfe-inline-pending-wrapper, body.mwp-sfe-preview-mode .mwp-sfe-inline-actions, body.mwp-sfe-preview-mode .mwp-sfe-inline-toolbar { opacity: 0 !important; pointer-events: none !important; transition: opacity var(--mwp-sfe-transition-fast) !important; } body.mwp-sfe-preview-mode [data-mwp-sfe-bound="1"], body.mwp-sfe-preview-mode [data-mwp-sfe-bound="1"] *, body.mwp-sfe-preview-mode .mwp-sfe-editing-disabled, body.mwp-sfe-preview-mode .mwp-sfe-editing-disabled * { cursor: auto !important; } /* ============================================ ACTIVE PREVIEW MODE (editor open but previewing) The editor is kept alive; only the editing UI is hidden and the active element is locked down. The .mwp-sfe-is-editing body class keeps everything else non-interactive. ============================================ */ body.mwp-sfe-active-preview .mwp-sfe-overlay-container, body.mwp-sfe-active-preview .mwp-sfe-inline-toolbar, body.mwp-sfe-active-preview .mwp-sfe-inline-actions { opacity: 0 !important; pointer-events: none !important; transition: opacity var(--mwp-sfe-transition-fast) !important; } /* Keep active editor locked down. */ body.mwp-sfe-active-preview .mwp-sfe-element-active, body.mwp-sfe-active-preview .mwp-sfe-element-active *, body.mwp-sfe-active-preview .mwp-sfe-inline-toolbar *, body.mwp-sfe-active-preview .mwp-sfe-inline-actions * { pointer-events: none !important; } /* In active preview, restore normal page interactions except editor chrome. */ body.mwp-sfe-active-preview * { pointer-events: auto !important; } /* Push the active element below the editing overlay so clicks pass to the overlay rather than into the contenteditable. */ body.mwp-sfe-active-preview .mwp-sfe-element-active { z-index: 1 !important; } body.mwp-sfe-active-preview [data-mwp-sfe-bound="1"]:not(.mwp-sfe-element-active), body.mwp-sfe-active-preview [data-mwp-sfe-bound="1"]:not(.mwp-sfe-element-active) *, body.mwp-sfe-active-preview .mwp-sfe-editing-disabled, body.mwp-sfe-active-preview .mwp-sfe-editing-disabled * { cursor: auto !important; } body.mwp-sfe-preview-mode .mwp-abe-block-sparkle, :host-context(body.mwp-sfe-preview-mode) .mwp-abe-launcher, :host-context(body.mwp-sfe-preview-mode) .mwp-abe-modal, :host-context(body.mwp-sfe-preview-mode) .mwp-abe-drawer, body.mwp-sfe-active-preview .mwp-abe-block-sparkle, :host-context(body.mwp-sfe-active-preview) .mwp-abe-launcher, :host-context(body.mwp-sfe-active-preview) .mwp-abe-modal, :host-context(body.mwp-sfe-active-preview) .mwp-abe-drawer { opacity: 0 !important; pointer-events: none !important; transition: opacity var(--mwp-sfe-transition-fast) !important; } :host-context(body.mwp-sfe-preview-mode) .mwp-abe-launcher, :host-context(body.mwp-sfe-active-preview) .mwp-abe-launcher { transform: translateY(8px) scale(0.92); } :host-context(body.mwp-sfe-preview-mode) .mwp-abe-drawer, :host-context(body.mwp-sfe-active-preview) .mwp-abe-drawer { transform: translateY(24px); } :host-context(body.mwp-sfe-preview-mode) .mwp-abe-modal-panel, :host-context(body.mwp-sfe-active-preview) .mwp-abe-modal-panel { opacity: 0 !important; transform: translateY(24px) scale(0.98); pointer-events: none !important; transition: opacity var(--mwp-sfe-transition-fast) !important; } {"id":1396,"date":"2026-04-26T14:37:22","date_gmt":"2026-04-26T14:37:22","guid":{"rendered":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/2026\/04\/26\/best-casino-app-new-zealand-your-2025-mobile-gaming-guide-4\/"},"modified":"2026-04-26T14:37:22","modified_gmt":"2026-04-26T14:37:22","slug":"best-casino-app-new-zealand-your-2025-mobile-gaming-guide-4","status":"publish","type":"post","link":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/2026\/04\/26\/best-casino-app-new-zealand-your-2025-mobile-gaming-guide-4\/","title":{"rendered":"Best casino app New Zealand: your 2025 mobile gaming guide"},"content":{"rendered":"

Finding the best casino app New Zealand has to offer can feel like a daunting task, but it doesn\u2019t have to be. With the rapid growth of mobile gaming, Kiwi players now have access to hundreds of casino platforms that promise big bonuses, flashy graphics, and instant payouts. However, not all of them deliver. That\u2019s why we\u2019ve tested and analysed the most popular apps on the market, focusing on what matters most to local users: reliability, game variety, banking speed, and fair licensing.<\/p>\n

This guide is designed for New Zealanders who want a safe and enjoyable casino experience straight from their phone or tablet. We\u2019ll walk you through the key features of the leading mobile casinos, compare their strengths, and help you make an informed choice. Whether you\u2019re a seasoned spinner or a newcomer looking for a fun way to pass the time, you\u2019ll find practical advice and honest recommendations here.<\/p>\n

What makes a casino app the best in NZ?<\/h2>\n

A truly great casino app feels intuitive from the moment you open it. Navigation should be smooth, with games sorted into clear categories such as pokies, table games, and live dealer titles. The best apps also load quickly, even on older devices, and support both portrait and landscape orientations. In New Zealand, where mobile data can be costly, an app that allows you to adjust video quality for live streams is a big plus.<\/p>\n

Game variety is another cornerstone. The top platforms partner with leading software providers like Microgaming, NetEnt, and Evolution Gaming, ensuring a steady stream of new titles. For example, spinbit casino online game has gained popularity among Kiwis for its extensive library of pokies and live casino options. This platform demonstrates how a well-optimised app can deliver a premium gaming experience without lag or crashes.<\/p>\n

Of course, the real test is banking. A NZ-friendly casino app should support local currencies and popular payment methods like POLi, bank transfers, and credit cards. Instant withdrawals are a major advantage, as are reasonable betting limits. Combine this with a responsive customer support team that understands Kiwi English, and you have a strong candidate for the title of best casino app New Zealand users can trust.<\/p>\n

How we selected and ranked the apps<\/h2>\n

Our evaluation process is straightforward. We start by checking the licensing status of each casino, favouring platforms regulated by respected authorities such as the Malta Gaming Authority, the UK Gambling Commission, or the New Zealand Department of Internal Affairs for offshore providers. We then sign up, verify our identity, and make a small deposit to test the user journey from start to finish.<\/p>\n

We also assess the mobile experience on both iOS and Android devices. We look at the strength of the software, game selection, and betting features, and we time every transaction, from deposits to withdrawals. Rather than relying on marketing claims, our team always makes sure to visit online<\/a> and play for real money. This hands-on approach gives us reliable data, which we combine with player reviews and independent forums to get a balanced view.<\/p>\n

For this guide, we shortlisted 15 popular casino apps that are accessible to New Zealanders. After two weeks of rigorous testing, we narrowed the list down to the five that consistently performed well in all categories. Our methodology prioritises user safety first, entertainment value second, and only then do we consider the scale of the welcome bonus.<\/p>\n

Side-by-side comparison: top casino apps for Kiwis<\/h2>\n

To help you see the landscape at a glance, we\u2019ve put together a comparison table of the standout platforms from our testing. The table highlights the key details every New Zealand player should consider before signing up.<\/p>\n\n\n\n\n\n\n\n
Casino App<\/th>\nGame Variety<\/th>\nWithdrawal Speed<\/th>\nWelcome Bonus<\/th>\nNZ Bank Support<\/th>\n<\/tr>\n<\/thead>\n
Spinbit<\/td>\n800+ slots<\/td>\n1-3 days<\/td>\n100% up to NZ$1500<\/td>\nYes<\/td>\n<\/tr>\n
Galactic Wins<\/td>\n600+ slots<\/td>\n24 hours<\/td>\nFree spins + NZ$500<\/td>\nYes<\/td>\n<\/tr>\n
Hellspin<\/td>\n700+ slots<\/td>\n1-2 days<\/td>\n200% up to NZ$2000<\/td>\nYes<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n

As you can see, these apps all offer solid banking support, but the differences in game libraries and bonus structures may sway your decision. If you value rapid payouts, Galactic Wins takes the lead. If you prefer a massive welcome boost, Hellspin stands out. Spinbit, meanwhile, is a dependable all-rounder.<\/p>\n

Bonuses and free spins for new players<\/h2>\n

A generous welcome bonus can stretch your bankroll, but you should always read the fine print. Wagering requirements, maximum cash-out limits, and game restrictions can turn a seemingly attractive deal into a trap. The best casino app New Zealand players love will offer low wagering requirements, usually around 20x to 35x, and allow you to claim the bonus with standard pokies.<\/p>\n

Free spins are another favourite among Kiwis. Many apps offer no-deposit free spins just for signing up, giving you a risk-free taste of the action. However, keep an eye on the validity period and the maximum win from free spins. For a complete breakdown of current promotional offers, check this useful link<\/a> to stay updated.<\/p>\n

In our experience, top-rated apps refresh their promotions regularly, including reload bonuses, weekend cashback, and loyalty programs. A strong VIP scheme is a good sign that the casino values its regular players. Just remember to set a budget and treat bonuses as entertainment rather than a guaranteed income.<\/p>\n

Fast and secure payment methods for NZ players<\/h2>\n

New Zealanders have several convenient ways to move money into and out of casino apps. Classic bank transfers are reliable, but they can take a few business days. E-wallets such as Skrill and Neteller offer faster withdrawals, while prepaid cards like Paysafecard are ideal for maintaining strict control over deposits. Increasingly, casinos are also accepting cryptocurrencies like Bitcoin, which provide near-instant transactions.<\/p>\n

When choosing an app, verify which payment methods are available in New Zealand and whether there are any fees. Some banks decline gambling-related transactions, so a casino that supports POLi or direct debit can save you a headache. For a detailed example of how a modern platform handles compliance, read the full review at https:\/\/bicestorhorsebox.maliknabeel.com\/h1-hellspin-casino-online-in-New%20Zealand-a-fresh-take-on-digital-gaming-h1\/<\/a>. The second comparison table below shows the differences at a glance.<\/p>\n\n\n\n\n\n\n\n\n
Payment Method<\/th>\nDeposit Speed<\/th>\nWithdrawal Speed<\/th>\nTypical Fees<\/th>\n<\/tr>\n<\/thead>\n
Credit\/Debit Card<\/td>\nInstant<\/td>\n2-5 days<\/td>\n0-2%<\/td>\n<\/tr>\n
POLi<\/td>\nInstant<\/td>\n1-3 days<\/td>\n0%<\/td>\n<\/tr>\n
Skrill<\/td>\nInstant<\/td>\n12-24 hours<\/td>\n0-3%<\/td>\n<\/tr>\n
Bitcoin<\/td>\nInstant<\/td>\n30 minutes<\/td>\nNetwork fee<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n

Bitcoin is clearly the fastest option for withdrawals, but not everyone is comfortable with cryptocurrency. For everyday Kiwi players, POLi and debit cards are perfectly serviceable. The key is to choose a method that matches your priorities, whether it\u2019s speed, simplicity, or anonymity.<\/p>\n

Keeping your data safe at online casinos<\/h2>\n

Security is the most critical factor when rating any casino app. A trustworthy platform will use SSL encryption to protect your personal and financial information. Look for logos from independent auditors like eCOGRA or iTech Labs, which verify the fairness of the games and the reliability of the random number generator.<\/p>\n

Another important element is the casino\u2019s privacy policy. It should explain exactly how your data is collected, stored, and shared. Avoid apps that sell your information to third parties or bombard you with spam. In an age where cyber threats are on the rise, taking a few extra seconds to secure your account is always worthwhile.<\/p>\n

Expert views on the future of mobile gambling in NZ<\/h2>\n

Industry experts predict that New Zealand\u2019s mobile gambling market will continue to grow as 5G coverage expands and smartphone technology improves. According to a 2024 report from the Department of Internal Affairs, online wagering participation has increased by 15% over the past two years, with most of that growth coming from mobile apps.<\/p>\n

The move toward live dealer games and virtual reality casinos is another trend to watch. As one gaming analyst put it, \u201cThe next generation of casino apps will blur the line between online and land-based venues, offering Kiwis a truly immersive experience from their sofa.\u201d We\u2019re already seeing early adopters, and the best casino app New Zealand will have tomorrow will almost certainly embrace these technologies.<\/p>\n

However, experts also caution that increased accessibility brings responsible gambling concerns. As a result, we expect to see more advanced self-exclusion tools and mandatory deposit limits become standard in the industry. This is a positive development for player welfare.<\/p>\n

Practical tips for selecting a safe and enjoyable casino app<\/h2>\n

Based on our testing and analysis, here are seven practical recommendations to guide your choice.<\/p>\n

    \n
  • Check the casino\u2019s licensing and read reviews from other New Zealand players.<\/li>\n
  • Test the app\u2019s performance on your own device, especially game loading times and touch response.<\/li>\n
  • Look for apps that offer a wide range of betting limits to suit both casual players and high rollers.<\/li>\n
  • Confirm that your preferred payment method is supported and that withdrawals are not subject to excessive delays.<\/li>\n
  • Preview the welcome bonus terms, including wagering requirements and maximum cash-out.<\/li>\n
  • See if the app provides reliable customer support via live chat or email in English.<\/li>\n
  • Set a personal budget and use deposit limits to keep your gaming habits healthy.<\/li>\n<\/ul>\n

    Following these steps will help you avoid common pitfalls and find an app that delivers hours of entertainment without unnecessary stress.<\/p>\n

    Ready to find your perfect casino app?<\/h2>\n

    Now that you have all the information you need, it\u2019s time to put your knowledge into action. The ideal casino app for you will depend on your personal preferences: whether you prioritise fast payouts, a huge game library, or a generous welcome offer. Take a look at the apps we\u2019ve compared above, but remember to do your own quick check before depositing.<\/p>\n

    Start your mobile gaming journey today by testing one of the recommended apps with a small deposit. Feel the excitement of spinning the reels, play a few hands of blackjack, or join a live dealer table \u2013 your next favourite pastime could be just a tap away. Play responsibly, set your limits, and enjoy everything the best casino app New Zealand has to offer.<\/p>\n","protected":false},"excerpt":{"rendered":"

    Finding the best casino app New Zealand has to offer can feel like a daunting task, but it doesn\u2019t have […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1396","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/wp-json\/wp\/v2\/posts\/1396","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/wp-json\/wp\/v2\/comments?post=1396"}],"version-history":[{"count":0,"href":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/wp-json\/wp\/v2\/posts\/1396\/revisions"}],"wp:attachment":[{"href":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/wp-json\/wp\/v2\/media?parent=1396"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/wp-json\/wp\/v2\/categories?post=1396"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spdev.emptyops.com\/temp_for_wbc_final_test_2\/wp-json\/wp\/v2\/tags?post=1396"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}