Porządkowanie styli Card, addons
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useMemo, useState } from "preact/hooks";
|
||||
import useDraggableFloating from "../hooks/useDraggableFloating.js";
|
||||
import "../../styles/modal.css";
|
||||
import "../../styles/addons.css";
|
||||
|
||||
@@ -73,6 +74,7 @@ export default function InternetAddonsModal({
|
||||
addons = [],
|
||||
cenaOpis = "zł / mies.",
|
||||
}) {
|
||||
const floating = useDraggableFloating("fuz_floating_total_pos_internet_v1");
|
||||
const phonePlans = useMemo(() => mapPhoneYamlToPlans(phoneCards), [phoneCards]);
|
||||
const addonsList = useMemo(() => normalizeAddons(addons), [addons]);
|
||||
|
||||
@@ -484,7 +486,13 @@ export default function InternetAddonsModal({
|
||||
</SectionAccordion>
|
||||
</div>
|
||||
|
||||
<div class="f-floating-total" onClick={(e) => e.stopPropagation()}>
|
||||
<div
|
||||
ref={floating.ref}
|
||||
class="f-floating-total"
|
||||
style={floating.style}
|
||||
{...floating.handlers}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div class="f-floating-total-circle" role="status" aria-label="Cena miesięczna">
|
||||
<span class="f-floating-total-unit">Razem</span>
|
||||
<span class="f-floating-total-amount">{money(totalMonthly)}</span>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useState } from "preact/hooks";
|
||||
import Markdown from "../Markdown.jsx";
|
||||
import OffersSwitches from "../Switches.jsx";
|
||||
import InternetAddonsModal from "./InternetAddonsModal.jsx";
|
||||
import "../../styles/addons.css";
|
||||
import "../../styles/cards.css";
|
||||
|
||||
function formatMoney(amount, currency = "PLN") {
|
||||
if (typeof amount !== "number" || Number.isNaN(amount)) return "";
|
||||
|
||||
140
src/islands/hooks/useDraggableFloating.js
Normal file
140
src/islands/hooks/useDraggableFloating.js
Normal file
@@ -0,0 +1,140 @@
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
|
||||
function clamp(v, min, max) {
|
||||
return Math.max(min, Math.min(max, v));
|
||||
}
|
||||
|
||||
export default function useDraggableFloating(storageKey, opts = {}) {
|
||||
const margin = Number.isFinite(opts.margin) ? opts.margin : 12;
|
||||
|
||||
const ref = useRef(null);
|
||||
|
||||
const [pos, setPos] = useState(() => {
|
||||
if (typeof window === "undefined") return { x: null, y: null };
|
||||
try {
|
||||
const raw = localStorage.getItem(storageKey);
|
||||
return raw ? JSON.parse(raw) : { x: null, y: null };
|
||||
} catch {
|
||||
return { x: null, y: null };
|
||||
}
|
||||
});
|
||||
|
||||
const stateRef = useRef({
|
||||
dragging: false,
|
||||
pointerId: null,
|
||||
startX: 0,
|
||||
startY: 0,
|
||||
originX: 0,
|
||||
originY: 0,
|
||||
});
|
||||
|
||||
function getBounds(el) {
|
||||
const rect = el.getBoundingClientRect();
|
||||
const maxX = window.innerWidth - rect.width - margin;
|
||||
const maxY = window.innerHeight - rect.height - margin;
|
||||
return { maxX, maxY };
|
||||
}
|
||||
|
||||
function persist(next) {
|
||||
try {
|
||||
localStorage.setItem(storageKey, JSON.stringify(next));
|
||||
} catch {}
|
||||
}
|
||||
|
||||
function onPointerDown(e) {
|
||||
if (e.pointerType === "mouse" && e.button !== 0) return;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
|
||||
el.setPointerCapture?.(e.pointerId);
|
||||
|
||||
const st = stateRef.current;
|
||||
st.dragging = true;
|
||||
st.pointerId = e.pointerId;
|
||||
st.startX = e.clientX;
|
||||
st.startY = e.clientY;
|
||||
|
||||
const rect = el.getBoundingClientRect();
|
||||
st.originX = pos.x == null ? rect.left : pos.x;
|
||||
st.originY = pos.y == null ? rect.top : pos.y;
|
||||
}
|
||||
|
||||
function onPointerMove(e) {
|
||||
const st = stateRef.current;
|
||||
if (!st.dragging || st.pointerId !== e.pointerId) return;
|
||||
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
|
||||
const dx = e.clientX - st.startX;
|
||||
const dy = e.clientY - st.startY;
|
||||
|
||||
const { maxX, maxY } = getBounds(el);
|
||||
|
||||
const next = {
|
||||
x: clamp(st.originX + dx, margin, maxX),
|
||||
y: clamp(st.originY + dy, margin, maxY),
|
||||
};
|
||||
|
||||
setPos(next);
|
||||
}
|
||||
|
||||
function onPointerUp(e) {
|
||||
const st = stateRef.current;
|
||||
if (!st.dragging || st.pointerId !== e.pointerId) return;
|
||||
|
||||
st.dragging = false;
|
||||
st.pointerId = null;
|
||||
|
||||
// zapis po puszczeniu
|
||||
persist(pos);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
const next = { x: null, y: null };
|
||||
setPos(next);
|
||||
try {
|
||||
localStorage.removeItem(storageKey);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// docinanie na resize
|
||||
useEffect(() => {
|
||||
function onResize() {
|
||||
const el = ref.current;
|
||||
if (!el || pos.x == null || pos.y == null) return;
|
||||
|
||||
const { maxX, maxY } = getBounds(el);
|
||||
const next = {
|
||||
x: clamp(pos.x, margin, maxX),
|
||||
y: clamp(pos.y, margin, maxY),
|
||||
};
|
||||
|
||||
if (next.x !== pos.x || next.y !== pos.y) {
|
||||
setPos(next);
|
||||
persist(next);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("resize", onResize);
|
||||
return () => window.removeEventListener("resize", onResize);
|
||||
}, [pos.x, pos.y]);
|
||||
|
||||
const style =
|
||||
pos.x == null || pos.y == null
|
||||
? undefined
|
||||
: `left:${pos.x}px; top:${pos.y}px; right:auto; bottom:auto;`;
|
||||
|
||||
const handlers = {
|
||||
onPointerDown,
|
||||
onPointerMove,
|
||||
onPointerUp,
|
||||
onPointerCancel: onPointerUp,
|
||||
};
|
||||
|
||||
return { ref, style, handlers, pos, setPos, reset };
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useEffect, useMemo, useState } from "preact/hooks";
|
||||
import useDraggableFloating from "../hooks/useDraggableFloating.js";
|
||||
|
||||
import "../../styles/modal.css";
|
||||
import "../../styles/addons.css";
|
||||
|
||||
@@ -181,6 +183,7 @@ export default function JamboxAddonsModal({
|
||||
const addonsList = useMemo(() => normalizeAddons(addons), [addons]);
|
||||
|
||||
const decodersList = useMemo(() => normalizeDecoders(decoders), [decoders]);
|
||||
const floating = useDraggableFloating("fuz_floating_total_pos_tv_v1");
|
||||
|
||||
const tvAddonsVisible = useMemo(() => {
|
||||
if (!pkg) return [];
|
||||
@@ -415,7 +418,7 @@ export default function JamboxAddonsModal({
|
||||
// ---------
|
||||
const LS_KEY = "fuz_offer_config_v1";
|
||||
|
||||
function buildOfferPayload() {
|
||||
function buildOfferPayload() {
|
||||
const phone = selectedPhoneId
|
||||
? phonePlans.find((p) => String(p.id) === String(selectedPhoneId))
|
||||
: null;
|
||||
@@ -470,21 +473,21 @@ function buildOfferPayload() {
|
||||
currencyLabel: cenaOpis,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function saveOfferToLocalStorage() {
|
||||
function saveOfferToLocalStorage() {
|
||||
try {
|
||||
const payload = buildOfferPayload();
|
||||
localStorage.setItem(LS_KEY, JSON.stringify(payload));
|
||||
} catch {}
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
//-- dopisane
|
||||
function moneyWithLabel(v) {
|
||||
//-- dopisane
|
||||
function moneyWithLabel(v) {
|
||||
return `${money(v)} ${cenaOpis}`;
|
||||
}
|
||||
}
|
||||
|
||||
function buildOfferMessage(payload) {
|
||||
function buildOfferMessage(payload) {
|
||||
const lines = [];
|
||||
|
||||
// nagłówek
|
||||
@@ -530,15 +533,15 @@ function buildOfferMessage(payload) {
|
||||
}
|
||||
|
||||
return lines.join("\n");
|
||||
}
|
||||
}
|
||||
|
||||
function saveOfferToLocalStorage() {
|
||||
function saveOfferToLocalStorage() {
|
||||
try {
|
||||
const payload = buildOfferPayload();
|
||||
payload.message = buildOfferMessage(payload); // ✅ gotowy tekst
|
||||
localStorage.setItem(LS_KEY, JSON.stringify(payload));
|
||||
} catch {}
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
|
||||
// ---------
|
||||
@@ -597,9 +600,9 @@ function saveOfferToLocalStorage() {
|
||||
onToggle={() => toggleSection("decoder")}
|
||||
>
|
||||
|
||||
{decodersList.length === 0 ? (
|
||||
{decodersList.length === 0 ? (
|
||||
<p>Brak dostępnych dekoderów.</p>
|
||||
) : (
|
||||
) : (
|
||||
<div class="f-radio-list">
|
||||
{decodersList.map((d) => {
|
||||
const isSelected = String(selectedDecoderId) === String(d.id);
|
||||
@@ -627,7 +630,7 @@ function saveOfferToLocalStorage() {
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
|
||||
|
||||
@@ -668,7 +671,7 @@ function saveOfferToLocalStorage() {
|
||||
>
|
||||
{phonePlans.length === 0 ? (
|
||||
<p>Brak dostępnych pakietów telefonicznych.</p>
|
||||
) : (
|
||||
) : (
|
||||
<div class="f-radio-list">
|
||||
{/* brak telefonu */}
|
||||
<label class={`f-radio-item ${selectedPhoneId === null ? "is-selected" : ""}`}>
|
||||
@@ -734,9 +737,9 @@ function saveOfferToLocalStorage() {
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)}
|
||||
)}
|
||||
|
||||
</SectionAccordion>
|
||||
</div>
|
||||
@@ -806,9 +809,9 @@ function saveOfferToLocalStorage() {
|
||||
href="/kontakt"
|
||||
class="btn btn-primary w-full mt-4"
|
||||
onClick={() => saveOfferToLocalStorage()}
|
||||
>
|
||||
>
|
||||
Wyślij zapytanie z tym wyborem
|
||||
</a>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -824,7 +827,13 @@ function saveOfferToLocalStorage() {
|
||||
</span>
|
||||
</div>
|
||||
</div> */}
|
||||
<div class="f-floating-total" onClick={(e) => e.stopPropagation()}>
|
||||
<div
|
||||
ref={floating.ref}
|
||||
class="f-floating-total"
|
||||
style={floating.style}
|
||||
{...floating.handlers}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div class="f-floating-total-circle" role="status" aria-label="Cena miesięczna">
|
||||
<span class="f-floating-total-unit">
|
||||
Razem
|
||||
@@ -836,7 +845,7 @@ function saveOfferToLocalStorage() {
|
||||
{cenaOpis}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from "preact/hooks";
|
||||
import "../../styles/addons.css";
|
||||
import "../../styles/cards.css";
|
||||
|
||||
import OffersSwitches from "../Switches.jsx";
|
||||
import JamboxChannelsModal from "./JamboxChannelsModal.jsx";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo, useState } from "preact/hooks";
|
||||
import "../../styles/modal.css";
|
||||
import "../../styles/addons.css";
|
||||
import "../../styles/channels-search.css";
|
||||
import "../../styles/jambox-modal-channel.css";
|
||||
import "../../styles/jambox-search.css";
|
||||
|
||||
export default function JamboxChannelsModal({ isOpen, onClose, pkg }) {
|
||||
const [channels, setChannels] = useState([]);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
|
||||
import "../../styles/channels-search.css";
|
||||
import "../../styles/jambox-search.css";
|
||||
|
||||
export default function JamboxChannelsSearch() {
|
||||
const [q, setQ] = useState("");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useMemo, useState } from "preact/hooks";
|
||||
import { marked } from "marked";
|
||||
import "../../styles/channels-search.css";
|
||||
import "../../styles/jambox-search.css";
|
||||
|
||||
function norm(s) {
|
||||
return String(s || "")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Markdown from "../../islands/Markdown.jsx";
|
||||
import "../../styles/addons.css";
|
||||
import "../../styles/cards.css";
|
||||
|
||||
/**
|
||||
* @typedef {{ klucz: string, label: string, value: (string|number) }} PhoneParam
|
||||
|
||||
@@ -1,310 +1,463 @@
|
||||
.f-offers {
|
||||
@apply my-6;
|
||||
.f-section-acc .f-accordion-header {
|
||||
@apply flex items-center justify-between gap-3;
|
||||
}
|
||||
|
||||
.f-offers-grid {
|
||||
@apply flex flex-wrap justify-center gap-8;
|
||||
.f-accordion-header-right {
|
||||
@apply flex items-center gap-3;
|
||||
}
|
||||
|
||||
.f-card {
|
||||
@apply bg-[--f-bg] text-[--f-text] border border-[--f-offers-border] rounded-2xl shadow-md p-6 relative flex flex-col gap-4;
|
||||
/* przewijanie uwzględnia sticky navbar */
|
||||
scroll-margin-top: calc(var(--f-navbar-height, 84px) + 16px);
|
||||
flex: 1 1 100%;
|
||||
max-width: 26rem;
|
||||
transition: transform 220ms ease, box-shadow 220ms ease;
|
||||
}
|
||||
|
||||
.f-card:hover {
|
||||
@apply shadow-lg;
|
||||
transform: translateY(-3px);
|
||||
.f-acc-chevron {
|
||||
@apply opacity-60 text-sm;
|
||||
}
|
||||
|
||||
|
||||
.f-card-popular {
|
||||
border: 2px solid var(--f-offers-popular);
|
||||
background: var(--f-offers-popular-bg);
|
||||
.f-floating-total {
|
||||
@apply fixed bottom-5 right-5 z-[10000];
|
||||
@apply pointer-events-auto;
|
||||
@apply select-none;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.f-card-badge {
|
||||
@apply absolute top-3 right-3 bg-[--btn-background] text-[--btn-text] text-sm font-semibold px-3 py-1 rounded-full;
|
||||
/* kółko */
|
||||
.f-floating-total-circle {
|
||||
@apply w-24 h-24 md:w-32 md:h-32 rounded-full;
|
||||
@apply flex flex-col items-center justify-center text-center;
|
||||
@apply shadow-xl;
|
||||
@apply bg-[--f-addons-background];
|
||||
@apply backdrop-blur-md;
|
||||
}
|
||||
|
||||
/* HEADER */
|
||||
.f-card-header {
|
||||
@apply flex flex-col items-start gap-1;
|
||||
/* kwota */
|
||||
.f-floating-total-amount {
|
||||
@apply text-lg md:text-xl font-bold leading-none text-[--f-addons-text];
|
||||
}
|
||||
|
||||
.f-card-name {
|
||||
@apply text-3xl font-semibold;
|
||||
/* jednostka */
|
||||
.f-floating-total-unit {
|
||||
@apply my-1 text-xs md:text-sm opacity-70 text-[--f-addons-text];
|
||||
}
|
||||
|
||||
.f-card-price {
|
||||
@apply text-3xl font-extrabold text-[--f-offers-price];
|
||||
|
||||
@keyframes fuz-bounce {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-6px); }
|
||||
}
|
||||
|
||||
/* FEATURES */
|
||||
.f-card-features {
|
||||
@apply list-none p-0 m-0;
|
||||
.f-floating-total:hover .f-floating-total-circle {
|
||||
animation: fuz-bounce 420ms ease-in-out;
|
||||
}
|
||||
|
||||
.f-card-row {
|
||||
@apply grid grid-cols-[2fr_1fr] gap-2 py-2 border-b border-[--f-offers-border] items-center;
|
||||
.f-floating-total:active .f-floating-total-circle {
|
||||
transform: translateY(-4px) scale(1.02);
|
||||
}
|
||||
|
||||
.f-card-row:last-child {
|
||||
/* 3D */
|
||||
.f-floating-total-circle {
|
||||
@apply relative overflow-hidden;
|
||||
@apply shadow-xl;
|
||||
@apply bg-[--f-addons-background];
|
||||
@apply backdrop-blur-md;
|
||||
|
||||
/* 3D feel */
|
||||
box-shadow:
|
||||
0 18px 35px hsla(221 47% 11% / 0.28),
|
||||
0 6px 14px hsla(221 47% 11% / 0.18),
|
||||
inset 0 1px 0 hsla(0 0% 100% / 0.22),
|
||||
inset 0 -10px 18px hsla(221 47% 11% / 0.25);
|
||||
|
||||
/* subtelna “kopuła” */
|
||||
background-image:
|
||||
radial-gradient(120% 120% at 30% 20%, hsla(0 0% 100% / 0.22) 0%, transparent 55%),
|
||||
radial-gradient(140% 140% at 70% 80%, hsla(221 47% 11% / 0.22) 0%, transparent 60%);
|
||||
}
|
||||
|
||||
/* połysk */
|
||||
.f-floating-total-circle::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -30% -30% auto -30%;
|
||||
height: 70%;
|
||||
border-radius: 9999px;
|
||||
background: radial-gradient(
|
||||
closest-side,
|
||||
hsla(0 0% 100% / 0.28),
|
||||
transparent 70%
|
||||
);
|
||||
transform: rotate(-12deg);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* “rim”/krawędź */
|
||||
.f-floating-total-circle::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 9999px;
|
||||
border: 1px solid hsla(0 0% 100% / 0.16);
|
||||
box-shadow: inset 0 0 0 1px hsla(221 47% 11% / 0.18);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* lekka reakcja 3D na hover */
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.f-floating-total:hover .f-floating-total-circle {
|
||||
transform: translateY(-2px) scale(1.02);
|
||||
box-shadow:
|
||||
0 22px 44px hsla(221 47% 11% / 0.32),
|
||||
0 8px 18px hsla(221 47% 11% / 0.20),
|
||||
inset 0 1px 0 hsla(0 0% 100% / 0.24),
|
||||
inset 0 -12px 20px hsla(221 47% 11% / 0.28);
|
||||
transition: transform 180ms ease, box-shadow 180ms ease;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ----------- Uporządkować ------ */
|
||||
/* ===========================
|
||||
TELEFON — AKORDEON
|
||||
=========================== */
|
||||
|
||||
.f-modal-phone-list.f-accordion {
|
||||
@apply flex flex-col gap-2;
|
||||
}
|
||||
|
||||
.f-accordion-item {
|
||||
@apply rounded-xl border overflow-hidden bg-[--f-background];
|
||||
border-color: rgba(148, 163, 184, 0.6);
|
||||
}
|
||||
|
||||
.f-accordion-header {
|
||||
@apply w-full flex items-center justify-between gap-4 px-4 py-2 cursor-pointer;
|
||||
background: rgba(148, 163, 184, 0.06);
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.f-accordion-header-left {
|
||||
@apply flex items-center gap-1;
|
||||
}
|
||||
|
||||
.f-modal-phone-name {
|
||||
@apply font-medium ml-2;
|
||||
}
|
||||
|
||||
.f-modal-phone-price {
|
||||
@apply font-semibold whitespace-nowrap;
|
||||
}
|
||||
|
||||
.f-accordion-body {
|
||||
@apply px-4 pt-2 pb-3;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.4);
|
||||
}
|
||||
|
||||
/* wyróżnienie otwartego pakietu */
|
||||
.f-accordion-item.is-open .f-accordion-header {
|
||||
background: color-mix(in srgb, var(--fuz-accent, #2563eb) 8%, transparent);
|
||||
}
|
||||
|
||||
/* ===========================
|
||||
DODATKI — KOLUMNOWA LISTA (GRID)
|
||||
checkbox: checkbox | main | price
|
||||
quantity: slot | main | qty | price
|
||||
=========================== */
|
||||
|
||||
.f-addon-list {
|
||||
@apply flex flex-col gap-2;
|
||||
}
|
||||
|
||||
/* BAZA: checkbox | main | price */
|
||||
.f-addon-item {
|
||||
@apply grid items-start gap-3 px-3 py-2;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.4);
|
||||
/* rounded-xl border cursor-pointer; */
|
||||
grid-template-columns: auto 1fr auto;
|
||||
/* border-color: rgba(148, 163, 184, 0.5); */
|
||||
background: var(--f-background);
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
.f-addon-item * {
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
.f-addon-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.f-card-label {
|
||||
@apply text-base font-medium opacity-80;
|
||||
.f-addon-item:hover {
|
||||
/* border-color: color-mix(
|
||||
in srgb,
|
||||
var(--fuz-accent, #2563eb) 70%,
|
||||
rgba(148, 163, 184, 0.5) 30%
|
||||
); */
|
||||
}
|
||||
|
||||
.f-card-value {
|
||||
@apply text-base font-semibold text-right;
|
||||
.f-addon-item input[type="checkbox"] {
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
.f-card-value.yes {
|
||||
@apply text-green-600;
|
||||
/* kolumna 1 */
|
||||
.f-addon-checkbox {
|
||||
@apply flex items-center justify-center;
|
||||
align-items: center;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.f-card-value.no {
|
||||
@apply text-red-600 opacity-60;
|
||||
}
|
||||
|
||||
/* INTELIGENTNY UKŁAD – OD MD↑ */
|
||||
@media (min-width: 768px) {
|
||||
.f-card {
|
||||
flex: 1 1 300px;
|
||||
max-width: 360px;
|
||||
}
|
||||
|
||||
/* 4 karty → 2 + 2 */
|
||||
.f-count-4 .f-card {
|
||||
flex: 0 1 calc(50% - 2rem);
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
/* 5 kart → 3 + 2 */
|
||||
.f-count-5 .f-card {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
}
|
||||
|
||||
.f-count-5 .f-card:nth-child(n + 4) {
|
||||
flex: 0 1 calc(50% - 2rem);
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
/* 7 kart → 3 + 3 + 1 (środek) */
|
||||
.f-count-7 .f-card {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
}
|
||||
|
||||
.f-count-7 .f-card:last-child {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* 8 kart → 3 + 3 + 2 */
|
||||
.f-count-8 .f-card {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
}
|
||||
|
||||
.f-count-8 .f-card:nth-child(n + 7) {
|
||||
flex: 0 1 calc(50% - 2rem);
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
/* 10 kart → 3 + 3 + 3 + 1 */
|
||||
.f-count-10 .f-card:last-child {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* =========================================
|
||||
TARGET — PODŚWIETLENIE PAKIETU PO KLIKNIĘCIU
|
||||
========================================== */
|
||||
|
||||
.f-card.is-target {
|
||||
outline: none;
|
||||
box-shadow:
|
||||
0 0 0 3px rgba(59, 130, 246, 0.45),
|
||||
0 10px 25px rgba(15, 23, 42, 0.18);
|
||||
transform: translateY(-6px) scale(1.01);
|
||||
position: relative;
|
||||
background-color: var(--f-navbar-background);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.f-card.is-target:hover {
|
||||
transform: translateY(-6px) scale(1.01);
|
||||
}
|
||||
|
||||
/* JAMBOX — GRID KANAŁÓW (MODAL) */
|
||||
|
||||
.jmb-channels-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 0.9rem;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.jmb-channel-card {
|
||||
position: relative;
|
||||
perspective: 1000px;
|
||||
|
||||
background: var(--f-bg);
|
||||
color: var(--f-text);
|
||||
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.15);
|
||||
|
||||
min-height: 170px;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
touch-action: manipulation;
|
||||
.f-addon-checkbox input[type="checkbox"] {
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
transform: scale(1.05);
|
||||
accent-color: var(--fuz-accent, #2563eb);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.jmb-channel-inner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform-style: preserve-3d;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
transition: transform 0.6s ease;
|
||||
/* kolumna 2 */
|
||||
.f-addon-main {
|
||||
@apply flex flex-col gap-0.5;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* DESKTOP: flip na hover */
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.jmb-channel-card:hover .jmb-channel-inner {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
.f-addon-name {
|
||||
@apply font-medium;
|
||||
}
|
||||
|
||||
/* MOBILE/TAP: flip po klasie */
|
||||
.jmb-channel-card.is-flipped .jmb-channel-inner {
|
||||
transform: rotateY(180deg);
|
||||
.f-addon-desc {
|
||||
@apply text-sm opacity-85;
|
||||
}
|
||||
|
||||
.jmb-channel-face {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
|
||||
padding: 0.75rem 0.5rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
text-align: center;
|
||||
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
/* kolumna 3 (cena) */
|
||||
.f-addon-price {
|
||||
@apply font-semibold whitespace-nowrap;
|
||||
justify-self: end;
|
||||
text-align: right;
|
||||
min-width: 140px;
|
||||
/* stała kolumna cen */
|
||||
}
|
||||
|
||||
.jmb-channel-front {
|
||||
transform: rotateY(0deg);
|
||||
}
|
||||
|
||||
.jmb-channel-back {
|
||||
transform: rotateY(180deg);
|
||||
|
||||
text-align: left;
|
||||
justify-content: flex-start;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.jmb-channel-logo {
|
||||
max-width: 90px;
|
||||
max-height: 60px;
|
||||
margin: 0 auto 0.5rem auto;
|
||||
display: block;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.jmb-channel-name {
|
||||
font-size: 0.85rem;
|
||||
/* suma pod ceną (quantity) */
|
||||
.f-addon-price-total {
|
||||
margin-top: 0.15rem;
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.15rem;
|
||||
opacity: 0.85;
|
||||
white-space: nowrap;
|
||||
color: var(--fuz-accent, #2563eb);
|
||||
}
|
||||
|
||||
.jmb-channel-number {
|
||||
font-size: 0.75rem;
|
||||
color: rgba(148, 163, 184, 0.95);
|
||||
/* WARIANT: quantity -> slot | main | qty | price */
|
||||
.f-addon-item--qty {
|
||||
grid-template-columns: auto 1fr auto auto;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.jmb-channel-back-title {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 700;
|
||||
/* “pusty” slot w kolumnie 1 (żeby wyrównać do checkboxa) */
|
||||
.f-addon-item--qty .f-addon-checkbox {
|
||||
visibility: hidden;
|
||||
/* zajmuje miejsce, ale nie widać */
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.jmb-channel-desc {
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.35;
|
||||
opacity: 0.92;
|
||||
overflow: auto;
|
||||
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(148, 163, 184, 0.55) transparent;
|
||||
/* kolumna qty (3) – bliżej prawej */
|
||||
.f-addon-item--qty .f-addon-qty {
|
||||
justify-self: end;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.05rem;
|
||||
}
|
||||
|
||||
.jmb-channel-desc::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
/* wartość qty */
|
||||
.f-addon-qty-value {
|
||||
min-width: 2ch;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.jmb-channel-desc::-webkit-scrollbar-thumb {
|
||||
background: rgba(148, 163, 184, 0.45);
|
||||
border-radius: 9999px;
|
||||
border: 3px solid transparent;
|
||||
background-clip: content-box;
|
||||
/* mobile: w razie ciasnoty przenosimy qty pod main, cena zostaje po prawej */
|
||||
@media (max-width: 640px) {
|
||||
.f-addon-item--qty {
|
||||
grid-template-columns: auto 1fr auto;
|
||||
grid-template-areas:
|
||||
"slot main price"
|
||||
"slot qty price";
|
||||
}
|
||||
|
||||
.jmb-channel-desc::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
.f-addon-item--qty .f-addon-checkbox {
|
||||
grid-area: slot;
|
||||
}
|
||||
|
||||
.f-addon-item--qty .f-addon-main {
|
||||
grid-area: main;
|
||||
}
|
||||
|
||||
.f-addon-item--qty .f-addon-qty {
|
||||
grid-area: qty;
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.f-addon-item--qty .f-addon-price {
|
||||
grid-area: price;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ===========================
|
||||
PODSUMOWANIE MIESIĘCZNE
|
||||
=========================== */
|
||||
|
||||
/* --------------------------------- */
|
||||
.f-section-acc .f-accordion-header {
|
||||
@apply flex items-center justify-between gap-3;
|
||||
}
|
||||
.f-summary {
|
||||
@apply pt-2;
|
||||
}
|
||||
|
||||
.f-accordion-header-right {
|
||||
.f-summary-list {
|
||||
@apply flex flex-col gap-1 mt-2 p-4 rounded-xl;
|
||||
background: rgba(148, 163, 184, 0.07);
|
||||
}
|
||||
|
||||
.f-summary-row,
|
||||
.f-summary-total {
|
||||
@apply flex items-center justify-between;
|
||||
}
|
||||
|
||||
.f-summary-row span:last-child {
|
||||
@apply font-medium whitespace-nowrap;
|
||||
}
|
||||
|
||||
.f-summary-total {
|
||||
@apply mt-1 pt-2;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.4);
|
||||
}
|
||||
|
||||
.f-summary-total span:last-child {
|
||||
@apply font-bold;
|
||||
font-size: 1.25rem;
|
||||
color: var(--fuz-accent, #2563eb);
|
||||
}
|
||||
|
||||
.f-modal-section {
|
||||
@apply mb-6;
|
||||
}
|
||||
|
||||
.f-modal-section h3 {
|
||||
@apply text-xl md:text-2xl font-semibold mb-3;
|
||||
}
|
||||
|
||||
/* opcja "bez telefonu" */
|
||||
.f-accordion-item--no-phone .f-accordion-header {
|
||||
background: rgba(148, 163, 184, 0.03);
|
||||
}
|
||||
|
||||
.f-accordion-header-left input[type="radio"] {
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
transform: scale(1.05);
|
||||
accent-color: var(--fuz-accent, #2563eb);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.f-addon-checkbox input[type="checkbox"] {
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
transform: scale(1.05);
|
||||
accent-color: var(--fuz-accent, #2563eb);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.f-accordion-header-left,
|
||||
.f-addon-checkbox {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
/* ===========================
|
||||
FLOATING TOTAL (dymek jak czat)
|
||||
=========================== */
|
||||
|
||||
.f-floating-total {
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
bottom: 1rem;
|
||||
z-index: 10000;
|
||||
/* wyżej niż overlay (9999) */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.f-floating-total-inner {
|
||||
@apply flex items-center gap-3;
|
||||
}
|
||||
@apply px-4 py-3 rounded-2xl shadow-xl border;
|
||||
border-color: rgba(148, 163, 184, 0.5);
|
||||
background: color-mix(in srgb, var(--f-background) 92%, transparent);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.f-acc-chevron {
|
||||
@apply opacity-60 text-sm;
|
||||
}
|
||||
.f-floating-total-label {
|
||||
@apply text-sm opacity-80;
|
||||
}
|
||||
|
||||
.f-floating-total {
|
||||
@apply fixed bottom-5 right-5 z-[10000];
|
||||
@apply pointer-events-auto;
|
||||
}
|
||||
.f-floating-total-value {
|
||||
@apply font-bold whitespace-nowrap;
|
||||
font-size: 1.1rem;
|
||||
color: var(--fuz-accent, #2563eb);
|
||||
}
|
||||
|
||||
/* kółko */
|
||||
.f-floating-total-circle {
|
||||
@apply w-24 h-24 md:w-32 md:h-32 rounded-full;
|
||||
@apply flex flex-col items-center justify-center text-center;
|
||||
@apply shadow-xl ;
|
||||
@apply bg-[--f-addons-background] ;
|
||||
@apply backdrop-blur-md;
|
||||
}
|
||||
/* na bardzo małych ekranach lekko mniejszy dymek */
|
||||
@media (max-width: 420px) {
|
||||
.f-floating-total-inner {
|
||||
@apply px-3 py-2;
|
||||
}
|
||||
|
||||
/* kwota */
|
||||
.f-floating-total-amount {
|
||||
@apply text-lg md:text-xl font-bold leading-none text-[--f-addons-text];
|
||||
}
|
||||
.f-floating-total-value {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* jednostka */
|
||||
.f-floating-total-unit {
|
||||
@apply my-1 text-xs md:text-sm opacity-70 text-[--f-addons-text];
|
||||
}
|
||||
.f-addon-price-total {
|
||||
margin-top: 0.15rem;
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
opacity: 0.85;
|
||||
white-space: nowrap;
|
||||
color: var(--fuz-accent, #2563eb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* -------------------------- */
|
||||
.f-radio-item {
|
||||
@apply grid items-start gap-3 px-3 py-2 cursor-pointer;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.4);
|
||||
background: var(--f-background);
|
||||
}
|
||||
|
||||
.f-radio-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.f-radio-check input {
|
||||
@apply mt-1;
|
||||
}
|
||||
|
||||
.f-radio-name {
|
||||
@apply font-medium;
|
||||
}
|
||||
|
||||
.f-radio-price {
|
||||
@apply whitespace-nowrap font-semibold;
|
||||
}
|
||||
|
||||
.f-radio-item.is-selected {
|
||||
/* delikatne wyróżnienie wybranego */
|
||||
/* @apply rounded-xl; */
|
||||
/* background: rgba(148, 163, 184, 0.12); */
|
||||
}
|
||||
|
||||
.f-radio-details {
|
||||
@apply pl-10 pr-3 pb-3 -mt-1 text-sm;
|
||||
/* pl-10 = przesunięcie w prawo (radio + gap) */
|
||||
}
|
||||
128
src/styles/cards.css
Normal file
128
src/styles/cards.css
Normal file
@@ -0,0 +1,128 @@
|
||||
.f-offers {
|
||||
@apply my-6;
|
||||
}
|
||||
|
||||
.f-offers-grid {
|
||||
@apply flex flex-wrap justify-center gap-8;
|
||||
}
|
||||
|
||||
.f-card {
|
||||
@apply bg-[--f-bg] text-[--f-text] border border-[--f-offers-border] rounded-2xl shadow-md p-6 relative flex flex-col gap-4;
|
||||
scroll-margin-top: calc(var(--f-navbar-height, 84px) + 16px);
|
||||
flex: 1 1 100%;
|
||||
max-width: 26rem;
|
||||
transition: transform 220ms ease, box-shadow 220ms ease;
|
||||
}
|
||||
|
||||
.f-card:hover {
|
||||
@apply shadow-lg;
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.f-card-popular {
|
||||
border: 2px solid var(--f-offers-popular);
|
||||
background: var(--f-offers-popular-bg);
|
||||
}
|
||||
|
||||
.f-card-badge {
|
||||
@apply absolute top-3 right-3 bg-[--btn-background] text-[--btn-text] text-sm font-semibold px-3 py-1 rounded-full;
|
||||
}
|
||||
|
||||
.f-card-header {
|
||||
@apply flex flex-col items-start gap-1;
|
||||
}
|
||||
|
||||
.f-card-name {
|
||||
@apply text-3xl font-semibold;
|
||||
}
|
||||
|
||||
.f-card-price {
|
||||
@apply text-3xl font-extrabold text-[--f-offers-price];
|
||||
}
|
||||
|
||||
.f-card-features {
|
||||
@apply list-none p-0 m-0;
|
||||
}
|
||||
|
||||
.f-card-row {
|
||||
@apply grid grid-cols-[2fr_1fr] gap-2 py-2 border-b border-[--f-offers-border] items-center;
|
||||
}
|
||||
|
||||
.f-card-row:last-child {
|
||||
@apply border-b-0;
|
||||
}
|
||||
|
||||
.f-card-label {
|
||||
@apply text-base font-medium opacity-80;
|
||||
}
|
||||
|
||||
.f-card-value {
|
||||
@apply text-base font-semibold text-right;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.f-card {
|
||||
flex: 1 1 300px;
|
||||
max-width: 360px;
|
||||
}
|
||||
|
||||
/* 4 karty → 2 + 2 */
|
||||
.f-count-4 .f-card {
|
||||
flex: 0 1 calc(50% - 2rem);
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
/* 5 kart → 3 + 2 */
|
||||
.f-count-5 .f-card {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
}
|
||||
|
||||
.f-count-5 .f-card:nth-child(n + 4) {
|
||||
flex: 0 1 calc(50% - 2rem);
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
/* 7 kart → 3 + 3 + 1 (środek) */
|
||||
.f-count-7 .f-card {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
}
|
||||
|
||||
.f-count-7 .f-card:last-child {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
/* 8 kart → 3 + 3 + 2 */
|
||||
.f-count-8 .f-card {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
}
|
||||
|
||||
.f-count-8 .f-card:nth-child(n + 7) {
|
||||
flex: 0 1 calc(50% - 2rem);
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
/* 10 kart → 3 + 3 + 3 + 1 */
|
||||
.f-count-10 .f-card:last-child {
|
||||
flex: 0 1 calc(33% - 2rem);
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.f-card.is-target {
|
||||
outline: none;
|
||||
box-shadow:
|
||||
0 0 0 3px var(--card-ring),
|
||||
0 10px 25px var(--card-shadow-deep);
|
||||
transform: translateY(-6px) scale(1.01);
|
||||
position: relative;
|
||||
background-color: var(--f-navbar-background);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.f-card.is-target:hover {
|
||||
transform: translateY(-6px) scale(1.01);
|
||||
}
|
||||
124
src/styles/jambox-modal-channel.css
Normal file
124
src/styles/jambox-modal-channel.css
Normal file
@@ -0,0 +1,124 @@
|
||||
.jmb-channels-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 0.9rem;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.jmb-channel-card {
|
||||
position: relative;
|
||||
perspective: 1000px;
|
||||
|
||||
background: var(--f-bg);
|
||||
color: var(--f-text);
|
||||
|
||||
border-radius: 0.75rem;
|
||||
border: 1px solid rgba(148, 163, 184, 0.25);
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.15);
|
||||
|
||||
min-height: 170px;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
touch-action: manipulation;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.jmb-channel-inner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform-style: preserve-3d;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
transition: transform 0.6s ease;
|
||||
}
|
||||
|
||||
/* DESKTOP: flip na hover */
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.jmb-channel-card:hover .jmb-channel-inner {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* MOBILE/TAP: flip po klasie */
|
||||
.jmb-channel-card.is-flipped .jmb-channel-inner {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.jmb-channel-face {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
|
||||
padding: 0.75rem 0.5rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
text-align: center;
|
||||
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
}
|
||||
|
||||
.jmb-channel-front {
|
||||
transform: rotateY(0deg);
|
||||
}
|
||||
|
||||
.jmb-channel-back {
|
||||
transform: rotateY(180deg);
|
||||
|
||||
text-align: left;
|
||||
justify-content: flex-start;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.jmb-channel-logo {
|
||||
max-width: 90px;
|
||||
max-height: 60px;
|
||||
margin: 0 auto 0.5rem auto;
|
||||
display: block;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.jmb-channel-name {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
|
||||
.jmb-channel-number {
|
||||
font-size: 0.75rem;
|
||||
color: rgba(148, 163, 184, 0.95);
|
||||
}
|
||||
|
||||
.jmb-channel-back-title {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.jmb-channel-desc {
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.35;
|
||||
opacity: 0.92;
|
||||
overflow: auto;
|
||||
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(148, 163, 184, 0.55) transparent;
|
||||
}
|
||||
|
||||
.jmb-channel-desc::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.jmb-channel-desc::-webkit-scrollbar-thumb {
|
||||
background: rgba(148, 163, 184, 0.45);
|
||||
border-radius: 9999px;
|
||||
border: 3px solid transparent;
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
.jmb-channel-desc::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
/* ===========================
|
||||
MODAL — FULLSCREEN OVERLAY
|
||||
=========================== */
|
||||
|
||||
.f-modal-overlay {
|
||||
@apply fixed inset-0 z-[9999] flex flex-col;
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
@@ -18,13 +14,12 @@
|
||||
@apply opacity-100;
|
||||
}
|
||||
|
||||
/* panel – pełny ekran, ale treść centrowana max-w */
|
||||
.f-modal-panel {
|
||||
@apply w-full h-full overflow-y-auto bg-[--f-background] text-[--f-text];
|
||||
@apply px-6 py-8 md:px-12 md:py-12;
|
||||
}
|
||||
|
||||
/* wersja "kompaktowa" z mniejszym max-width (używana w dodatkach) */
|
||||
|
||||
.f-modal-panel.f-modal-panel--compact {
|
||||
@apply flex justify-center items-start;
|
||||
}
|
||||
@@ -50,330 +45,3 @@
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
/* ===========================
|
||||
TELEFON — AKORDEON
|
||||
=========================== */
|
||||
|
||||
.f-modal-phone-list.f-accordion {
|
||||
@apply flex flex-col gap-2;
|
||||
}
|
||||
|
||||
.f-accordion-item {
|
||||
@apply rounded-xl border overflow-hidden bg-[--f-background];
|
||||
border-color: rgba(148, 163, 184, 0.6);
|
||||
}
|
||||
|
||||
.f-accordion-header {
|
||||
@apply w-full flex items-center justify-between gap-4 px-4 py-2 cursor-pointer;
|
||||
background: rgba(148, 163, 184, 0.06);
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.f-accordion-header-left {
|
||||
@apply flex items-center gap-1;
|
||||
}
|
||||
|
||||
.f-modal-phone-name {
|
||||
@apply font-medium ml-2;
|
||||
}
|
||||
|
||||
.f-modal-phone-price {
|
||||
@apply font-semibold whitespace-nowrap;
|
||||
}
|
||||
|
||||
.f-accordion-body {
|
||||
@apply px-4 pt-2 pb-3;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.4);
|
||||
}
|
||||
|
||||
/* wyróżnienie otwartego pakietu */
|
||||
.f-accordion-item.is-open .f-accordion-header {
|
||||
background: color-mix(in srgb, var(--fuz-accent, #2563eb) 8%, transparent);
|
||||
}
|
||||
|
||||
/* ===========================
|
||||
DODATKI — KOLUMNOWA LISTA (GRID)
|
||||
checkbox: checkbox | main | price
|
||||
quantity: slot | main | qty | price
|
||||
=========================== */
|
||||
|
||||
.f-addon-list {
|
||||
@apply flex flex-col gap-2;
|
||||
}
|
||||
|
||||
/* BAZA: checkbox | main | price */
|
||||
.f-addon-item {
|
||||
@apply grid items-start gap-3 px-3 py-2;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.4);
|
||||
/* rounded-xl border cursor-pointer; */
|
||||
grid-template-columns: auto 1fr auto;
|
||||
/* border-color: rgba(148, 163, 184, 0.5); */
|
||||
background: var(--f-background);
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
.f-addon-item * { @apply cursor-pointer; }
|
||||
|
||||
.f-addon-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.f-addon-item:hover {
|
||||
/* border-color: color-mix(
|
||||
in srgb,
|
||||
var(--fuz-accent, #2563eb) 70%,
|
||||
rgba(148, 163, 184, 0.5) 30%
|
||||
); */
|
||||
}
|
||||
|
||||
.f-addon-item input[type="checkbox"] {
|
||||
@apply cursor-pointer;
|
||||
}
|
||||
|
||||
/* kolumna 1 */
|
||||
.f-addon-checkbox {
|
||||
@apply flex items-center justify-center;
|
||||
align-items: center;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.f-addon-checkbox input[type="checkbox"] {
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
transform: scale(1.05);
|
||||
accent-color: var(--fuz-accent, #2563eb);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* kolumna 2 */
|
||||
.f-addon-main {
|
||||
@apply flex flex-col gap-0.5;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.f-addon-name {
|
||||
@apply font-medium;
|
||||
}
|
||||
|
||||
.f-addon-desc {
|
||||
@apply text-sm opacity-85;
|
||||
}
|
||||
|
||||
/* kolumna 3 (cena) */
|
||||
.f-addon-price {
|
||||
@apply font-semibold whitespace-nowrap;
|
||||
justify-self: end;
|
||||
text-align: right;
|
||||
min-width: 140px; /* stała kolumna cen */
|
||||
}
|
||||
|
||||
/* suma pod ceną (quantity) */
|
||||
.f-addon-price-total {
|
||||
margin-top: 0.15rem;
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
opacity: 0.85;
|
||||
white-space: nowrap;
|
||||
color: var(--fuz-accent, #2563eb);
|
||||
}
|
||||
|
||||
/* WARIANT: quantity -> slot | main | qty | price */
|
||||
.f-addon-item--qty {
|
||||
grid-template-columns: auto 1fr auto auto;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
/* “pusty” slot w kolumnie 1 (żeby wyrównać do checkboxa) */
|
||||
.f-addon-item--qty .f-addon-checkbox {
|
||||
visibility: hidden; /* zajmuje miejsce, ale nie widać */
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* kolumna qty (3) – bliżej prawej */
|
||||
.f-addon-item--qty .f-addon-qty {
|
||||
justify-self: end;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.05rem;
|
||||
}
|
||||
|
||||
/* wartość qty */
|
||||
.f-addon-qty-value {
|
||||
min-width: 2ch;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* mobile: w razie ciasnoty przenosimy qty pod main, cena zostaje po prawej */
|
||||
@media (max-width: 640px) {
|
||||
.f-addon-item--qty {
|
||||
grid-template-columns: auto 1fr auto;
|
||||
grid-template-areas:
|
||||
"slot main price"
|
||||
"slot qty price";
|
||||
}
|
||||
|
||||
.f-addon-item--qty .f-addon-checkbox { grid-area: slot; }
|
||||
.f-addon-item--qty .f-addon-main { grid-area: main; }
|
||||
.f-addon-item--qty .f-addon-qty { grid-area: qty; justify-self: start; }
|
||||
.f-addon-item--qty .f-addon-price { grid-area: price; }
|
||||
}
|
||||
|
||||
|
||||
/* ===========================
|
||||
PODSUMOWANIE MIESIĘCZNE
|
||||
=========================== */
|
||||
|
||||
.f-summary {
|
||||
@apply pt-2;
|
||||
}
|
||||
|
||||
.f-summary-list {
|
||||
@apply flex flex-col gap-1 mt-2 p-4 rounded-xl;
|
||||
background: rgba(148, 163, 184, 0.07);
|
||||
}
|
||||
|
||||
.f-summary-row,
|
||||
.f-summary-total {
|
||||
@apply flex items-center justify-between;
|
||||
}
|
||||
|
||||
.f-summary-row span:last-child {
|
||||
@apply font-medium whitespace-nowrap;
|
||||
}
|
||||
|
||||
.f-summary-total {
|
||||
@apply mt-1 pt-2;
|
||||
border-top: 1px solid rgba(148, 163, 184, 0.4);
|
||||
}
|
||||
|
||||
.f-summary-total span:last-child {
|
||||
@apply font-bold;
|
||||
font-size: 1.25rem;
|
||||
color: var(--fuz-accent, #2563eb);
|
||||
}
|
||||
|
||||
.f-modal-section {
|
||||
@apply mb-6;
|
||||
}
|
||||
|
||||
.f-modal-section h3 {
|
||||
@apply text-xl md:text-2xl font-semibold mb-3;
|
||||
}
|
||||
|
||||
/* opcja "bez telefonu" */
|
||||
.f-accordion-item--no-phone .f-accordion-header {
|
||||
background: rgba(148, 163, 184, 0.03);
|
||||
}
|
||||
|
||||
.f-accordion-header-left input[type="radio"] {
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
transform: scale(1.05);
|
||||
accent-color: var(--fuz-accent, #2563eb);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.f-addon-checkbox input[type="checkbox"] {
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
transform: scale(1.05);
|
||||
accent-color: var(--fuz-accent, #2563eb);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.f-accordion-header-left,
|
||||
.f-addon-checkbox {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
||||
/* ===========================
|
||||
FLOATING TOTAL (dymek jak czat)
|
||||
=========================== */
|
||||
|
||||
.f-floating-total {
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
bottom: 1rem;
|
||||
z-index: 10000; /* wyżej niż overlay (9999) */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.f-floating-total-inner {
|
||||
@apply flex items-center gap-3;
|
||||
@apply px-4 py-3 rounded-2xl shadow-xl border;
|
||||
border-color: rgba(148, 163, 184, 0.5);
|
||||
background: color-mix(in srgb, var(--f-background) 92%, transparent);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.f-floating-total-label {
|
||||
@apply text-sm opacity-80;
|
||||
}
|
||||
|
||||
.f-floating-total-value {
|
||||
@apply font-bold whitespace-nowrap;
|
||||
font-size: 1.1rem;
|
||||
color: var(--fuz-accent, #2563eb);
|
||||
}
|
||||
|
||||
/* na bardzo małych ekranach lekko mniejszy dymek */
|
||||
@media (max-width: 420px) {
|
||||
.f-floating-total-inner {
|
||||
@apply px-3 py-2;
|
||||
}
|
||||
.f-floating-total-value {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.f-addon-price-total {
|
||||
margin-top: 0.15rem;
|
||||
font-size: 0.9em;
|
||||
font-weight: 600;
|
||||
opacity: 0.85;
|
||||
white-space: nowrap;
|
||||
color: var(--fuz-accent, #2563eb);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* -------------------------- */
|
||||
.f-radio-item {
|
||||
@apply grid items-start gap-3 px-3 py-2 cursor-pointer;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
border-bottom: 1px solid rgba(148, 163, 184, 0.4);
|
||||
background: var(--f-background);
|
||||
}
|
||||
|
||||
.f-radio-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.f-radio-check input {
|
||||
@apply mt-1;
|
||||
}
|
||||
|
||||
.f-radio-name {
|
||||
@apply font-medium;
|
||||
}
|
||||
|
||||
.f-radio-price {
|
||||
@apply whitespace-nowrap font-semibold;
|
||||
}
|
||||
|
||||
.f-radio-item.is-selected {
|
||||
/* delikatne wyróżnienie wybranego */
|
||||
/* @apply rounded-xl; */
|
||||
/* background: rgba(148, 163, 184, 0.12); */
|
||||
}
|
||||
|
||||
.f-radio-details {
|
||||
@apply pl-10 pr-3 pb-3 -mt-1 text-sm;
|
||||
/* pl-10 = przesunięcie w prawo (radio + gap) */
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
--surface5-dark: hsla(200, 35%, 25%, 1);
|
||||
--surface6-dark: hsla(205, 51%, 41%, 1);
|
||||
|
||||
|
||||
--card-ring: hsla(217 91% 60% / 0.45);
|
||||
--card-shadow-deep: hsla(221 47% 11% / 0.18);
|
||||
/*
|
||||
|
||||
|
||||
@@ -54,7 +57,7 @@
|
||||
--cookie-accept-dark: hsla(120, 60%, 45%, 1);
|
||||
--f-navbar-height: 84px;
|
||||
|
||||
/* Wyrózznienie ceny */
|
||||
/* Wyróznienie ceny */
|
||||
--f-addons-text: hsla(45, 100%, 92%, 1);
|
||||
--f-addons-background: hsla(165, 80%, 25%, 1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user