feat(branding): re-theme Bootstrap to the brand colour; 3D neon button hover; hide Mensalidades link without plans
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4b2823d1e5
commit
32f8d7a613
6 files changed
+307
-1
No files matched your search
@@ -153,3 +153,6 @@ or adapted for production, and these accounts must never exist in a production d
|
|||||||
- `includes/navbar.php` (barra antiga) foi apagado; `system_settings.php` já não o inclui.
|
- `includes/navbar.php` (barra antiga) foi apagado; `system_settings.php` já não o inclui.
|
||||||
- `views/staff/dashboard.php`: saudação mínima (o staff ainda não alcança nada em `views/admin/`).
|
- `views/staff/dashboard.php`: saudação mínima (o staff ainda não alcança nada em `views/admin/`).
|
||||||
- Gotcha de dev: a tabela `trial_leads` não existe na BD de dev, por isso `views/admin/trials/index.php` dá 500 (migração por aplicar; anterior a esta mudança).
|
- Gotcha de dev: a tabela `trial_leads` não existe na BD de dev, por isso `views/admin/trials/index.php` dá 500 (migração por aplicar; anterior a esta mudança).
|
||||||
|
|
||||||
|
## Bootstrap re-tematizado (2026-10-13)
|
||||||
|
- `assets/css/bs-brand.css` (carregado depois do Bootstrap em `includes/header.php` e `includes/auth_header.php`) sobrescreve as cores do Bootstrap só com variáveis `--bs-*` e as variáveis de componente (`.btn-*`, `.form-check-input`, `.page-link`…), claro e escuro. A cor de marca é `--fitme-accent` (fallback `#C2D500`); todos os tons derivam dela com `color-mix()`; `--brand-on` é o texto sobre a cor. Secondary/success/danger/warning/info têm valores próprios. Verificação: `platform.php?tool=branding` (Montra da marca) não deve mostrar nenhum azul por omissão. O site público ainda não carrega este ficheiro.
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
/* ── Bootstrap re-themed to the FitMe brand ──────────────────────────────────
|
||||||
|
Loaded after bootstrap.min.css (and before backoffice.css). Bootstrap's source
|
||||||
|
is never edited: everything here is --bs-* variables plus the component-scoped
|
||||||
|
variables Bootstrap 5.3 exposes (.btn-*, .form-check-input, .page-link …).
|
||||||
|
The brand colour is a single token, --fitme-accent (a gym's own colour on the
|
||||||
|
public site, see gym_brand_css()); every shade below is derived from it with
|
||||||
|
color-mix(), so changing the brand colour re-themes all of Bootstrap at once.
|
||||||
|
The other semantic colours (success/danger/warning/info) are tuned to sit next
|
||||||
|
to the brand without being confused with it. */
|
||||||
|
:root,
|
||||||
|
[data-bs-theme="light"],
|
||||||
|
[data-bs-theme="dark"] {
|
||||||
|
--brand: var(--fitme-accent, #C2D500);
|
||||||
|
--brand-ink: color-mix(in srgb, var(--brand) 55%, #000); /* text on light surfaces */
|
||||||
|
--brand-on: var(--fitme-on-accent, #0B0B0D); /* text on the brand colour */
|
||||||
|
|
||||||
|
--bs-primary: var(--brand);
|
||||||
|
--bs-primary-rgb: var(--fitme-accent-rgb, 194, 213, 0);
|
||||||
|
--bs-secondary: #3D403E;
|
||||||
|
--bs-secondary-rgb: 61, 64, 62;
|
||||||
|
--bs-success: #2E9E5B;
|
||||||
|
--bs-success-rgb: 46, 158, 91;
|
||||||
|
--bs-danger: #D6322E;
|
||||||
|
--bs-danger-rgb: 214, 50, 46;
|
||||||
|
--bs-warning: #F2A900;
|
||||||
|
--bs-warning-rgb: 242, 169, 0;
|
||||||
|
--bs-info: #2C9FD0;
|
||||||
|
--bs-info-rgb: 44, 159, 208;
|
||||||
|
--bs-light: #F7F8FA;
|
||||||
|
--bs-light-rgb: 247, 248, 250;
|
||||||
|
--bs-dark: #0B0B0D;
|
||||||
|
--bs-dark-rgb: 11, 11, 13;
|
||||||
|
|
||||||
|
--bs-focus-ring-color: color-mix(in srgb, var(--brand) 40%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subtle / emphasis / border tints: light theme (tint 80 / 60, shade 60) … */
|
||||||
|
:root,
|
||||||
|
[data-bs-theme="light"] {
|
||||||
|
--bs-primary-text-emphasis: color-mix(in srgb, var(--brand) 40%, #000);
|
||||||
|
--bs-primary-bg-subtle: color-mix(in srgb, var(--brand) 20%, #fff);
|
||||||
|
--bs-primary-border-subtle: color-mix(in srgb, var(--brand) 40%, #fff);
|
||||||
|
--bs-secondary-text-emphasis: #191a19;
|
||||||
|
--bs-secondary-bg-subtle: #e5e6e5;
|
||||||
|
--bs-secondary-border-subtle: #c5c6c5;
|
||||||
|
--bs-success-text-emphasis: #124f2c;
|
||||||
|
--bs-success-bg-subtle: #d5ecde;
|
||||||
|
--bs-success-border-subtle: #acdabd;
|
||||||
|
--bs-danger-text-emphasis: #561411;
|
||||||
|
--bs-danger-bg-subtle: #f7d6d5;
|
||||||
|
--bs-danger-border-subtle: #efadac;
|
||||||
|
--bs-warning-text-emphasis: #613f00;
|
||||||
|
--bs-warning-bg-subtle: #fceecc;
|
||||||
|
--bs-warning-border-subtle: #fadf99;
|
||||||
|
--bs-info-text-emphasis: #11404e;
|
||||||
|
--bs-info-bg-subtle: #d5ecf6;
|
||||||
|
--bs-info-border-subtle: #abd9ec;
|
||||||
|
--bs-link-color: var(--brand-ink);
|
||||||
|
--bs-link-color-rgb: 0, 0, 0;
|
||||||
|
--bs-link-hover-color: color-mix(in srgb, var(--brand) 40%, #000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* … dark theme (tint 40, shade 80 / 60) */
|
||||||
|
[data-bs-theme="dark"] {
|
||||||
|
--bs-primary-text-emphasis: color-mix(in srgb, var(--brand) 60%, #fff);
|
||||||
|
--bs-primary-bg-subtle: color-mix(in srgb, var(--brand) 20%, #000);
|
||||||
|
--bs-primary-border-subtle: color-mix(in srgb, var(--brand) 40%, #000);
|
||||||
|
--bs-secondary-text-emphasis: #b1b2b1;
|
||||||
|
--bs-secondary-bg-subtle: #131413;
|
||||||
|
--bs-secondary-border-subtle: #252726;
|
||||||
|
--bs-success-text-emphasis: #82c59d;
|
||||||
|
--bs-success-bg-subtle: #09200f;
|
||||||
|
--bs-success-border-subtle: #1c5f36;
|
||||||
|
--bs-danger-text-emphasis: #e88380;
|
||||||
|
--bs-danger-bg-subtle: #2b0a09;
|
||||||
|
--bs-danger-border-subtle: #801e1c;
|
||||||
|
--bs-warning-text-emphasis: #f7ca66;
|
||||||
|
--bs-warning-bg-subtle: #302200;
|
||||||
|
--bs-warning-border-subtle: #916800;
|
||||||
|
--bs-info-text-emphasis: #80c5e3;
|
||||||
|
--bs-info-bg-subtle: #0e2833;
|
||||||
|
--bs-info-border-subtle: #1a5f7d;
|
||||||
|
--bs-link-color: var(--brand);
|
||||||
|
--bs-link-color-rgb: var(--fitme-accent-rgb, 194, 213, 0);
|
||||||
|
--bs-link-hover-color: color-mix(in srgb, var(--brand) 75%, #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Components: Bootstrap hard-codes white text on solid primary/semantic
|
||||||
|
fills; the brand colour is light, so the text must be dark. ─────────────── */
|
||||||
|
.btn-primary {
|
||||||
|
--bs-btn-color: var(--brand-on);
|
||||||
|
--bs-btn-bg: var(--brand);
|
||||||
|
--bs-btn-border-color: var(--brand);
|
||||||
|
--bs-btn-hover-color: var(--brand-on);
|
||||||
|
--bs-btn-hover-bg: color-mix(in srgb, var(--brand) 86%, #000);
|
||||||
|
--bs-btn-hover-border-color: color-mix(in srgb, var(--brand) 80%, #000);
|
||||||
|
--bs-btn-focus-shadow-rgb: var(--fitme-accent-rgb, 194, 213, 0);
|
||||||
|
--bs-btn-active-color: var(--brand-on);
|
||||||
|
--bs-btn-active-bg: color-mix(in srgb, var(--brand) 78%, #000);
|
||||||
|
--bs-btn-active-border-color: color-mix(in srgb, var(--brand) 70%, #000);
|
||||||
|
--bs-btn-disabled-color: var(--brand-on);
|
||||||
|
--bs-btn-disabled-bg: var(--brand);
|
||||||
|
--bs-btn-disabled-border-color: var(--brand);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline-primary {
|
||||||
|
--bs-btn-color: var(--brand-ink);
|
||||||
|
--bs-btn-border-color: var(--brand);
|
||||||
|
--bs-btn-hover-color: var(--brand-on);
|
||||||
|
--bs-btn-hover-bg: var(--brand);
|
||||||
|
--bs-btn-hover-border-color: var(--brand);
|
||||||
|
--bs-btn-focus-shadow-rgb: var(--fitme-accent-rgb, 194, 213, 0);
|
||||||
|
--bs-btn-active-color: var(--brand-on);
|
||||||
|
--bs-btn-active-bg: var(--brand);
|
||||||
|
--bs-btn-active-border-color: var(--brand);
|
||||||
|
--bs-btn-disabled-color: var(--brand-ink);
|
||||||
|
--bs-btn-disabled-border-color: var(--brand);
|
||||||
|
}
|
||||||
|
[data-bs-theme="dark"] .btn-outline-primary { --bs-btn-color: var(--brand); --bs-btn-disabled-color: var(--brand); }
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
--bs-btn-bg: var(--bs-secondary);
|
||||||
|
--bs-btn-border-color: var(--bs-secondary);
|
||||||
|
--bs-btn-hover-bg: #2f3230;
|
||||||
|
--bs-btn-hover-border-color: #2b2d2c;
|
||||||
|
--bs-btn-active-bg: #2b2d2c;
|
||||||
|
--bs-btn-active-border-color: #262826;
|
||||||
|
--bs-btn-disabled-bg: var(--bs-secondary);
|
||||||
|
--bs-btn-disabled-border-color: var(--bs-secondary);
|
||||||
|
}
|
||||||
|
.btn-outline-secondary {
|
||||||
|
--bs-btn-color: var(--bs-secondary);
|
||||||
|
--bs-btn-border-color: var(--bs-secondary);
|
||||||
|
--bs-btn-hover-bg: var(--bs-secondary);
|
||||||
|
--bs-btn-hover-border-color: var(--bs-secondary);
|
||||||
|
--bs-btn-active-bg: var(--bs-secondary);
|
||||||
|
--bs-btn-active-border-color: var(--bs-secondary);
|
||||||
|
--bs-btn-disabled-color: var(--bs-secondary);
|
||||||
|
--bs-btn-disabled-border-color: var(--bs-secondary);
|
||||||
|
}
|
||||||
|
[data-bs-theme="dark"] .btn-outline-secondary { --bs-btn-color: #9a9d9b; --bs-btn-border-color: #5b5f5d; }
|
||||||
|
|
||||||
|
.btn-success { --bs-btn-bg: var(--bs-success); --bs-btn-border-color: var(--bs-success); --bs-btn-hover-bg: #27864d; --bs-btn-hover-border-color: #257d49; --bs-btn-active-bg: #257d49; --bs-btn-active-border-color: #227545; --bs-btn-disabled-bg: var(--bs-success); --bs-btn-disabled-border-color: var(--bs-success); }
|
||||||
|
.btn-danger { --bs-btn-bg: var(--bs-danger); --bs-btn-border-color: var(--bs-danger); --bs-btn-hover-bg: #b62a27; --bs-btn-hover-border-color: #ab2825; --bs-btn-active-bg: #ab2825; --bs-btn-active-border-color: #a02622; --bs-btn-disabled-bg: var(--bs-danger); --bs-btn-disabled-border-color: var(--bs-danger); }
|
||||||
|
.btn-warning { --bs-btn-bg: var(--bs-warning); --bs-btn-border-color: var(--bs-warning); --bs-btn-hover-bg: #f5b61f; --bs-btn-hover-border-color: #f4b212; --bs-btn-active-bg: #f6bb2b; --bs-btn-active-border-color: #f4b212; --bs-btn-disabled-bg: var(--bs-warning); --bs-btn-disabled-border-color: var(--bs-warning); }
|
||||||
|
.btn-info { --bs-btn-bg: var(--bs-info); --bs-btn-border-color: var(--bs-info); --bs-btn-hover-bg: #52b0d9; --bs-btn-hover-border-color: #42a9d6; --bs-btn-active-bg: #5bb5dc; --bs-btn-active-border-color: #42a9d6; --bs-btn-disabled-bg: var(--bs-info); --bs-btn-disabled-border-color: var(--bs-info); }
|
||||||
|
.btn-outline-success { --bs-btn-color: var(--bs-success); --bs-btn-border-color: var(--bs-success); --bs-btn-hover-bg: var(--bs-success); --bs-btn-hover-border-color: var(--bs-success); --bs-btn-active-bg: var(--bs-success); --bs-btn-active-border-color: var(--bs-success); --bs-btn-disabled-color: var(--bs-success); --bs-btn-disabled-border-color: var(--bs-success); }
|
||||||
|
.btn-outline-danger { --bs-btn-color: var(--bs-danger); --bs-btn-border-color: var(--bs-danger); --bs-btn-hover-bg: var(--bs-danger); --bs-btn-hover-border-color: var(--bs-danger); --bs-btn-active-bg: var(--bs-danger); --bs-btn-active-border-color: var(--bs-danger); --bs-btn-disabled-color: var(--bs-danger); --bs-btn-disabled-border-color: var(--bs-danger); }
|
||||||
|
.btn-outline-warning { --bs-btn-color: #b07a00; --bs-btn-border-color: var(--bs-warning); --bs-btn-hover-bg: var(--bs-warning); --bs-btn-hover-border-color: var(--bs-warning); --bs-btn-active-bg: var(--bs-warning); --bs-btn-active-border-color: var(--bs-warning); --bs-btn-disabled-color: #b07a00; --bs-btn-disabled-border-color: var(--bs-warning); }
|
||||||
|
.btn-outline-info { --bs-btn-color: #1f7ea6; --bs-btn-border-color: var(--bs-info); --bs-btn-hover-bg: var(--bs-info); --bs-btn-hover-border-color: var(--bs-info); --bs-btn-active-bg: var(--bs-info); --bs-btn-active-border-color: var(--bs-info); --bs-btn-disabled-color: #1f7ea6; --bs-btn-disabled-border-color: var(--bs-info); }
|
||||||
|
[data-bs-theme="dark"] .btn-outline-warning { --bs-btn-color: var(--bs-warning); --bs-btn-disabled-color: var(--bs-warning); }
|
||||||
|
[data-bs-theme="dark"] .btn-outline-info { --bs-btn-color: var(--bs-info); --bs-btn-disabled-color: var(--bs-info); }
|
||||||
|
.btn-success, .btn-danger, .btn-info, .btn-outline-success, .btn-outline-danger, .btn-outline-info { --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff; }
|
||||||
|
.btn-success, .btn-danger, .btn-info { --bs-btn-color: #fff; --bs-btn-disabled-color: #fff; }
|
||||||
|
.btn-warning, .btn-outline-warning { --bs-btn-hover-color: #0B0B0D; --bs-btn-active-color: #0B0B0D; }
|
||||||
|
.btn-warning { --bs-btn-color: #0B0B0D; --bs-btn-disabled-color: #0B0B0D; }
|
||||||
|
|
||||||
|
/* ── Solid fills that use the colour as background ───────────────────────── */
|
||||||
|
.text-bg-primary { color: var(--brand-on) !important; background-color: var(--brand) !important; }
|
||||||
|
.text-bg-secondary { background-color: var(--bs-secondary) !important; }
|
||||||
|
.text-bg-success { background-color: var(--bs-success) !important; }
|
||||||
|
.text-bg-danger { background-color: var(--bs-danger) !important; }
|
||||||
|
.text-bg-warning { color: #0B0B0D !important; background-color: var(--bs-warning) !important; }
|
||||||
|
.text-bg-info { color: #fff !important; background-color: var(--bs-info) !important; }
|
||||||
|
.link-primary { color: var(--brand-ink) !important; }
|
||||||
|
[data-bs-theme="dark"] .link-primary { color: var(--brand) !important; }
|
||||||
|
|
||||||
|
/* ── Forms ───────────────────────────────────────────────────────────────── */
|
||||||
|
.form-control:focus, .form-select:focus {
|
||||||
|
border-color: color-mix(in srgb, var(--brand) 70%, #000);
|
||||||
|
box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color);
|
||||||
|
}
|
||||||
|
.form-check-input:checked,
|
||||||
|
.form-check-input[type="checkbox"]:indeterminate {
|
||||||
|
background-color: var(--brand);
|
||||||
|
border-color: var(--brand);
|
||||||
|
}
|
||||||
|
/* the tick / dot / knob are inline SVGs with a hard-coded white fill */
|
||||||
|
.form-check-input:checked[type="checkbox"] {
|
||||||
|
--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%230B0B0D' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
|
||||||
|
}
|
||||||
|
.form-check-input:checked[type="radio"] {
|
||||||
|
--bs-form-check-bg-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%230B0B0D'/%3e%3c/svg%3e");
|
||||||
|
}
|
||||||
|
.form-check-input:focus { border-color: var(--brand); box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }
|
||||||
|
.form-switch .form-check-input:focus {
|
||||||
|
--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23B9C65A'/%3e%3c/svg%3e");
|
||||||
|
}
|
||||||
|
.form-switch .form-check-input:checked {
|
||||||
|
--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%230B0B0D'/%3e%3c/svg%3e");
|
||||||
|
}
|
||||||
|
.form-range::-webkit-slider-thumb { background-color: var(--brand); }
|
||||||
|
.form-range::-webkit-slider-thumb:active { background-color: color-mix(in srgb, var(--brand) 60%, #fff); }
|
||||||
|
.form-range::-moz-range-thumb { background-color: var(--brand); }
|
||||||
|
.form-range::-moz-range-thumb:active { background-color: color-mix(in srgb, var(--brand) 60%, #fff); }
|
||||||
|
.form-range:focus::-webkit-slider-thumb { box-shadow: 0 0 0 1px #fff, 0 0 0 .25rem var(--bs-focus-ring-color); }
|
||||||
|
.form-range:focus::-moz-range-thumb { box-shadow: 0 0 0 1px #fff, 0 0 0 .25rem var(--bs-focus-ring-color); }
|
||||||
|
.was-validated .form-control:valid, .form-control.is-valid,
|
||||||
|
.was-validated .form-select:valid, .form-select.is-valid { border-color: var(--bs-success); }
|
||||||
|
.was-validated .form-control:invalid, .form-control.is-invalid,
|
||||||
|
.was-validated .form-select:invalid, .form-select.is-invalid { border-color: var(--bs-danger); }
|
||||||
|
|
||||||
|
/* ── Navigation & lists ──────────────────────────────────────────────────── */
|
||||||
|
.nav {
|
||||||
|
--bs-nav-link-color: var(--bs-link-color);
|
||||||
|
--bs-nav-link-hover-color: var(--bs-link-hover-color);
|
||||||
|
}
|
||||||
|
.nav-pills {
|
||||||
|
--bs-nav-pills-link-active-color: var(--brand-on);
|
||||||
|
--bs-nav-pills-link-active-bg: var(--brand);
|
||||||
|
}
|
||||||
|
.nav-tabs .nav-link.active, .nav-tabs .nav-item.show .nav-link { border-top: 2px solid var(--brand); }
|
||||||
|
.pagination {
|
||||||
|
--bs-pagination-color: var(--bs-link-color);
|
||||||
|
--bs-pagination-hover-color: var(--bs-link-hover-color);
|
||||||
|
--bs-pagination-focus-color: var(--bs-link-hover-color);
|
||||||
|
--bs-pagination-focus-box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color);
|
||||||
|
--bs-pagination-active-color: var(--brand-on);
|
||||||
|
--bs-pagination-active-bg: var(--brand);
|
||||||
|
--bs-pagination-active-border-color: var(--brand);
|
||||||
|
}
|
||||||
|
.list-group { --bs-list-group-active-color: var(--brand-on); --bs-list-group-active-bg: var(--brand); --bs-list-group-active-border-color: var(--brand); }
|
||||||
|
.dropdown-menu { --bs-dropdown-link-active-color: var(--brand-on); --bs-dropdown-link-active-bg: var(--brand); }
|
||||||
|
.accordion {
|
||||||
|
--bs-accordion-active-color: var(--bs-primary-text-emphasis);
|
||||||
|
--bs-accordion-active-bg: var(--bs-primary-bg-subtle);
|
||||||
|
--bs-accordion-btn-focus-border-color: var(--brand);
|
||||||
|
--bs-accordion-btn-focus-box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Feedback ────────────────────────────────────────────────────────────── */
|
||||||
|
.progress { --bs-progress-bar-bg: var(--brand); --bs-progress-bar-color: var(--brand-on); }
|
||||||
|
.alert-primary {
|
||||||
|
--bs-alert-color: var(--bs-primary-text-emphasis);
|
||||||
|
--bs-alert-bg: var(--bs-primary-bg-subtle);
|
||||||
|
--bs-alert-border-color: var(--bs-primary-border-subtle);
|
||||||
|
--bs-alert-link-color: var(--bs-primary-text-emphasis);
|
||||||
|
}
|
||||||
|
.table-primary {
|
||||||
|
--bs-table-color: var(--bs-primary-text-emphasis);
|
||||||
|
--bs-table-bg: var(--bs-primary-bg-subtle);
|
||||||
|
--bs-table-border-color: var(--bs-primary-border-subtle);
|
||||||
|
--bs-table-striped-bg: color-mix(in srgb, var(--bs-primary-bg-subtle) 94%, #000);
|
||||||
|
--bs-table-hover-bg: color-mix(in srgb, var(--bs-primary-bg-subtle) 92%, #000);
|
||||||
|
--bs-table-active-bg: color-mix(in srgb, var(--bs-primary-bg-subtle) 90%, #000);
|
||||||
|
}
|
||||||
|
.border-primary { border-color: var(--brand) !important; }
|
||||||
|
.bg-primary { background-color: var(--brand) !important; color: var(--brand-on); }
|
||||||
|
.text-primary { color: var(--brand-ink) !important; }
|
||||||
|
[data-bs-theme="dark"] .text-primary { color: var(--brand) !important; }
|
||||||
|
.bg-primary-subtle { background-color: var(--bs-primary-bg-subtle) !important; }
|
||||||
|
.text-primary-emphasis { color: var(--bs-primary-text-emphasis) !important; }
|
||||||
|
.border-primary-subtle { border-color: var(--bs-primary-border-subtle) !important; }
|
||||||
@@ -36,7 +36,10 @@ function site_navbar(?array $gym = null): array {
|
|||||||
$items = ['Home' => ['#home', null]];
|
$items = ['Home' => ['#home', null]];
|
||||||
foreach (['Modalidades' => 'modalidades', 'Equipa' => 'equipa', 'Horário' => 'horario',
|
foreach (['Modalidades' => 'modalidades', 'Equipa' => 'equipa', 'Horário' => 'horario',
|
||||||
'Mensalidades' => 'mensalidades', 'Contactos' => 'contactos'] as $label => $sec) {
|
'Mensalidades' => 'mensalidades', 'Contactos' => 'contactos'] as $label => $sec) {
|
||||||
if (gym_section_on($gym, $sec)) $items[$label] = ['#' . $sec, $sec];
|
if (!gym_section_on($gym, $sec)) continue;
|
||||||
|
// No active plans → the section isn't rendered, so no link to it either.
|
||||||
|
if ($sec === 'mensalidades' && !empty($GLOBALS['pdo']) && !site_memberships($GLOBALS['pdo'], (int) $gym['id'])) continue;
|
||||||
|
$items[$label] = ['#' . $sec, $sec];
|
||||||
}
|
}
|
||||||
$nav = [];
|
$nav = [];
|
||||||
foreach ($items as $label => [$hash]) $nav[$label] = gym_url($gym, $hash);
|
foreach ($items as $label => [$hash]) $nav[$label] = gym_url($gym, $hash);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ $app_name = defined('APP_NAME') ? APP_NAME : 'FitMe 3070';
|
|||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
<link href="<?= base_url('assets/vendor/bootstrap5/css/bootstrap.min.css') ?>" rel="stylesheet">
|
<link href="<?= base_url('assets/vendor/bootstrap5/css/bootstrap.min.css') ?>" rel="stylesheet">
|
||||||
|
<link href="<?= htmlspecialchars(_asset_versioned('assets/css/bs-brand.css'), ENT_QUOTES) ?>" rel="stylesheet">
|
||||||
<link href="<?= base_url('assets/vendor/bootstrap-icons/bootstrap-icons.css') ?>" rel="stylesheet">
|
<link href="<?= base_url('assets/vendor/bootstrap-icons/bootstrap-icons.css') ?>" rel="stylesheet">
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ $app_name = defined('APP_NAME') ? APP_NAME : 'FitMe 3070';
|
|||||||
var g=JSON.parse(localStorage.getItem('bo-nav-groups')||'{}');d.setAttribute('data-bo-groups',Object.keys(g).filter(function(k){return g[k]}).join(' '));}catch(e){}
|
var g=JSON.parse(localStorage.getItem('bo-nav-groups')||'{}');d.setAttribute('data-bo-groups',Object.keys(g).filter(function(k){return g[k]}).join(' '));}catch(e){}
|
||||||
</script>
|
</script>
|
||||||
<link href="<?= base_url('assets/vendor/bootstrap5/css/bootstrap.min.css') ?>" rel="stylesheet">
|
<link href="<?= base_url('assets/vendor/bootstrap5/css/bootstrap.min.css') ?>" rel="stylesheet">
|
||||||
|
<link href="<?= htmlspecialchars(_asset_versioned('assets/css/bs-brand.css'), ENT_QUOTES) ?>" rel="stylesheet">
|
||||||
<link href="<?= base_url('assets/vendor/bootstrap-icons/bootstrap-icons.css') ?>" rel="stylesheet">
|
<link href="<?= base_url('assets/vendor/bootstrap-icons/bootstrap-icons.css') ?>" rel="stylesheet">
|
||||||
<link href="<?= base_url('assets/vendor/summernote/summernote-bs5.min.css') ?>" rel="stylesheet">
|
<link href="<?= base_url('assets/vendor/summernote/summernote-bs5.min.css') ?>" rel="stylesheet">
|
||||||
<link href="<?= htmlspecialchars(_asset_versioned('assets/css/backoffice.css'), ENT_QUOTES) ?>" rel="stylesheet">
|
<link href="<?= htmlspecialchars(_asset_versioned('assets/css/backoffice.css'), ENT_QUOTES) ?>" rel="stylesheet">
|
||||||
|
|||||||
@@ -353,6 +353,51 @@ section[id] {
|
|||||||
color: var(--fitme-accent);
|
color: var(--fitme-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── 3D neon extrusion on hover ────────────────────────────────────────────────
|
||||||
|
The button lifts off the "wall" toward the viewer; the faces it leaves behind
|
||||||
|
(the extruded sides) are drawn with stacked hard shadows in the brand colour
|
||||||
|
and lit like neon tubes (glow on top). Colours come from the gym's brand
|
||||||
|
tokens, so each gym glows in its own colour. */
|
||||||
|
.site-btn,
|
||||||
|
.gym-switch-btn {
|
||||||
|
--neon: color-mix(in srgb, var(--fitme-accent) 70%, #fff);
|
||||||
|
--neon-edge: var(--fitme-accent-dark);
|
||||||
|
--depth: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
|
||||||
|
.site-btn,
|
||||||
|
.gym-switch-btn {
|
||||||
|
transition: transform .18s ease, box-shadow .18s ease, background var(--fitme-transition), color var(--fitme-transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-btn:hover,
|
||||||
|
.site-btn:focus-visible,
|
||||||
|
.gym-switch-btn:hover,
|
||||||
|
.gym-switch-btn:focus-visible {
|
||||||
|
transform: translate(calc(var(--depth) * -1), calc(var(--depth) * -1));
|
||||||
|
box-shadow:
|
||||||
|
1px 1px 0 var(--neon-edge),
|
||||||
|
2px 2px 0 var(--neon),
|
||||||
|
3px 3px 0 var(--neon-edge),
|
||||||
|
4px 4px 0 var(--neon),
|
||||||
|
5px 5px 0 var(--neon-edge),
|
||||||
|
6px 6px 0 var(--neon),
|
||||||
|
7px 7px 0 var(--neon-edge),
|
||||||
|
7px 7px 14px 2px rgba(var(--fitme-accent-rgb), .75),
|
||||||
|
10px 10px 30px 4px rgba(var(--fitme-accent-rgb), .45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-btn:active,
|
||||||
|
.gym-switch-btn:active {
|
||||||
|
transform: translate(-2px, -2px);
|
||||||
|
box-shadow:
|
||||||
|
1px 1px 0 var(--neon-edge),
|
||||||
|
2px 2px 0 var(--neon),
|
||||||
|
2px 2px 10px 1px rgba(var(--fitme-accent-rgb), .6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Bootstrap Nav Overrides ───────────────────────────────────────────────── */
|
/* ── Bootstrap Nav Overrides ───────────────────────────────────────────────── */
|
||||||
.nav-link {
|
.nav-link {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|||||||
Reference in new issue
Block a user