// Quick City — Info pages: About, Companies, Tech, Values, Certs, Team, Contact, Projects
const { useState: useI, useMemo: useIm } = React;
const HomeStyles = window.HomeStyles;
/* ─────────────────────────────────────────
Shared: a Legacy-Look hero matching home pages
───────────────────────────────────────── */
function PageHero({ brand, eyebrow, title, sub, image, side = 'left' }) {
// side: which side the SVG-shape sits on. ifm=left, lns=right.
const isIfm = brand === 'ifm';
return (
{image && }
{side === 'left' ?
<>
> :
<>
>
}
);
}
/* small inline-styles ensure info hero a bit shorter than home hero */
function InfoHeroStyles() {
React.useEffect(() => {
if (document.getElementById('info-hero-styles')) return;
const s = document.createElement('style');
s.id = 'info-hero-styles';
s.textContent = `
.hh--info { height: 56vh; min-height: 440px; max-height: 620px; }
.hh--info .hh__title { font-size: clamp(32px, 4.2vw, 56px); }
.hh--info .hh__content { max-width: 540px; }
.page > .hh--info:first-child { height: 56vh; min-height: 440px; max-height: 620px; }
/* Team page bits */
.tm-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 40px; }
.tm-chip { background:#fff; border:1px solid #e8e8e8; padding:10px 18px; font-family:inherit; font-size:11px; font-weight:700; letter-spacing:0.15em; text-transform:uppercase; cursor:pointer; transition: all .2s; color:#444; }
.tm-chip:hover { border-color: var(--accent); color: var(--accent); }
.tm-chip.active { background: var(--accent); color:#fff; border-color: var(--accent); }
.tm-grid { display:grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
@media (max-width: 1100px) { .tm-grid { grid-template-columns: repeat(3,1fr); } }
@media (max-width: 800px) { .tm-grid { grid-template-columns: repeat(2,1fr); } }
.tm-card { background:#fff; padding: 28px 24px; cursor:pointer; transition: transform .25s, box-shadow .25s; border-bottom: 3px solid transparent; position:relative; }
.tm-card:hover { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(0,0,0,.08); border-bottom-color: var(--accent); }
.tm-card__ph { width: 88px; height: 88px; border-radius:50%; background: linear-gradient(135deg, #efefef, #d8d8d8); display:flex; align-items:center; justify-content:center; font-size:24px; font-weight:900; color:#999; letter-spacing:0.05em; margin-bottom:18px; }
.tm-card__name { font-size:16px; font-weight:700; margin-bottom:4px; }
.tm-card__role { font-size:12px; color:#666; line-height:1.5; margin-bottom:8px; }
.tm-card__dept { font-size:10px; font-weight:700; letter-spacing:0.18em; text-transform:uppercase; color: var(--accent); }
/* Org chart */
.tm-org { padding: 40px 0 8px; }
.tm-org__row { display: flex; gap: 24px; justify-content:center; flex-wrap:wrap; }
.tm-org__connector { width: 2px; height: 24px; background: var(--accent); margin: 0 auto; }
.tm-org__crossbar { height: 2px; background: var(--accent); width: min(560px, 80%); margin: 0 auto; }
.tm-org-card { background: #fff; border-top: 4px solid var(--accent); padding: 24px 28px; min-width: 240px; max-width: 280px; cursor:pointer; transition: transform .2s, box-shadow .2s; box-shadow: 0 2px 8px rgba(0,0,0,.05); }
.tm-org-card:hover { transform: translateY(-3px); box-shadow: 0 12px 28px rgba(0,0,0,.1); }
.tm-org-card__ph { width: 60px; height: 60px; border-radius:50%; background: linear-gradient(135deg, #efefef, #d8d8d8); display:flex; align-items:center; justify-content:center; font-size:18px; font-weight:900; color:#999; margin-bottom:14px; }
.tm-org-card__name { font-size:15px; font-weight:700; }
.tm-org-card__role { font-size:12px; color:#666; line-height:1.5; margin-top:2px; }
.tm-org-card__dept { font-size:10px; font-weight:700; letter-spacing:0.18em; text-transform:uppercase; color: var(--accent); margin-top:8px; }
/* Modal */
.tm-modal { position:fixed; inset:0; background: rgba(20,20,20,0.7); display:flex; align-items:center; justify-content:center; z-index:1000; padding:24px; }
.tm-modal__box { background:#fff; max-width:560px; width:100%; padding: 48px 48px 40px; position:relative; border-top: 6px solid var(--accent); }
.tm-modal__close { position:absolute; top:14px; right:18px; background:none; border:none; font-size:28px; cursor:pointer; color:#888; }
.tm-modal__ph { width:100px; height:100px; border-radius:50%; background: linear-gradient(135deg, #efefef, #d8d8d8); display:flex; align-items:center; justify-content:center; font-size:30px; font-weight:900; color:#999; margin-bottom:20px; }
.tm-modal__name { font-size:24px; font-weight:700; margin-bottom:4px; }
.tm-modal__role { font-size:14px; color:#555; }
.tm-modal__dept { font-size:11px; font-weight:700; letter-spacing:0.2em; text-transform:uppercase; color: var(--accent); margin-top:12px; }
.tm-modal__bio { font-size:14.5px; line-height:1.75; color:#444; margin-top:20px; }
/* Contact form */
.ck-grid { display:grid; grid-template-columns: 1fr 1.2fr; gap: 64px; }
@media (max-width: 900px) { .ck-grid { grid-template-columns: 1fr; gap: 32px; } }
.ck-info { display:flex; flex-direction:column; gap: 2px; }
.ck-info__block { background:#fff; padding: 28px 32px; border-left: 4px solid var(--accent); }
.ck-info__label { font-size:10px; font-weight:700; letter-spacing:0.25em; text-transform:uppercase; color: var(--accent); margin-bottom:10px; }
.ck-info__value { font-size:15px; line-height:1.7; color:#222; white-space: pre-line; }
.ck-info__value a { color: inherit; text-decoration:none; border-bottom:1px solid rgba(0,0,0,0.15); }
.ck-info__value a:hover { color: var(--accent); border-color: var(--accent); }
.ck-form { background:#fff; padding: 40px 44px; border-top: 4px solid var(--accent); }
@media (max-width: 600px) { .ck-form { padding: 28px; } }
.ck-form__label { font-size:10px; font-weight:700; letter-spacing:0.25em; text-transform:uppercase; color: var(--accent); margin-bottom:8px; }
.ck-form__title { font-size:24px; font-weight:900; margin-bottom:24px; text-transform:uppercase; letter-spacing:-0.01em; }
.ck-row { display:grid; grid-template-columns: 1fr 1fr; gap:14px; }
@media (max-width: 600px) { .ck-row { grid-template-columns: 1fr; } }
.ck-field { margin-bottom: 14px; }
.ck-field label { display:block; font-size:11px; font-weight:700; letter-spacing:0.12em; text-transform:uppercase; color:#555; margin-bottom:6px; }
.ck-field input, .ck-field select, .ck-field textarea {
width:100%; padding:12px 14px; border:1px solid #ddd; background:#fafafa; font-family:inherit; font-size:14px; color:#222; transition: border-color .2s, background .2s;
}
.ck-field input:focus, .ck-field select:focus, .ck-field textarea:focus {
outline:none; border-color: var(--accent); background:#fff;
}
.ck-field textarea { min-height: 120px; resize: vertical; }
.ck-submit { display:inline-flex; align-items:center; gap:12px; background: var(--accent); color:#fff; border:none; font-family:inherit; font-size:11px; font-weight:700; letter-spacing:0.2em; text-transform:uppercase; padding:14px 28px; cursor:pointer; transition: opacity .2s; }
.ck-submit:hover { opacity:0.85; }
.ck-success { padding: 32px 0; text-align:center; }
.ck-success__check { width:64px; height:64px; border-radius:50%; background: var(--accent); color:#fff; display:flex; align-items:center; justify-content:center; font-size:32px; margin:0 auto 18px; }
/* Cert list (legacy) */
.cert-list { display: grid; gap: 4px; }
.cert-row { background:#fff; padding: 36px 40px; display:grid; grid-template-columns: 220px 1fr auto; gap: 40px; align-items:center; border-left: 4px solid var(--accent); }
@media (max-width: 800px) { .cert-row { grid-template-columns: 1fr; gap:20px; padding: 28px; } }
.cert-row__img { background:#f5f5f5; padding: 20px; text-align:center; border: none; cursor: default; font: inherit; color: inherit; position: relative; width: 100%; }
.cert-row__img--clickable { cursor: zoom-in; transition: background 0.2s, transform 0.2s; }
.cert-row__img--clickable:hover { background: #ececec; transform: scale(1.02); }
.cert-row__img--clickable:hover .cert-row__zoom { opacity: 1; }
.cert-row__img img { max-width:100%; height:auto; display:block; margin:0 auto; }
.cert-row__placeholder { color:#999; font-size:11px; letter-spacing:0.2em; text-transform:uppercase; padding: 30px 0; font-weight:700; }
.cert-row__zoom { position: absolute; top: 10px; right: 10px; width: 32px; height: 32px; border-radius: 50%; background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.2s; pointer-events: none; }
.cert-row__badge { position: absolute; left: 8px; bottom: 8px; width: 34px; height: 34px; object-fit: contain; background: #fff; border-radius: 50%; padding: 3px; box-shadow: 0 1px 5px rgba(0,0,0,0.2); }
/* Cert lightbox */
.cert-lightbox { position: fixed; inset: 0; background: rgba(0,0,0,0.92); z-index: 500; display: flex; align-items: center; justify-content: center; padding: 40px; animation: certLbFadeIn 0.18s ease-out; }
@keyframes certLbFadeIn { from { opacity: 0; } to { opacity: 1; } }
.cert-lightbox__close { position: absolute; top: 24px; right: 28px; width: 44px; height: 44px; border-radius: 50%; background: rgba(255,255,255,0.1); color: #fff; border: none; font-size: 28px; line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.15s; }
.cert-lightbox__close:hover { background: rgba(255,255,255,0.2); }
.cert-lightbox__inner { max-width: min(1200px, 92vw); max-height: 85vh; display: flex; flex-direction: column; align-items: center; gap: 16px; }
.cert-lightbox__inner img { max-width: 100%; max-height: 78vh; height: auto; width: auto; object-fit: contain; background: #fff; padding: 16px; box-shadow: 0 30px 80px rgba(0,0,0,0.5); }
.cert-lightbox__label { font-size: 12px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(255,255,255,0.85); }
.cert-row__code { font-size:11px; font-weight:700; letter-spacing:0.2em; text-transform:uppercase; color: var(--accent); margin-bottom:8px; }
.cert-row__name { font-size:22px; font-weight:700; margin-bottom:14px; line-height:1.2; }
.cert-row__meta { display:grid; grid-template-columns: auto 1fr; gap: 6px 16px; font-size:13.5px; color:#555; line-height:1.6; }
.cert-row__meta dt { font-weight:700; color:#222; }
.cert-row__valid { font-size:11px; font-weight:700; letter-spacing:0.18em; text-transform:uppercase; color:#888; white-space:nowrap; }
`;
document.head.appendChild(s);
}, []);
return null;
}
function PageHead({ brand, crumbs, title, sub, image }) {
const b = window.QC_DATA.brands[brand];
const cls = 'page-head' + (image ? ' page-head--image' : '');
const style = image ? { '--bg-image': `url("${image}")` } : null;
return (
);
}
/* ─────────────────────────────────────────
ABOUT — original legacy markup (page-head + narrative + next-block)
───────────────────────────────────────── */
function AboutStyles() {
React.useEffect(() => {
if (document.getElementById('about-styles')) return;
const s = document.createElement('style');
s.id = 'about-styles';
s.textContent = `
.ab-lead { font-size: 19px; line-height: 1.7; color: #444; max-width: 720px; margin-bottom: 64px; }
.ab-lead strong { color: var(--accent); font-weight: 700; }
.ab-narrative { display: grid; grid-template-columns: 1fr 1fr; gap: 72px 96px; margin-bottom: 88px; }
@media (max-width: 800px) { .ab-narrative { grid-template-columns: 1fr; gap: 48px; } }
.ab-item h3 { font-size: 20px; font-weight: 700; margin-bottom: 14px; color: var(--accent); }
.ab-item h3::before { content:''; display:inline-block; width:24px; height:2px; background:var(--accent); vertical-align:middle; margin-right:12px; }
.ab-item p { font-size: 15px; line-height: 1.8; color: #444; }
.ab-stats-box { background:#f5f5f5; padding:32px; border-left:4px solid var(--accent); }
.ab-stats-box__label { font-size:11px; font-weight:700; letter-spacing:0.22em; text-transform:uppercase; color:var(--accent); margin-bottom:12px; }
.ab-stats-grid { display:grid; grid-template-columns:1fr 1fr; gap:18px 24px; }
.ab-stat__num { font-size:32px; font-weight:700; color:var(--accent); line-height:1; }
.ab-stat__label { font-size:12px; color:#666; margin-top:4px; }
.ab-next { margin-top: 64px; background: var(--accent); color: #fff; padding: 56px 64px; display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: center; }
@media (max-width: 800px) { .ab-next { grid-template-columns: 1fr; gap: 24px; padding: 40px; } }
.ab-next h3 { font-size: 28px; font-weight: 700; line-height: 1.2; }
.ab-next p { font-size: 16px; line-height: 1.7; color: rgba(255,255,255,0.9); margin-bottom: 24px; }
.ab-next .btn { background:#fff; color:var(--accent); border-color:#fff; }
`;
document.head.appendChild(s);
}, []);
return null;
}
function AboutPage({ brand }) {
if (brand === 'lns' && typeof window.LnsAboutPage === 'function') {
return ;
}
if (brand === 'ifm' && typeof window.IfmAboutPage === 'function') {
return ;
}
const { t } = useT();
const d = window.QC_CONTENT.about[brand];
const titleHtml = t(`${brand}.about.title2`, (d.title || '').replace(/ /gi, ' '));
const stripTitle = titleHtml.replace(/ /gi, ' ');
return (
{d.blocks.map((bl, i) => {
const k = `${brand}.about.p${i + 1}`;
return (
);
})}
{brand === 'ifm' ? t('ifm.about.stats.label', 'Quick City in Zahlen') : t('lns.about.stats.label', 'LNS in Zahlen')}
{d.stats.map((s, i) =>
{t(`${brand}.about.stat${i + 1}.label`, s.label)}
)}
{t('companies.together', 'Gemeinsam stark')}
);
}
/* ─────────────────────────────────────────
COMPANIES (left as-is — already passable)
───────────────────────────────────────── */
function CompaniesPage({ brand }) {
const { t } = useT();
const d = window.QC_CONTENT.companies;
return (
{d.cards.map((c) => {
const cb = window.QC_DATA.brands[c.brand];
return (
);
})}
{t('companies.section.label', 'Zusammenspiel')}
{t('companies.together', d.togetherH)}
{t('companies.together.text', d.togetherT)}
);
}
/* ─────────────────────────────────────────
TECH (left as-is)
───────────────────────────────────────── */
function TechPage({ brand }) {
const { t, lang } = useT();
const d = window.QC_CONTENT.tech[brand];
// Technik-Übersetzung: Hersteller bleiben, Kategorien & Bezeichnungen werden übersetzt
const TT = window.QC_TECH_TX || { ui: {}, terms: {} };
const txUI = (de) => (lang === 'de' ? de : (TT.ui[lang] && TT.ui[lang][de]) || de);
const txTerm = (de) => (lang === 'de' ? de : (TT.terms[lang] && TT.terms[lang][de]) || de);
const heroImg = brand === 'ifm' ? 'assets/ifm-fleet-sprinter.jpg' : 'assets/lns-fleet.jpg';
const hasInventory = Array.isArray(d.inventory) && d.inventory.length > 0;
const totalMachines = hasInventory ? d.inventory.reduce((s, c) => s + c.items.reduce((a, it) => a + (typeof it.count === 'number' ? it.count : 1), 0), 0) : 0;
const hasCounts = hasInventory && d.inventory.some(g => g.items.some(it => typeof it.count === 'number'));
// Display override: IFM shows aggregate "350+" since per-item counts aren't tracked
const totalDisplay = brand === 'ifm' ? '350+' : brand === 'lns' ? '850+' : `${totalMachines}${hasCounts ? '+' : ''}`;
return (
{/* Overview cats — only shown when no detailed inventory exists */}
{!hasInventory && (
{d.cats.map((c, i) =>
{String(i + 1).padStart(2, '0')}
{t(`tech.cat${i + 1}`, c.name)}
{t(`${brand}.tech.f${i + 1}.t`, c.t)}
)}
)}
{/* Detailed inventory (IFM only — when data is present) */}
{hasInventory && (
{txUI('Maschinenpark')}
{txUI('Vollständige Übersicht.')}
{totalDisplay} {txUI('Maschinen & Fahrzeuge')}
{d.inventory.length} {txUI('Bereiche')}
100 % {txUI('Eigener Bestand')}
{d.inventory.map((group, gi) => (
{group.icon}
{txTerm(group.cat)}
{group.compact ? (
{group.items.map((it, ii) => (
{txTerm(it.type)}
))}
{group.items[0] && group.items[0].brand ? group.items[0].brand : txUI('Diverse Hersteller')}
) : (
{txUI('Bezeichnung')}
{txUI('Hersteller / Modell')}
{hasCounts &&
{txUI('Anzahl')}
}
{group.items.map((it, ii) => (
{txTerm(it.type)}
{it.brand}
{hasCounts &&
{typeof it.count === 'number' ? {it.count}× : — }
}
))}
)}
))}
{txUI('Auszug aus unserem Bestand · Stand: laufend aktualisiert. Wartung, Reparatur und Pflege erfolgen in der eigenen Werkstatt.')}
)}
);
}
function TechStyles() {
React.useEffect(() => {
if (document.getElementById('tech-inv-styles')) return;
const s = document.createElement('style');
s.id = 'tech-inv-styles';
s.textContent = `
.tech-inv__head { text-align: center; max-width: 760px; margin: 0 auto 56px; }
.tech-inv__head .section__h, .tech-inv__head .section__title, .tech-inv__head .section__sub { margin-left: auto; margin-right: auto; }
.tech-inv__head .section__sub { max-width: 60ch; }
.tech-inv__stats { display: flex; justify-content: center; gap: 56px; margin-top: 32px; flex-wrap: wrap; }
.tech-inv__stat { text-align: center; }
.tech-inv__stat strong { display: block; font-size: 38px; font-weight: 800; color: var(--accent); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; line-height: 1; }
.tech-inv__stat span { display: block; margin-top: 6px; font-size: 11px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: #888; }
.tech-inv__list { display: flex; flex-direction: column; gap: 28px; }
.tech-inv__group { background: #fff; border: 1px solid #ececec; overflow: hidden; }
.tech-inv__group-head { display: flex; align-items: center; gap: 18px; padding: 22px 28px; background: #1a1a1a; color: #fff; }
.tech-inv__group-icon { font-size: 26px; line-height: 1; flex-shrink: 0; width: 44px; height: 44px; border-radius: 50%; background: var(--accent); display: flex; align-items: center; justify-content: center; }
.tech-inv__group-info { display: flex; align-items: baseline; gap: 14px; flex: 1; flex-wrap: wrap; }
.tech-inv__group-title { font-size: 19px; font-weight: 700; letter-spacing: -0.005em; margin: 0; }
.tech-inv__group-count { font-size: 11px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255,255,255,0.55); }
.tech-inv__table { display: flex; flex-direction: column; }
/* Compact chip layout — used for groups with all-same brand (e.g. "Spezialtechnik") */
.tech-inv__chips { padding: 28px; display: flex; flex-wrap: wrap; gap: 10px; align-items: center; position: relative; }
.tech-inv__chip { display: inline-block; padding: 9px 16px; background: #fafafa; border: 1px solid #ececec; border-left: 3px solid var(--accent); font-size: 13.5px; font-weight: 600; color: #1a1a1a; letter-spacing: 0.01em; line-height: 1.3; }
.tech-inv__chips-note { width: 100%; margin-top: 12px; padding-top: 14px; border-top: 1px dashed #e0e0e0; font-size: 11px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: #999; }
.tech-inv__row { display: grid; grid-template-columns: 1.4fr 1fr; gap: 24px; padding: 14px 28px; border-bottom: 1px solid #f0f0f0; font-size: 14.5px; }
.tech-inv__table--with-count .tech-inv__row { grid-template-columns: 1.4fr 1fr 100px; }
.tech-inv__row:last-child { border-bottom: none; }
.tech-inv__row:nth-child(even) { background: #fafafa; }
.tech-inv__row--head { background: #fff !important; padding-top: 16px; padding-bottom: 16px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: #999; border-bottom: 2px solid #1a1a1a; }
.tech-inv__type { color: #333; font-weight: 500; }
.tech-inv__brand { color: #1a1a1a; font-weight: 700; }
.tech-inv__count-cell { text-align: right; }
.tech-inv__count-pill { display: inline-flex; align-items: center; justify-content: center; min-width: 52px; padding: 4px 10px; background: var(--accent); color: #fff; font-size: 12px; font-weight: 800; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; }
.tech-inv__count-pill--ghost { background: #ececec; color: #999; }
@media (max-width: 640px) {
.tech-inv__row,
.tech-inv__table--with-count .tech-inv__row { grid-template-columns: 1fr auto; gap: 4px 12px; padding: 12px 20px; }
.tech-inv__row--head { display: none; }
.tech-inv__type { font-size: 12px; color: #888; letter-spacing: 0.04em; text-transform: uppercase; grid-column: 1 / -1; }
.tech-inv__count-cell { grid-row: 2; grid-column: 2; align-self: center; }
.tech-inv__brand { grid-row: 2; grid-column: 1; }
.tech-inv__group-head { padding: 18px 20px; gap: 14px; }
.tech-inv__group-icon { width: 38px; height: 38px; font-size: 22px; }
.tech-inv__group-title { font-size: 17px; }
}
.tech-inv__note { margin-top: 36px; font-size: 12px; color: #888; text-align: center; font-style: italic; }
`;
document.head.appendChild(s);
}, []);
return null;
}
/* ─────────────────────────────────────────
VALUES (left as-is)
───────────────────────────────────────── */
function ValuesPage({ brand }) {
const { t } = useT();
const d = window.QC_CONTENT.values[brand];
return (
{d.vals.map((v, i) =>
{t(`${brand}.val${i + 1}.h`, v.h)}
{t(`${brand}.val${i + 1}.t`, v.t)}
{v.points && (
{v.points.map((p, j) => {t(`${brand}.val${i + 1}.p${j + 1}`, p)} )}
)}
)}
);
}
function ValuesStyles() {
React.useEffect(() => {
if (document.getElementById('qc-vals-styles')) return;
const s = document.createElement('style');
s.id = 'qc-vals-styles';
s.textContent = `
.qc-vals-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
@media (max-width: 980px) { .qc-vals-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 680px) { .qc-vals-grid { grid-template-columns: 1fr; gap: 16px; } }
.qc-val-card { background: #fff; border: 1px solid #ececec; border-top: 3px solid var(--accent); padding: 32px 30px 28px; transition: transform 0.25s, box-shadow 0.25s; }
.qc-val-card:hover { transform: translateY(-3px); box-shadow: 0 16px 36px rgba(0,0,0,0.06); }
.qc-val-card__h { font-size: 21px; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 14px; color: #1a1a1a; }
.qc-val-card__t { font-size: 14.5px; line-height: 1.7; color: #555; margin: 0 0 18px; }
.qc-val-card__list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 9px; }
.qc-val-card__list li { position: relative; padding-left: 18px; font-size: 13.5px; line-height: 1.5; color: var(--accent); font-weight: 600; }
.qc-val-card__list li::before { content: ''; position: absolute; left: 0; top: 8px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
@media (max-width: 680px) {
.qc-val-card { padding: 24px 22px 22px !important; }
.qc-val-card__h { font-size: 18px !important; }
.qc-val-card__t { font-size: 14px !important; }
}
`;
document.head.appendChild(s);
}, []);
return null;
}
/* ─────────────────────────────────────────
CERTS — Legacy-Look
───────────────────────────────────────── */
function CertsPage({ brand }) {
const { t, lang } = useT();
const certName = (n) => {
const m = { 'Qualitätsmanagement': { en: 'Quality management', tr: 'Kalite yönetimi' }, 'Umweltmanagement': { en: 'Environmental management', tr: 'Çevre yönetimi' } };
return lang === 'de' ? n : (m[n] && m[n][lang]) || n;
};
const certValid = (v) => {
if (lang === 'de' || !v) return v;
const yr = (v.match(/\d{4}/) || [''])[0];
if (lang === 'en') return yr ? `valid until ${yr}` : v;
if (lang === 'tr') return yr ? `${yr}’e kadar geçerli` : v;
return v;
};
const d = window.QC_CONTENT.certs[brand];
const isIfm = brand === 'ifm';
const heroImg = isIfm ? 'assets/ifm-hero.png' : 'assets/lns-kabel.jpg';
const [lightbox, setLightbox] = useI(null);
React.useEffect(() => {
if (!lightbox) return;
const onKey = (e) => { if (e.key === 'Escape') setLightbox(null); };
window.addEventListener('keydown', onKey);
document.body.style.overflow = 'hidden';
return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = ''; };
}, [lightbox]);
// map known cert codes to image files
const imgFor = (code, c) => {
if (c && c.img) return c.img;
if (code.includes('9001')) return isIfm ? 'assets/zertifikate/qc-iso-9001.jpg' : 'assets/zertifikate/lns-iso-9001.jpg';
if (code.includes('14001')) return 'assets/zertifikate/qc-iso-14001.jpg';
return null;
};
return (
{t('certs.overview.label', 'Übersicht')}
{t('certs.overview.title', 'Unsere aktuellen Zertifizierungen')}
{d.list.map((c, i) => {
const img = imgFor(c.code, c);
const isIso9 = c.code.includes('9001');
const isIso14 = c.code.includes('14001');
const scopeKey = isIso9 ? `${brand}.certs.iso9.scope` : isIso14 ? `${brand}.certs.iso14.scope` : null;
return (
{ if (img) setLightbox({ src: img, label: c.code }); }}
aria-label={img ? `${c.code} vergrößern` : c.code}
type="button"
>
{img ?
{e.target.style.display = 'none';e.target.nextSibling && (e.target.nextSibling.style.display = 'block');}} /> :
null}
{isIfm && (isIso9 || isIso14) && }
{c.code}
{img && (
)}
{c.code}
{certName(c.name)}
{t('certs.scope.h', 'Geltungsbereich')} {scopeKey ? t(scopeKey, c.scope) : c.scope}
{(isIso9 || isIso14) ? t('certs.body.h', 'Zertifizierungsstelle') : t('certs.body2.h', 'Art des Nachweises')} {c.body}
{(isIso9 || isIso14) && (<>{t('certs.acc.h', 'Akkreditierung')} {t('certs.dakks', 'DAkkS · IAF')} >)}
{certValid(c.valid)}
);
})}
{/* Was uns Zertifizieren bedeutet */}
{t('certs.bg.label', 'Hintergrund')}
für uns bedeutet') }} />
{t('certs.next.t', 'Zertifizierungen sind kein Selbstzweck. Sie zwingen uns zu Disziplin: Prozesse werden dokumentiert, Abweichungen analysiert, Verbesserungen umgesetzt. Jährliche Überwachungsaudits durch unabhängige Stellen sichern, dass Anspruch und Realität deckungsgleich bleiben — auf jeder Baustelle, in jedem Auftrag.')}
{/* Lightbox */}
{lightbox && (
{ if (e.target.classList.contains('cert-lightbox')) setLightbox(null); }}>
setLightbox(null)} aria-label="Schließen">×
{lightbox.label}
)}
);
}
/* ─────────────────────────────────────────
TEAM — Legacy-Look mit Org-Chart + Filter
───────────────────────────────────────── */
function TeamPage({ brand }) {
const { t } = useT();
const td = window.TEAM_DATA[brand];
const all = [...td.leadership, ...td.team];
const depts = [...new Set(all.map((p) => p.dept))];
const [active, setActive] = useI('all');
const [openId, setOpenId] = useI(null);
const list = active === 'all' ? td.team : td.team.filter((p) => p.dept === active);
const isIfm = brand === 'ifm';
const heroImg = isIfm ? 'assets/ifm-bg.jpg' : 'assets/lns-tiefbau.jpeg';
const initials = (n) => n.split(' ').filter((p) => p[0] && p[0] === p[0].toUpperCase()).slice(0, 2).map((p) => p[0]).join('');
// Org: GF row + Bereichsleitung row
const gf = td.leadership.filter((p) => p.dept === 'Geschäftsführung');
const bl = td.leadership.filter((p) => p.dept !== 'Geschäftsführung');
const openPerson = openId ? all.find((p) => p.id === openId) : null;
// ── WIP-Schalter: nur LNS-Team-Seite vorerst in Bearbeitung.
const TEAM_WIP = brand === 'lns';
if (TEAM_WIP) {
return (
{t('wip.h', 'Diese Seite ist in Bearbeitung.')}
{t('wip.team.p', 'Wir stellen Ihnen unser Team in Kürze hier vor. Bis dahin erreichen Sie uns jederzeit direkt.')}
);
}
return (
{/* Org chart */}
{td.leadership.length > 0 &&
{t('team.leadership.label', 'Führung')}
{t('team.leadership.title', 'Geschäftsführung & Bereichsleitung')}
{gf.length > 0 &&
{gf.map((p) =>
setOpenId(p.id)}>
{p.photo ?
: initials(p.name)}
{p.name}
{p.role}
{p.dept}
)}
}
{gf.length > 0 && bl.length > 0 && <>
>}
{bl.length > 0 &&
{bl.map((p) =>
setOpenId(p.id)}>
{p.photo ?
: initials(p.name)}
{p.name}
{p.role}
{p.dept}
)}
}
}
{/* Team grid with filters */}
{t('team.staff.label', 'Mitarbeiter')}
{t('team.staff.title', 'Unser Team')}
setActive('all')}>{t('team.filter.all', 'Alle')} ({td.team.length})
{depts.filter((d) => td.team.some((p) => p.dept === d)).map((d) =>
setActive(d)}>{d} ({td.team.filter((p) => p.dept === d).length})
)}
{list.map((p) =>
setOpenId(p.id)}>
{p.photo ?
: initials(p.name)}
{p.name}
{p.role}
{p.dept}
)}
{openPerson &&
{if (e.target.classList.contains('tm-modal')) setOpenId(null);}}>
setOpenId(null)}>×
{openPerson.photo ?
: initials(openPerson.name)}
{openPerson.name}
{openPerson.role}
{openPerson.dept}
{openPerson.bio}
{openPerson.email &&
{openPerson.email} }
}
);
}
/* ─────────────────────────────────────────
CONTACT — original legacy markup
───────────────────────────────────────── */
function ContactStyles() {
React.useEffect(() => {
if (document.getElementById('contact-styles')) return;
const s = document.createElement('style');
s.id = 'contact-styles';
s.textContent = `
.ct-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 64px; align-items: start; }
@media (max-width: 900px) { .ct-grid { grid-template-columns: 1fr; gap: 40px; } }
.ct-info { background: var(--light); padding: 36px; border-left: 4px solid var(--accent); }
.ct-block { margin-bottom: 28px; }
.ct-block:last-child { margin-bottom: 0; }
.ct-block__label { font-size: 10px; font-weight: 700; letter-spacing: 0.25em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
.ct-block__value { font-size: 15px; line-height: 1.7; color: #222; white-space: pre-line; }
.ct-block__value a { color: var(--accent); text-decoration: none; }
.ct-block__value a:hover { text-decoration: underline; }
.ct-section-label { font-size: 11px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent); margin-bottom: 12px; }
.ct-section-title { font-size: 32px; font-weight: 700; line-height: 1.15; margin-bottom: 16px; }
.ct-intro { font-size: 16px; line-height: 1.7; color: #555; margin-bottom: 36px; }
.ct-form { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 600px) { .ct-form { grid-template-columns: 1fr; } }
.ct-form__full { grid-column: 1 / -1; }
.ct-field { display: flex; flex-direction: column; }
.ct-field label { font-size: 11px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: #555; margin-bottom: 6px; }
.ct-field input, .ct-field select, .ct-field textarea {
width: 100%; padding: 12px 14px; border: 1px solid #ddd; background: #fafafa;
font-family: inherit; font-size: 14px; color: #222; transition: border-color .2s, background .2s;
}
.ct-field input:focus, .ct-field select:focus, .ct-field textarea:focus {
outline: none; border-color: var(--accent); background: #fff;
}
.ct-field textarea { min-height: 140px; resize: vertical; }
.ct-submit { display: inline-flex; align-items: center; gap: 12px; background: var(--accent); color: #fff; border: none; font-family: inherit; font-size: 11px; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase; padding: 14px 28px; cursor: pointer; transition: opacity .2s; }
.ct-submit:hover { opacity: 0.85; }
.ct-success { background: #fff4ec; border-left: 4px solid var(--accent); padding: 18px 22px; margin-top: 18px; font-size: 14px; color: #b04510; }
.ct-map-section { padding: 0 0 96px; }
.ct-map-wrap { width: 100%; height: 480px; position: relative; overflow: hidden; border-top: 4px solid var(--accent); }
.ct-map-wrap iframe { width: 100%; height: 100%; border: 0; display: block; }
.ct-map-consent { width: 100%; height: 100%; border: 0; cursor: pointer; background: #1a1a1a; color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 32px; text-align: center; font-family: inherit; }
.ct-map-consent svg { color: var(--accent); margin-bottom: 4px; }
.ct-map-consent__title { font-size: 18px; font-weight: 700; letter-spacing: 0.02em; }
.ct-map-consent__text { font-size: 13px; line-height: 1.6; color: rgba(255,255,255,0.65); max-width: 420px; }
.ct-map-consent__btn { margin-top: 8px; display: inline-block; padding: 12px 24px; background: var(--accent); color: #fff; font-size: 12px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; }
.ct-map-consent:hover .ct-map-consent__btn { background: #fff; color: #1a1a1a; }
.ct-map-cta { position: absolute; bottom: 24px; right: 24px; background: #fff; padding: 14px 22px; box-shadow: 0 8px 24px rgba(0,0,0,0.15); font-size: 11px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent); text-decoration: none; display: inline-flex; align-items: center; gap: 8px; transition: background 0.2s, color 0.2s; }
.ct-map-cta:hover { background: var(--accent); color: #fff; }
`;
document.head.appendChild(s);
}, []);
return null;
}
function ContactPage({ brand }) {
const { t } = useT();
const d = window.QC_CONTENT.contact[brand];
const [sent, setSent] = useI(false);
const [mapConsent, setMapConsent] = useI(false);
const [sending, setSending] = useI(false);
const [sendError, setSendError] = useI(false);
const isIfm = brand === 'ifm';
const submitContact = async (e) => {
e.preventDefault();
if (sending) return;
const form = e.target;
const payload = {
brand,
name: form.name.value,
company: form.company ? form.company.value : '',
email: form.email.value,
phone: form.phone ? form.phone.value : '',
city: form.city ? form.city.value : '',
topic: form.topic ? form.topic.value : '',
message: form.message.value,
website: form.website ? form.website.value : ''
};
setSending(true); setSendError(false);
try {
const res = await fetch('kontakt.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const data = await res.json().catch(() => ({ ok: false }));
if (res.ok && data.ok) { setSent(true); }
else { setSendError(true); }
} catch (err) {
setSendError(true);
} finally {
setSending(false);
}
};
const mapQ = d.mapQuery || 'Blankenburger+Straße+18,+13089+Berlin';
return (
{/* FORM */}
{t('contact.form.label', 'Anfrage senden')}
{t('contact.form.title', 'Schreiben Sie uns')}
{isIfm ?
t('ifm.contact.intro', 'Beschreiben Sie kurz Ihr Anliegen — wir melden uns in der Regel innerhalb eines Werktags.') :
t('lns.contact.intro', 'Beschreiben Sie kurz Bauvorhaben und Standort — wir melden uns in der Regel innerhalb eines Werktags.')}
{sent ?
{t('contact.success', 'Vielen Dank — wir haben Ihre Nachricht erhalten und melden uns zeitnah. Eine Eingangsbestätigung haben wir Ihnen per E-Mail geschickt (bitte ggf. auch den Spam-Ordner prüfen).')}
:
}
{/* INFO */}
{isIfm ? t('contact.info.address', 'Adresse') : t('contact.info.hq', 'Leitungszentrale')}
{d.address}
{t('contact.info.phone', 'Telefon')}
{d.phone}
{d.fax ? <>{'\n'}{t('contact.info.fax', 'Fax')}: {d.fax}> : null}
{t('contact.info.email', 'E-Mail')}
{isIfm ? t('contact.info.hours', 'Öffnungszeiten') : t('contact.info.officehours', 'Bürozeiten')}
{t(`${brand}.contact.hours`, d.hours)}
{isIfm && (
{t('contact.info.emergency', 'Notfall & Winterdienst')}
)}
{/* MAP — DSGVO: erst nach Klick laden */}
{mapConsent ? (
) : (
setMapConsent(true)}>
{t('contact.map.consent.title', 'Karte anzeigen')}
{t('contact.map.consent.text', 'Mit dem Laden der Karte akzeptieren Sie die Datenschutzbestimmungen von Google. Es werden Daten an Google übertragen.')}
{t('contact.map.consent.btn', 'Google Maps laden')}
)}
{mapConsent && (
{t('contact.map.route', 'Route planen')}
)}
);
}
/* ─────────────────────────────────────────
PROJECTS — neu strukturiert (LNS-fokussiert)
───────────────────────────────────────── */
function ProjectsPage({ brand }) {
const { t } = useT();
const bf = brand;
// ── WIP-Schalter: Projekte-Seite noch nicht final. true = "in Bearbeitung"-Hinweis.
// Zum Freischalten der echten Projekte-Seite auf false setzen.
const PROJ_WIP = true;
if (PROJ_WIP) {
return (
{t('wip.h', 'Diese Seite ist in Bearbeitung.')}
{t('wip.proj.p', 'Wir stellen Ihnen unsere Referenzprojekte in Kürze hier vor. Bis dahin erreichen Sie uns jederzeit direkt.')}
);
}
const [discipline, setDisc] = useI('all');
const [region, setRegion] = useI('all');
const [year, setYear] = useI('all');
const [activeId, setActive] = useI(null);
const allProjects = window.QC_DATA.projects;
const brandProjects = allProjects.filter(p => p.brand === bf);
const filtered = brandProjects.filter(p =>
(discipline === 'all' || (p.discipline || '') === discipline) &&
(region === 'all' || p.region === region) &&
(year === 'all' || p.year === year)
);
const discLabels = { glasfaser: 'FTTH-Glasfaserausbau', tiefbau: 'Tiefbau', strassenbau: 'Straßenbau', verkehr: 'Verkehrssicherung' };
const disciplines = [];
const regions = [...new Set(brandProjects.map(p => p.region))];
const years = [...new Set(brandProjects.map(p => p.year))].sort((a,b) => Number(b) - Number(a));
const featured = filtered[0];
const rest = filtered.slice(1);
const activeProject = activeId ? allProjects.find(p => p.id === activeId) : null;
// Discipline-Icon for disciplines we use
const discIcon = {
glasfaser: '📡',
tiefbau: '⛏',
strassenbau:'🚧',
verkehr: '🛡'
};
// Aggregate stats across filtered LNS projects
const totalKm = bf === 'lns' ? filtered.reduce((s,p)=>{
const km = parseFloat((p.stats||[]).find(x=>/km/.test(x.num||''))?.num) || 0;
return s + km;
}, 0) : 0;
return (
{/* Hero — page head */}
{t('projects.title', 'Projekte aus der Praxis.').replace(/ /gi, ' ')}
{bf === 'lns'
? 'Über 64 Projekte haben wir deutschlandweit realisiert — vom Glasfaser-Hausanschluss bis zum großflächigen FTTH-Ausbau ganzer Landkreise. Hier sehen Sie eine Auswahl der wichtigsten. Klicken Sie ein Projekt für Details.'
: t('projects.lead', 'Eine Auswahl aktueller und abgeschlossener Aufträge — vom Wohnumfeld bis zum Backbone.')}
{/* Filter bar */}
{disciplines.length > 0 && (
Bereich
setDisc('all')}>Alle
{disciplines.map(d => (
setDisc(d.id)}>
{d.label} ({brandProjects.filter(p => p.discipline === d.id).length})
))}
)}
Region
setRegion('all')}>{t('projects.allregions', 'Alle Regionen')}
{regions.map(r => (
setRegion(r)}>{t('projects.region.' + r, r)}
))}
Jahr
setYear('all')}>Alle
{years.map(y => (
setYear(y)}>{y}
))}
{filtered.length} von {brandProjects.length}
{/* Featured project */}
{featured && (
Highlight
setActive(featured.id)}>
{featured.img ?
:
📷
}
{featured.year}
{featured.status &&
{featured.status}
}
{t('projects.region.' + featured.region, featured.region)}
{featured.discipline ? (discLabels[featured.discipline] || featured.discipline) : 'QC ' + featured.brand.toUpperCase()}
{t('projects.p' + featured.id + '.title', featured.title)}
{featured.headline &&
{featured.headline}
}
Auftraggeber
{featured.client}
{featured.stats && (
{featured.stats.map((s, i) => (
))}
)}
Projekt-Details ansehen →
)}
{/* Grid of remaining projects */}
{rest.length > 0 && (
Weitere Projekte
{rest.map(p => (
setActive(p.id)}>
{p.img ?
:
📷
}
{p.year}
{p.status &&
{p.status}
}
{t('projects.region.' + p.region, p.region)}
·
{p.discipline ? (discLabels[p.discipline] || p.discipline) : 'QC ' + p.brand.toUpperCase()}
{t('projects.p' + p.id + '.title', p.title)}
{p.client}
{p.headline &&
{p.headline}
}
{p.stats && p.stats.length > 0 && (
{p.stats.slice(0, 2).map((s, i) => (
{s.num}
{s.label}
))}
)}
Details →
))}
Eine Auswahl aus über 60 abgeschlossenen und laufenden Projekten — von Hamburg bis Sachsen. Gerne stellen wir Ihnen weitere Referenzen auf Anfrage zusammen.
)}
{filtered.length === 0 && (
Keine Projekte mit dieser Filterauswahl.
{setDisc('all'); setRegion('all'); setYear('all');}}>Filter zurücksetzen
)}
{/* CTA */}
Ihr Projekt
Sie planen einen Netzausbau? Sprechen wir darüber.
Erzählen Sie uns von Ihrem Vorhaben — wir melden uns mit einer konkreten Einschätzung.
Anfrage stellen →
{/* Detail modal */}
{activeProject && (
setActive(null)} t={t} disciplines={disciplines} />
)}
);
}
function ProjectModal({ project, onClose, t, disciplines }) {
React.useEffect(() => {
document.body.style.overflow = 'hidden';
const onEsc = e => { if (e.key === 'Escape') onClose(); };
window.addEventListener('keydown', onEsc);
return () => { document.body.style.overflow = ''; window.removeEventListener('keydown', onEsc); };
}, []);
const p = project;
const discLabel = p.discipline ? (disciplines.find(d => d.id === p.discipline)?.label || p.discipline) : null;
return (
{ if (e.target.classList.contains('prj-modal')) onClose(); }}>
×
{p.beforeImg && p.afterImg ? (
<>
{/* Title bar without image */}
{p.period || p.year}
{t('projects.region.' + p.region, p.region)}
{discLabel && <>{discLabel} >}
{t('projects.p' + p.id + '.title', p.title)}
{p.headline &&
{p.headline}
}
{p.status &&
{p.status}
}
{/* Slider as separate block */}
>
) : (
{p.img ?
:
📷
}
{p.year}
{t('projects.region.' + p.region, p.region)}
{discLabel && <>{discLabel} >}
{t('projects.p' + p.id + '.title', p.title)}
{p.headline &&
{p.headline}
}
{p.status &&
{p.status}
}
)}
{/* Stats */}
{p.stats && p.stats.length > 0 && (
{p.stats.map((s, i) => (
))}
)}
{/* Client + services */}
Leistungen
{p.services.map(s => (
{t('projects.svc.' + s, s)}
))}
{/* Challenge / Approach / Result */}
{(p.challenge || p.approach || p.result) && (
{p.challenge && (
Die Herausforderung
{p.challenge}
)}
{p.approach && (
Unser Ansatz
{p.approach}
)}
{p.result && (
)}
)}
{/* Fallback short desc if no full story */}
{!p.challenge && p.desc && (
{t('projects.p' + p.id + '.desc', p.desc)}
)}
{/* Team */}
{p.people && p.people.length > 0 && (
Projektteam
{p.people.map(person => {person} )}
)}
{/* CTA */}
);
}
function ProjectsStyles() {
React.useEffect(() => {
if (document.getElementById('prj-styles')) return;
const s = document.createElement('style');
s.id = 'prj-styles';
s.textContent = `
/* Hero */
.prj-hero { background: #1a1a1a; color: #fff; padding: 120px 0 64px; position: relative; }
.prj-hero::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--accent); }
.prj-hero__crumbs { display: flex; align-items: center; gap: 10px; font-size: 11px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(255,255,255,0.5); margin-bottom: 20px; }
.prj-hero__crumbs a { color: rgba(255,255,255,0.5); text-decoration: none; }
.prj-hero__crumbs a:hover { color: #fff; }
.prj-hero__crumbs > span:last-child { color: #fff; }
.prj-hero__title { font-size: clamp(36px, 6vw, 64px); font-weight: 800; line-height: 1.05; letter-spacing: -0.02em; margin: 0 0 16px; }
.prj-hero__lead { font-size: 17px; line-height: 1.6; color: rgba(255,255,255,0.72); max-width: 68ch; margin: 0 0 28px; }
.prj-hero__stats { display: flex; gap: 32px; font-size: 13px; color: rgba(255,255,255,0.55); padding-top: 24px; border-top: 1px solid rgba(255,255,255,0.12); flex-wrap: wrap; }
.prj-hero__stats strong { color: #fff; font-size: 22px; font-weight: 700; display: block; margin-bottom: 2px; font-variant-numeric: tabular-nums; }
/* Filter bar */
.prj-filter { background: #fafafa; border-bottom: 1px solid #e0e0e0; padding: 12px 0; position: sticky; top: 68px; z-index: 50; }
.prj-filter__row { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: center; }
.prj-filter__group { display: flex; align-items: center; gap: 10px; }
.prj-filter__label { font-size: 10px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: #888; flex-shrink: 0; }
.prj-filter__count { font-size: 12px; color: #888; margin-left: auto; padding-left: 14px; border-left: 1px solid #ddd; }
.prj-filter .chip { padding: 4px 10px; font-size: 12px; border-radius: 14px; }
@media (max-width: 720px) { .prj-filter { padding: 10px 0; } .prj-filter__count { width: 100%; margin-left: 0; padding-left: 0; border-left: none; padding-top: 6px; border-top: 1px solid #e0e0e0; } }
/* Sections */
.prj-section { padding: 64px 0; }
.prj-section--alt { background: #fafafa; padding: 80px 0; }
.prj-eyebrow { display: flex; align-items: center; gap: 14px; margin-bottom: 32px; font-size: 10px; font-weight: 700; letter-spacing: 0.28em; text-transform: uppercase; color: var(--accent); }
.prj-eyebrow__line { flex: 1; height: 2px; background: var(--accent); opacity: 0.25; }
/* Featured */
.prj-featured { display: grid; grid-template-columns: 1.2fr 1fr; gap: 0; background: #fff; border: 1px solid #ececec; cursor: pointer; padding: 0; font-family: inherit; text-align: left; width: 100%; overflow: hidden; transition: transform 0.25s, box-shadow 0.25s; }
.prj-featured:hover { transform: translateY(-3px); box-shadow: 0 20px 50px rgba(0,0,0,0.1); }
@media (max-width: 900px) { .prj-featured { grid-template-columns: 1fr; } }
.prj-featured__media { position: relative; min-height: 380px; background: #1a1a1a; overflow: hidden; }
.prj-featured__media img { width: 100%; height: 100%; object-fit: cover; position: absolute; inset: 0; transition: transform 0.6s; }
.prj-featured:hover .prj-featured__media img { transform: scale(1.04); }
.prj-featured__media-ph { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 60px; color: rgba(255,255,255,0.2); }
.prj-featured__overlay { position: absolute; inset: 0; background: linear-gradient(180deg, transparent 30%, rgba(0,0,0,0.45) 100%); }
.prj-featured__year { position: absolute; left: 28px; top: 24px; z-index: 2; color: #fff; font-size: 64px; font-weight: 900; letter-spacing: -0.03em; line-height: 0.85; font-variant-numeric: tabular-nums; text-shadow: 0 2px 12px rgba(0,0,0,0.4); }
.prj-featured__status { position: absolute; right: 24px; top: 24px; z-index: 2; padding: 6px 12px; background: var(--accent); color: #fff; font-size: 10px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; }
.prj-featured__body { padding: 40px 44px; display: flex; flex-direction: column; }
@media (max-width: 720px) { .prj-featured__body { padding: 28px 24px; } .prj-featured__year { font-size: 44px; left: 20px; top: 18px; } .prj-featured__media { min-height: 260px; } }
.prj-featured__meta { display: flex; align-items: center; gap: 12px; font-size: 11px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent); margin-bottom: 16px; }
.prj-featured__dot { width: 4px; height: 4px; border-radius: 50%; background: rgba(0,0,0,0.2); }
.prj-featured__title { font-size: 28px; font-weight: 700; line-height: 1.2; letter-spacing: -0.015em; margin: 0 0 12px; }
.prj-featured__headline { font-size: 15.5px; line-height: 1.6; color: #555; margin: 0 0 20px; }
.prj-featured__client { display: flex; align-items: center; gap: 14px; padding: 14px 0; border-top: 1px solid #ececec; border-bottom: 1px solid #ececec; margin-bottom: 20px; }
.prj-featured__client-label { font-size: 10px; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase; color: #999; }
.prj-featured__client-name { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.prj-featured__stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 16px; margin-bottom: 24px; }
.prj-featured__stat-num { font-size: 22px; font-weight: 800; color: var(--accent); letter-spacing: -0.01em; }
.prj-featured__stat-lbl { font-size: 11px; color: #777; letter-spacing: 0.06em; margin-top: 2px; }
.prj-featured__cta { margin-top: auto; font-size: 13px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }
/* Card grid */
.prj-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 20px; }
.prj-card { background: #fff; border: 1px solid #ececec; cursor: pointer; padding: 0; font-family: inherit; text-align: left; overflow: hidden; transition: transform 0.25s, box-shadow 0.25s; display: flex; flex-direction: column; }
.prj-card:hover { transform: translateY(-3px); box-shadow: 0 16px 36px rgba(0,0,0,0.08); }
.prj-card__media { position: relative; aspect-ratio: 16/10; background: #1a1a1a; overflow: hidden; }
.prj-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s; }
.prj-card:hover .prj-card__media img { transform: scale(1.05); }
.prj-card__media-ph { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 40px; color: rgba(255,255,255,0.25); }
.prj-card__year { position: absolute; left: 18px; top: 14px; color: #fff; font-size: 32px; font-weight: 900; letter-spacing: -0.02em; text-shadow: 0 2px 8px rgba(0,0,0,0.4); font-variant-numeric: tabular-nums; }
.prj-card__status { position: absolute; right: 14px; top: 14px; padding: 4px 10px; background: var(--accent); color: #fff; font-size: 10px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; }
.prj-card__status--done { background: #1f8a4c; }
.prj-featured__status--done { background: #1f8a4c; }
.prj-card__body { padding: 24px 26px 22px; display: flex; flex-direction: column; flex: 1; }
.prj-card__meta { display: flex; gap: 8px; font-size: 10.5px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); margin-bottom: 10px; }
.prj-card__title { font-size: 18px; font-weight: 700; line-height: 1.3; letter-spacing: -0.005em; margin: 0 0 8px; }
.prj-card__client { font-size: 12.5px; color: #888; margin-bottom: 12px; }
.prj-card__headline { font-size: 13.5px; line-height: 1.55; color: #555; margin: 0 0 16px; flex: 1; }
.prj-card__stats { display: flex; gap: 18px; padding: 14px 0; border-top: 1px solid #ececec; margin-bottom: 14px; }
.prj-card__stat-num { font-size: 16px; font-weight: 800; color: var(--accent); letter-spacing: -0.01em; display: block; }
.prj-card__stat-lbl { font-size: 10.5px; color: #888; letter-spacing: 0.04em; margin-top: 2px; display: block; }
.prj-card__cta { font-size: 11px; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); margin-top: auto; }
/* CTA */
.prj-cta { background: #1a1a1a; color: #fff; padding: 80px 0; }
.prj-more-note { display: flex; align-items: flex-start; gap: 18px; margin-top: 48px; padding-top: 28px; border-top: 1px solid #e0e0e0; }
.prj-more-note__line { flex-shrink: 0; width: 32px; height: 2px; background: var(--accent); margin-top: 9px; }
.prj-more-note__text { font-size: 14.5px; line-height: 1.65; color: #666; max-width: 70ch; }
.prj-cta__inner { display: grid; grid-template-columns: 1.5fr auto; gap: 40px; align-items: center; }
@media (max-width: 800px) { .prj-cta__inner { grid-template-columns: 1fr; } }
.prj-cta__eyebrow { font-size: 11px; font-weight: 700; letter-spacing: 0.22em; text-transform: uppercase; color: var(--accent); margin-bottom: 14px; }
.prj-cta__title { font-size: clamp(24px, 3.4vw, 36px); font-weight: 700; line-height: 1.2; letter-spacing: -0.015em; margin: 0 0 12px; }
.prj-cta__sub { font-size: 15.5px; line-height: 1.6; color: rgba(255,255,255,0.65); margin: 0; max-width: 60ch; }
/* Modal */
.prj-modal { position: fixed; inset: 0; background: rgba(0,0,0,0.78); z-index: 300; display: flex; align-items: flex-start; justify-content: center; padding: 40px 20px; overflow-y: auto; animation: prjFadeIn 0.18s ease-out; }
@keyframes prjFadeIn { from { opacity: 0; } to { opacity: 1; } }
.prj-modal__box { background: #fff; max-width: 980px; width: 100%; border-radius: 4px; position: relative; overflow: hidden; animation: prjSlideUp 0.22s cubic-bezier(0.2, 0.8, 0.2, 1); will-change: transform, opacity; }
@keyframes prjSlideUp { from { transform: translateY(12px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
.prj-modal__close { position: absolute; top: 16px; right: 16px; z-index: 5; width: 40px; height: 40px; border-radius: 50%; background: rgba(255,255,255,0.92); border: none; font-size: 28px; line-height: 1; cursor: pointer; color: #1a1a1a; display: flex; align-items: center; justify-content: center; transition: background 0.15s; }
.prj-modal__close:hover { background: #fff; }
.prj-modal__hero { position: relative; height: 360px; background: #1a1a1a; overflow: hidden; }
@media (max-width: 720px) { .prj-modal__hero { height: 260px; } }
.prj-modal__hero img { width: 100%; height: 100%; object-fit: cover; }
.prj-modal__hero-ph { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 60px; color: rgba(255,255,255,0.2); }
.prj-modal__hero-overlay { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,0.1) 0%, rgba(0,0,0,0.75) 100%); }
.prj-modal__hero-content { position: absolute; left: 0; right: 0; bottom: 0; padding: 36px 40px; color: #fff; }
/* Title bar variant — used when BeforeAfter slider is shown */
.prj-modal__title-bar { background: #1a1a1a; color: #fff; padding: 36px 40px 30px; position: relative; }
@media (max-width: 720px) { .prj-modal__title-bar { padding: 26px 24px 22px; } }
.prj-modal__slider { background: #0a0a0a; padding: 0; }
.prj-modal__status--inbar { position: absolute; right: 24px; top: 24px; }
@media (max-width: 720px) { .prj-modal__hero-content { padding: 24px; } }
.prj-modal__hero-meta { display: flex; align-items: center; gap: 12px; font-size: 11px; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); margin-bottom: 12px; }
.prj-modal__dot { width: 4px; height: 4px; border-radius: 50%; background: rgba(255,255,255,0.45); }
.prj-modal__title { font-size: clamp(24px, 3.4vw, 36px); font-weight: 800; line-height: 1.15; letter-spacing: -0.02em; margin: 0 0 10px; }
.prj-modal__headline { font-size: 16px; line-height: 1.5; color: rgba(255,255,255,0.9); margin: 0; max-width: 60ch; }
.prj-modal__status { position: absolute; right: 16px; top: 16px; padding: 6px 14px; background: var(--accent); color: #fff; font-size: 11px; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; }
.prj-modal__body { padding: 36px 40px 40px; }
@media (max-width: 720px) { .prj-modal__body { padding: 24px; } }
.prj-modal__stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 20px; padding-bottom: 28px; border-bottom: 1px solid #ececec; margin-bottom: 28px; }
.prj-modal__stat-num { font-size: 28px; font-weight: 800; color: var(--accent); letter-spacing: -0.02em; }
.prj-modal__stat-lbl { font-size: 12px; color: #777; letter-spacing: 0.06em; margin-top: 4px; }
.prj-modal__row { display: grid; grid-template-columns: 220px 1fr; gap: 32px; padding-bottom: 28px; border-bottom: 1px solid #ececec; margin-bottom: 28px; }
@media (max-width: 600px) { .prj-modal__row { grid-template-columns: 1fr; gap: 18px; } }
.prj-modal__h { font-size: 11px; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase; color: #999; margin-bottom: 8px; }
.prj-modal__client { font-size: 17px; font-weight: 700; color: #1a1a1a; }
.prj-modal__services { display: flex; flex-wrap: wrap; gap: 6px; }
.prj-modal__service { font-size: 12px; padding: 5px 12px; background: #f4f4f0; border-radius: 2px; color: #444; }
.prj-modal__story { display: flex; flex-direction: column; gap: 24px; margin-bottom: 28px; }
.prj-modal__story-block { padding-left: 16px; border-left: 3px solid var(--accent); }
.prj-modal__story-label { font-size: 11px; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase; color: var(--accent); margin-bottom: 6px; }
.prj-modal__story-block p { font-size: 14.5px; line-height: 1.7; color: #444; margin: 0; }
.prj-modal__team { padding-top: 24px; border-top: 1px solid #ececec; margin-top: 8px; }
.prj-modal__people { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.prj-modal__person { font-size: 13px; padding: 6px 12px; background: #fafafa; border: 1px solid #ececec; border-radius: 20px; color: #444; }
.prj-modal__cta { margin-top: 28px; padding-top: 24px; border-top: 1px solid #ececec; text-align: center; }
`;
document.head.appendChild(s);
}, []);
return null;
}
Object.assign(window, { PageHead, PageHero, InfoHeroStyles, AboutPage, CompaniesPage, TechPage, ValuesPage, CertsPage, TeamPage, ContactPage, ProjectsPage });