diff --git a/src/app/globals.css b/src/app/globals.css
index 7d51803d..c36068d9 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -776,3 +776,163 @@ tbody tr:hover {
opacity: 0.6;
}
}
+
+/* Footer CMS info popup */
+.cms-info-trigger {
+ appearance: none;
+ border: 0;
+ background: transparent;
+ color: var(--link-color-readable, var(--link-color));
+ cursor: pointer;
+ font: inherit;
+ font-size: 0.78rem;
+ font-weight: 800;
+ line-height: 1;
+ padding: 0.35rem 0.5rem;
+ text-decoration: underline;
+ text-decoration-thickness: 2px;
+ text-underline-offset: 3px;
+}
+.cms-info-trigger:hover,
+.cms-info-trigger:focus-visible {
+ color: var(--link-hover-color-readable, var(--link-hover-color));
+}
+.cms-info-trigger:focus-visible,
+.cms-info-close:focus-visible {
+ outline: 3px solid color-mix(in srgb, var(--color-primary) 42%, transparent);
+ outline-offset: 3px;
+}
+.cms-info-backdrop {
+ position: fixed;
+ inset: 0;
+ z-index: 1000;
+ display: grid;
+ place-items: center;
+ padding: 1rem;
+ background: rgba(8, 10, 14, 0.68);
+ backdrop-filter: blur(6px);
+}
+.cms-info-dialog {
+ position: relative;
+ width: min(440px, 100%);
+ border: 1px solid color-mix(in srgb, var(--color-primary) 30%, var(--border));
+ border-radius: 8px;
+ background:
+ linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 12%, transparent), transparent 42%),
+ var(--color-surface);
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.34);
+ color: var(--color-text-readable, var(--color-text));
+ padding: 1.25rem;
+}
+.cms-info-close {
+ position: absolute;
+ top: 0.75rem;
+ right: 0.75rem;
+ display: grid;
+ width: 2rem;
+ height: 2rem;
+ place-items: center;
+ border: 1px solid color-mix(in srgb, var(--color-text-muted) 18%, transparent);
+ border-radius: 999px;
+ background: color-mix(in srgb, var(--color-surface) 84%, transparent);
+ color: var(--color-text-muted-readable, var(--color-text-muted));
+ cursor: pointer;
+ font-weight: 900;
+ line-height: 1;
+}
+.cms-info-close:hover {
+ color: var(--color-text-readable, var(--color-text));
+ border-color: color-mix(in srgb, var(--color-primary) 40%, transparent);
+}
+.cms-info-kicker {
+ color: var(--color-primary-readable, var(--color-primary));
+ font-size: 0.74rem;
+ font-weight: 900;
+ letter-spacing: 0;
+ text-transform: uppercase;
+}
+.cms-info-dialog h2 {
+ margin: 0.2rem 2.2rem 0 0;
+ font-size: 1.75rem;
+ font-weight: 900;
+ line-height: 1.1;
+}
+.cms-info-badge {
+ display: inline-flex;
+ align-items: center;
+ margin-top: 0.65rem;
+ border: 1px solid color-mix(in srgb, var(--color-primary) 34%, transparent);
+ border-radius: 999px;
+ background: color-mix(in srgb, var(--color-primary) 14%, transparent);
+ color: var(--color-text-readable, var(--color-text));
+ font-size: 0.75rem;
+ font-weight: 900;
+ padding: 0.3rem 0.6rem;
+}
+.cms-info-copy {
+ margin: 0.9rem 0 0;
+ color: var(--color-text-muted-readable, var(--color-text-muted));
+ font-size: 0.92rem;
+ line-height: 1.55;
+}
+.cms-info-grid {
+ display: grid;
+ gap: 0.5rem;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ margin: 1rem 0 0;
+}
+.cms-info-grid div {
+ border: 1px solid color-mix(in srgb, var(--color-text-muted) 14%, transparent);
+ border-radius: 8px;
+ background: color-mix(in srgb, var(--color-background) 68%, transparent);
+ padding: 0.7rem;
+}
+.cms-info-grid dt {
+ color: var(--color-text-muted-readable, var(--color-text-muted));
+ font-size: 0.68rem;
+ font-weight: 800;
+ text-transform: uppercase;
+}
+.cms-info-grid dd {
+ margin: 0.18rem 0 0;
+ color: var(--color-text-readable, var(--color-text));
+ font-size: 0.8rem;
+ font-weight: 900;
+ line-height: 1.25;
+}
+.cms-info-credit-list {
+ display: grid;
+ gap: 0.5rem;
+ margin-top: 1rem;
+}
+.cms-info-credit {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ border: 1px solid color-mix(in srgb, var(--color-primary) 18%, transparent);
+ border-radius: 8px;
+ background: color-mix(in srgb, var(--color-primary) 8%, transparent);
+ padding: 0.65rem 0.75rem;
+}
+.cms-info-credit span {
+ color: var(--color-text-readable, var(--color-text));
+ font-weight: 900;
+}
+.cms-info-credit small {
+ color: var(--color-text-muted-readable, var(--color-text-muted));
+ font-size: 0.74rem;
+ font-weight: 700;
+ text-align: right;
+}
+
+@media (max-width: 520px) {
+ .cms-info-dialog { padding: 1rem; }
+ .cms-info-grid { grid-template-columns: 1fr; }
+ .cms-info-credit {
+ align-items: flex-start;
+ flex-direction: column;
+ gap: 0.2rem;
+ }
+ .cms-info-credit small { text-align: left; }
+}
diff --git a/src/components/cms-info-popup.test.tsx b/src/components/cms-info-popup.test.tsx
new file mode 100644
index 00000000..e8e01394
--- /dev/null
+++ b/src/components/cms-info-popup.test.tsx
@@ -0,0 +1,10 @@
+import { renderToStaticMarkup } from "react-dom/server";
+import { describe, expect, it } from "vitest";
+import { CmsInfoPopup } from "@/components/cms-info-popup";
+
+describe("CmsInfoPopup", () => {
+ it("renders the footer trigger", () => {
+ const html = renderToStaticMarkup(
A modern web layer for the hotel community, focused on fast navigation, clean administration, and a familiar AtomCMS experience.
+