glanzlicht / OnOffice-Hardimporter-Addon

OnOffice Hardimporter Addon

Verified secure showcase
30 Files 289 KB Public size 0 Redacted PHP · CSS · JavaScript · Markdown

Project overview

OnOffice-Hardimporter-Addon is a verified code showcase with 30 visible project entries across 3 top-level modules. The primary detected language is PHP; protected files remain visible in the structure while their contents stay private.

README

onOffice Elementor Bridge

Version 0.9.8 – Entwicklungsfassung von FRESH.

Zweck

Das Plugin ergänzt onOffice for WP-Websites. Es übernimmt Immobilien über dessen vorhandene API-Anbindung und speichert sie als echte lokale WordPress-Datensätze. Damit können Elementor Pro, SEO-Plugins und eigene Templates mit den Daten arbeiten, ohne an die Standardausgabe des onOffice-Plugins gebunden zu sein.

Voraussetzungen

  • WordPress 6.2+
  • PHP 8.0+
  • offizielles Plugin onOffice for WP-Websites (gegen 6.14 entwickelt)
  • darin eingerichtete/funktionierende onOffice-API-Zugangsdaten
  • Elementor Pro optional, aber für Dynamic-Template-Nutzung empfohlen

Neu in 0.2.0

  • dynamische Feldschema-Erkennung mit deutschen/überlieferten Feldbezeichnungen
  • vollständiger Feldimport in API-Blöcken statt 250-Feld-Grenze
  • Mapping für WordPress-Titel, Inhalt und Auszug
  • Taxonomien für Ort, Objektart, Vermarktungsart und Sync-Status
  • Sync-Status und onOffice-ID direkt in der Immobilienliste
  • Sync-Infobox im Immobilien-Editor
  • lokaler Galerie-Dynamic-Tag für Elementor
  • Galerie-Shortcode [oo_gallery]
  • reaktiviert archivierte Immobilien automatisch, wenn sie wieder in onOffice auftauchen

Custom Fields

Jedes geladene onOffice-Feld wird als WordPress-Metafeld gespeichert:

oo_<onoffice-feldname>

Beispiele:

  • oo_kaufpreis
  • oo_wohnflaeche
  • oo_anzahl_zimmer
  • oo_ort
  • oo_objektbeschreibung

Zusätzlich:

  • _fresh_oo_id – onOffice-ID
  • oo_gallery_ids – Array lokaler Attachment-IDs
  • oo_gallery_csv – dieselben IDs kommasepariert
  • oo_gallery_remote – Rohinformationen/Remote-URLs der onOffice-Bilder

Elementor

Normale Werte: Dynamic Tags → Custom Field und den gewünschten oo_*-Key verwenden.

Galerie: In einem Elementor-Widget, das den Dynamic-Tag-Typ „Gallery“ unterstützt, onOffice Galerie (lokal) auswählen.

Alternativ kann ein Shortcode-Widget verwendet werden:

[oo_gallery]

Verhalten bei entfernten Immobilien

Standardmäßig werden nicht mehr gelistete Immobilien nicht gelöscht, sondern auf Entwurf gesetzt und mit Status „Archiviert“ markiert. Dadurch bleiben Datensatz, Medien und Historie lokal erhalten.

Wichtiger Hinweis

Dies ist noch eine Entwicklungsfassung. Vor Produktion auf einer Staging-Seite mit dem echten Kundenaccount testen. Insbesondere kundenspezifische onOffice-Felder, Feldtypen, Bildkategorien, Mehrsprachigkeit und große Datenbestände müssen gegen die reale Installation geprüft werden.

Immobilien-Suche (0.3.0-Paket)

Zusätzlich enthalten ist onoffice-property-search.php mit dem Shortcode:

[oo_property_search]

Die Maske filtert den lokalen Immobilienbestand nach Kaufen/Mieten, Objektart, Ort, Preis, Wohnfläche, Zimmer und Suchbegriff.

Demo-Modus / Seeder (v0.4)

Unter Immobilien → Demo-Immobilien können 10 Berliner Beispielobjekte angelegt werden. Sie verwenden dieselben oo_*-Metafelder und Taxonomien wie der spätere Live-Import. Dadurch können Elementor-Templates, Loop-Grids und die Suchmaske vor Freischaltung des Kundenaccounts komplett gebaut und getestet werden. Der Löschbutton entfernt ausschließlich vom Seeder erzeugte Demo-Objekte.

0.5.2

  • Elementor Dynamic Tag fresh-oo-field als robuste benannte Data_Tag-Klasse umgesetzt.
  • Klasse wird erst im Elementor-Dynamic-Tag-Registrierungs-Hook geladen.
  • Bestehende Loop-Templates bleiben kompatibel, da der Tag-Name unverändert bleibt.

0.7.0

  • Neues Admin-Dashboard mit Statuskarten, Sync-Status, Mapping-Bereichen und einklappbaren Diagnoseansichten.
  • Elementor Dynamic Tag listet jetzt auch dynamisch erkannte onOffice-Felder.
  • Zahlen werden im Smart-Modus ohne unnötige .00 ausgegeben.
  • Meta-Box für Immobilien übersichtlicher und auf tatsächlich vorhandene Werte reduziert.

v0.7.0 — onOffice Immobiliengalerie

Neu ist ein eigenes Elementor-Widget „onOffice Immobiliengalerie“ im WooCommerce-Stil:

  • großes Hauptbild mit Thumbnail-Slider
  • Klick auf Thumbnail tauscht das Hauptbild
  • Swipe- und Tastatur-Navigation
  • optionale Fullscreen-Lightbox
  • responsive Seitenverhältnisse, Thumbnail-Größen und Abstände
  • umfangreiche Elementor-Styling-Optionen für Radien, Rahmen, Schatten, Farben und Navigation
  • nutzt automatisch die lokal importierten oo_gallery_ids der aktuellen Immobilie
  • responsive Bilder mit srcset/sizes, Lazy Loading für Thumbnails und priorisiertem Hauptbild
  • SEO/GEO-freundliches semantisches ImageGallery/ImageObject-Markup, sinnvolle Alt-Texte und optionale Captions
  • barrierearme Buttons, ARIA-Labels, Tastaturbedienung und prefers-reduced-motion

0.8.0 – Elementor Toolkit

Version 0.8.0 turns the bridge into a modular Elementor toolkit. The widgets read the locally synchronized oo_* fields of the current fresh_immobilie post, hide missing values automatically, and expose responsive Elementor style controls instead of imposing a fixed onOffice layout.

New widgets

  • onOffice Feld – any imported onOffice field with type-aware formatting, optional icon, label, prefix/suffix and empty-value handling.
  • onOffice Feldgruppe – freely configurable repeater of fields with individual icons, labels and formatting; responsive grid columns.
  • onOffice Eckdaten – a ready-to-use facts variant for living area, rooms, bedrooms, bathrooms etc., fully editable like the field group.
  • onOffice Preis – automatically chooses purchase/rental price, supports secondary price, monthly period, commission and Offer semantics.
  • onOffice Ausstattung – boolean/value-aware icon grid; entries only appear when the configured onOffice field is actually present/true.
  • onOffice Detailtabelle – freely sortable fields grouped into sections such as category, prices, areas and key facts; uses semantic dl/dt/dd markup.
  • onOffice Energieausweis – visual A+–H efficiency scale plus available energy certificate data; derives a display class from consumption when no class is supplied.
  • onOffice Immobiliengalerie – WooCommerce-style main image + thumbnail slider from v0.7 remains included.

All toolkit widgets live in their own Elementor category onOffice · FRESH and support Elementor typography, colors, borders, radii, shadows and responsive controls where appropriate. Empty data is suppressed by default to keep single-property templates reusable across heterogeneous onOffice records.

0.9.2 — Numeric formatter hotfix

Behebt einen Fehler der Smart-Formatierung, bei dem signifikante Nullen am Ende ganzer Zahlen entfernt wurden. Werte wie 160.00, 680.00, 200.00 und 299000.00 werden nun korrekt als 160, 680, 200 und 299.000 dargestellt. Dezimalwerte wie 2.50 bleiben kompakt als 2,5 erhalten.

0.9.0 — Smart Rendering

Version 0.9.0 führt eine zentrale semantische Feldlogik ein. Das Toolkit unterscheidet nun unter anderem Preise, Flächen, Energiekennwerte, Jahreszahlen, Datumswerte, Zähler, Booleans und Arrays. Dadurch werden Felder kontextgerecht formatiert und sinnlose Nullwerte intelligent ausgeblendet.

Neu bzw. erweitert:

  • Baujahr wird als 2002 statt 2.002 ausgegeben.
  • Datumswerte werden deutsch formatiert (05.04.2022).
  • Kauf-/Mietfelder werden anhand der Vermarktungsart sinnvoll gefiltert.
  • onOffice Eckdaten besitzt intelligente Presets und drei Darstellungsmodi.
  • onOffice Detailtabelle kann automatisch passende Sektionen und Felder erzeugen.
  • onOffice Energieausweis besitzt Kennwert, Klasse, Skala und Marker sowie Full/Compact/Scale-Layouts.
  • Neues Widget onOffice Objekt-Meta für Objektart, Objekttyp, Vermarktungsart und Objektnummer.
  • Neues Widget onOffice Adresse mit Datenschutzstufen und optionalem PostalAddress-Markup.

Neu in 0.9.2

  • Elementor Widget onOffice Objektkopf: Titel, Ort, Objekt-Meta und Preis in einem intelligenten Hero-Baustein.
  • Objekt-Meta mit optionalen Icons, vertikalem Modus und frei benennbarer Objektnummer.
  • Adress-Widget mit Inline/Mehrzeilen-Layout, privacy-aware Kartenlink und sauberem PostalAddress-Markup.
  • Erweiterte Styling-Optionen für Meta und Adresse.

0.9.3

  • Neues Elementor Widget onOffice Status-Badge auf Basis von oo_status2/oo_status, inklusive eigener Farben für aktive Vermarktung, Akquise, reserviert, verkauft/vermietet und sonstige Stati.
  • Optionaler globaler Farb-Override für das offizielle onOffice-Frontend (Links, Formulare, Buttons, Fokus/Hover) direkt in den Bridge-Einstellungen.
  • Immobilien-Suchfeld auf 6-Spalten-Grid angepasst; Suchbutton spannt 4 Spalten, äußerer Hintergrund transparent, weißer Hintergrund liegt nur auf dem Grid.

0.9.4 — Responsive Elementor controls

  • Erweitert die Toolkit-Widgets um responsive Desktop/Tablet/Mobile-Steuerung für sinnvolle Layoutwerte wie Ausrichtung, Spalten, Abstände, Radien, Padding und Icon-Größen.
  • Typografie bleibt über Elementors responsive Typography Group Controls steuerbar.
  • Detailtabelle und Energie-Details erhalten responsive Spaltensteuerung.
  • Galerie-Radien und aktive Rahmenbreite sind responsive.
  • Entfernt den festen Galerie-Hintergrund #F3F1ED; die Galerie ist standardmäßig transparent. Eine Hintergrundfarbe kann weiterhin bewusst im Widget gesetzt werden.

0.9.6

  • Ausstattungswerte semantisch bereinigt: verschachtelte Stellplatzdaten werden als echte Stellplatztypen/-anzahlen ausgegeben, boolesche Werte wie Haustiere nicht mehr als rohe 1.
  • Galerie gegen globale Button-Hover-Styles abgeschirmt: kein pinker Hintergrund am Hauptbild und kein pinker Rahmen an Thumbnails.

0.9.5 — Ausstattungs-Automatik & Admin-Notice-Fix

  • Admin-Hinweise anderer Plugins werden nicht mehr in den dunklen Sync-Hero hineingeschoben; der WordPress-Notice-Anker liegt außerhalb des Hero-Bereichs.
  • Das Widget onOffice Ausstattung rendert bei komplett leeren Treffern gar nichts mehr — auch keinen Hinweistext.
  • Deutlich umfangreicherer Standardkatalog an Ausstattungsmerkmalen mit Icons (u. a. Balkon, Terrasse, Fahrstuhl, Keller, Garten, Gäste-WC, Barrierefreiheit, TV, Kamin, Klima, Sauna, Wintergarten, Whirlpool, Einliegerwohnung, Denkmalschutz, Heizung, Befeuerung, Stellplatz, Boden, Internet, Haustiere, Erschließung).
  • Nicht gesetzte/inhaltlich leere Merkmale werden automatisch ausgeblendet; bei befüllten Text-/Auswahlfeldern kann der konkrete Wert mit ausgegeben werden.

0.9.7

  • Neues Elementor-Widget onOffice Immobilienbild als schlanke Alternative zur Galerie.
  • Nutzt automatisch Titelbild oder erstes Galeriebild der Immobilie.
  • Optionales Objektstatus-Badge direkt als Overlay auf dem Bild.
  • Badge-Position, Abstände, Typografie, Radius, Border, Shadow und Farben je Status in Elementor stylebar steuerbar.
  • Bildbreite, Höhe, Fit, Radius, Border und Shadow responsiv stylebar.

Neu in 0.9.8

  • Wird in onOffice „Auf Website veröffentlichen“ deaktiviert, setzt der nächste Sync eine bereits lokale Immobilie automatisch auf Entwurf.
  • Die lokale Kopie bleibt erhalten und wird bei erneuter Freigabe automatisch wieder veröffentlicht.
  • Nicht freigegebene Objekte gelten weiterhin als gesehen und werden nicht zusätzlich als „fehlend“ archiviert.

0.9.9

  • Objektkopf: Preisbereich um Provision, Zusatzpreis und Mietzeitraum ergänzt; Zusatztexte separat stylebar.

0.10.1

  • Neues Elementor-Widget „onOffice Objektanfrage“: rendert ein offizielles onOffice-Kontaktformular direkt im Immobilien-Template und setzt automatisch die onOffice Objekt-ID als Estate-Kontext.
  • Verwendet bewusst Kontaktformulare (nicht das Interessenten-/Suchprofil-Formular), damit objektbezogene Anfragen über die offizielle onOffice contactaddress-Logik laufen.

0.10.1

  • Neues Elementor-Widget „onOffice Objektkarte“ für die aktuelle Immobilie.
  • Neues Elementor-Widget „onOffice Immobilienkarte“ für mehrere veröffentlichte Immobilien.
  • Nutzt die Kartenanbieter-Einstellung des offiziellen onOffice-Plugins (OpenStreetMap oder Google Maps) oder einen Widget-Override.
  • Importiert die onOffice-Kartenfelder breitengrad, laengengrad, showGoogleMap und virtualAddress, sofern im Account lesbar.
  • Karten werden nur ausgegeben, wenn gültige Koordinaten vorhanden sind; die Mehrfachkarte berücksichtigt nur veröffentlichte WordPress-Objekte.

0.10.3

  • Stabilisiert Elementor-Editor: den in 0.10.2 hinzugefügten großen generischen Feld-Repeater im Objekt-Meta-Widget wieder entfernt.
  • Baujahr, Etage, Zustand und Verfügbar-ab bleiben als leichte Schalter im Objekt-Meta erhalten.
  • Baujahr, Etage und Zustand bleiben im Objektkopf zuschaltbar.
  • Semantische onOffice-Wertübersetzungen (z. B. luftwp → Luft-Wasser-Wärmepumpe) bleiben erhalten.

0.10.7

  • Energieausweis rendert keine leeren Zeilen mehr (z. B. 0000-00-00 bei „Gültig bis“).
  • Kein Fallback mehr vom Energieausweis-Baujahr auf das allgemeine Objekt-Baujahr.
  • Farbskala wird nur noch angezeigt, wenn eine Energieklasse vorhanden oder aus einem echten Kennwert ableitbar ist.
  • Platzhalter-/Nullwerte werden nach der Formatierung vollständig ausgeblendet.

0.10.6

  • Ausstattungs-Widget: Leere onOffice-Multiparkinglot-Strukturen werden nicht mehr als „Stellplätze“ ausgegeben. Ein Stellplatz-Eintrag erscheint nur, wenn mindestens ein Stellplatz mit Count > 0 vorhanden ist.
assets/css/toolkit.cssCSS
.fresh-oo-field{display:flex;align-items:center;gap:12px}.fresh-oo-field__body{display:flex;flex-direction:column;min-width:0}.fresh-oo-field__label,.fresh-oo-field-group__label,.fresh-oo-facts__label{font-size:.82em;opacity:.72}.fresh-oo-field__value,.fresh-oo-field-group__value,.fresh-oo-facts__value{font-weight:700}.fresh-oo-field__icon,.fresh-oo-field-group__icon,.fresh-oo-features__icon,.fresh-oo-facts__icon,.fresh-oo-address__icon{display:inline-flex;flex:0 0 auto}.fresh-oo-field__icon svg,.fresh-oo-field-group__icon svg,.fresh-oo-features__icon svg,.fresh-oo-facts__icon svg,.fresh-oo-address__icon svg{width:1em;height:1em;fill:currentColor}.fresh-oo-field-group,.fresh-oo-facts{display:grid;gap:16px}.fresh-oo-field-group__item,.fresh-oo-facts__item{display:flex;align-items:center;gap:12px;min-width:0}.fresh-oo-field-group__text,.fresh-oo-facts__text{display:flex;flex-direction:column;min-width:0}.fresh-oo-facts--minimal .fresh-oo-facts__item{padding:0!important;background:transparent!important;border:0!important;box-shadow:none!important}.fresh-oo-facts--value_top .fresh-oo-facts__item{flex-direction:column;align-items:flex-start}.fresh-oo-facts--value_top .fresh-oo-facts__text{flex-direction:column-reverse}.fresh-oo-facts--value_top .fresh-oo-facts__value{font-size:1.5em}.fresh-oo-features{list-style:none!important;margin:0!important;padding:0!important;display:grid;gap:12px}.fresh-oo-features__item{display:flex;align-items:center;gap:10px}.fresh-oo-features__label small{opacity:.7}.fresh-oo-price{display:flex;flex-direction:column;gap:4px}.fresh-oo-price__type{font-size:.82em;text-transform:uppercase;letter-spacing:.08em;opacity:.72}.fresh-oo-price__value{font-size:clamp(1.75rem,4vw,3rem);font-weight:700;line-height:1.05}.fresh-oo-price__value small{font-size:.38em;font-weight:500;opacity:.72}.fresh-oo-price__meta{font-size:.9em;opacity:.75}.fresh-oo-detail{display:grid;grid-template-columns:1fr;gap:2rem}.fresh-oo-detail--sections-2 .fresh-oo-detail{grid-template-columns:repeat(2,minmax(0,1fr));align-items:start}.fresh-oo-detail__section{margin:0}.fresh-oo-detail__heading{margin:0 0 .55rem}.fresh-oo-detail__list{margin:0}.fresh-oo-detail__row{display:flex;justify-content:space-between;gap:1.2rem;border-bottom:1px solid rgba(0,0,0,.1);padding:12px 0}.fresh-oo-detail__label{font-weight:500;margin:0;opacity:.72}.fresh-oo-detail__value{margin:0;text-align:right;font-weight:600;word-break:break-word}.fresh-oo-detail--cards .fresh-oo-detail__list{display:grid;gap:8px}.fresh-oo-detail--cards .fresh-oo-detail__row{border:1px solid rgba(0,0,0,.08);padding:12px 14px;border-radius:8px}.fresh-oo-detail--clean .fresh-oo-detail__row{border:0;padding:7px 0}.fresh-oo-energy{--fresh-oo-energy-marker:#17211d}.fresh-oo-energy__title{margin:0 0 1rem}.fresh-oo-energy__metric{display:flex;align-items:baseline;flex-wrap:wrap;gap:6px 10px;margin:0 0 15px}.fresh-oo-energy__metric-value{font-size:clamp(2rem,5vw,3.25rem);font-weight:750;line-height:1}.fresh-oo-energy__metric-unit{opacity:.7}.fresh-oo-energy__metric-class{font-size:.82em;font-weight:700;padding:4px 8px;border-radius:999px;background:rgba(0,0,0,.06)}.fresh-oo-energy__scale{display:grid;grid-template-columns:repeat(9,1fr);gap:3px;align-items:end;margin:8px 0 8px}.fresh-oo-energy__class{position:relative;display:flex;align-items:center;justify-content:center;height:34px;color:#111;font-size:12px;clip-path:polygon(0 0,85% 0,100% 50%,85% 100%,0 100%,12% 50%)}.fresh-oo-energy__class:first-child{clip-path:polygon(0 0,85% 0,100% 50%,85% 100%,0 100%)}.fresh-oo-energy__class--aplus{background:#1ca64a}.fresh-oo-energy__class--a{background:#59b847}.fresh-oo-energy__class--b{background:#9acb3b}.fresh-oo-energy__class--c{background:#d1dc35}.fresh-oo-energy__class--d{background:#ffdd32}.fresh-oo-energy__class--e{background:#f6b52b}.fresh-oo-energy__class--f{background:#ef8b29}.fresh-oo-energy__class--g{background:#e85727}.fresh-oo-energy__class--h{background:#d52d27;color:#fff}.fresh-oo-energy__class.is-active{outline:2px solid var(--fresh-oo-energy-marker);outline-offset:2px;z-index:1}.fresh-oo-energy__marker-track{position:relative;height:18px;margin:0 0 12px;background:linear-gradient(90deg,#1ca64a 0%,#59b847 16%,#d1dc35 35%,#ffdd32 48%,#f6b52b 60%,#ef8b29 72%,#e85727 85%,#d52d27 100%);border-radius:999px;opacity:.3}.fresh-oo-energy__marker-track span{position:absolute;top:-3px;width:3px;height:24px;background:var(--fresh-oo-energy-marker);transform:translateX(-50%);border-radius:4px}.fresh-oo-energy__details{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 24px;margin:0}.fresh-oo-energy__detail{display:flex;justify-content:space-between;gap:16px;padding:10px 0;border-bottom:1px solid rgba(0,0,0,.1)}.fresh-oo-energy__detail dt{opacity:.7}.fresh-oo-energy__detail dd{margin:0;text-align:right}.fresh-oo-energy--compact .fresh-oo-energy__details,.fresh-oo-energy--scale .fresh-oo-energy__details,.fresh-oo-energy--scale .fresh-oo-energy__metric{display:none}.fresh-oo-property-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px}.fresh-oo-property-meta__item{display:inline-flex;align-items:center;padding:6px 10px;border-radius:999px;background:rgba(0,0,0,.05)}.fresh-oo-property-meta--inline .fresh-oo-property-meta__item{padding:0;background:transparent;border:0!important;border-radius:0!important}.fresh-oo-property-meta__separator{opacity:.45}.fresh-oo-address{display:flex;align-items:flex-start;gap:10px}.fresh-oo-address__text{display:flex;flex-direction:column}.fresh-oo-field,.fresh-oo-field-group__item,.fresh-oo-facts__item,.fresh-oo-features__item,.fresh-oo-price,.fresh-oo-energy,.fresh-oo-address{transition:border-color .2s ease,box-shadow .2s ease,background-color .2s ease}@media(max-width:767px){.fresh-oo-detail__row{gap:12px}.fresh-oo-energy__scale{gap:1px}.fresh-oo-energy__class{font-size:10px;height:30px}.fresh-oo-energy__details{grid-template-columns:1fr}}
/* v0.9.2 */
.fresh-oo-property-meta__item{gap:7px}.fresh-oo-property-meta__icon{display:inline-flex;align-items:center;justify-content:center}.fresh-oo-property-meta__icon svg{width:1em;height:1em;fill:currentColor}.fresh-oo-property-meta--stacked .fresh-oo-property-meta{flex-direction:column;align-items:flex-start}.fresh-oo-property-meta--stacked .fresh-oo-property-meta__item{width:100%}
.fresh-oo-address__icon{align-items:center;justify-content:center}.fresh-oo-address__text a{color:inherit;text-decoration:inherit}.fresh-oo-address--inline .fresh-oo-address{align-items:center}.fresh-oo-address--inline .fresh-oo-address__text{display:block}
.fresh-oo-property-header{display:flex;flex-direction:column;gap:14px}.fresh-oo-property-header__main{display:flex;align-items:flex-end;justify-content:space-between;gap:24px}.fresh-oo-property-header__content{min-width:0}.fresh-oo-property-header__title{margin:0;line-height:1.05}.fresh-oo-property-header__location{margin-top:8px;opacity:.72}.fresh-oo-property-header__badges{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}.fresh-oo-property-header__badge{display:inline-flex;align-items:center;padding:6px 10px;border-radius:999px;background:rgba(0,0,0,.05)}.fresh-oo-property-header__price{display:flex;flex-direction:column;align-items:flex-end;flex:0 0 auto}.fresh-oo-property-header__price-label{font-size:.78em;text-transform:uppercase;letter-spacing:.08em;opacity:.65}.fresh-oo-property-header__price-meta{font-size:.9em;line-height:1.35;opacity:.72;margin-top:5px}.fresh-oo-property-header__price-value{font-size:clamp(1.8rem,4vw,3.2rem);font-weight:700;line-height:1.05}.fresh-oo-header--stacked .fresh-oo-property-header__main{flex-direction:column;align-items:flex-start}.fresh-oo-header--stacked .fresh-oo-property-header__price{align-items:flex-start}.fresh-oo-header--centered .fresh-oo-property-header__main{flex-direction:column;align-items:center;text-align:center}.fresh-oo-header--centered .fresh-oo-property-header__badges{justify-content:center}.fresh-oo-header--centered .fresh-oo-property-header__price{align-items:center}
@media(max-width:767px){.fresh-oo-header--split .fresh-oo-property-header__main{flex-direction:column;align-items:flex-start}.fresh-oo-header--split .fresh-oo-property-header__price{align-items:flex-start}.fresh-oo-property-header__price-value{font-size:clamp(1.6rem,10vw,2.5rem)}}
.fresh-oo-status-badge{display:inline-flex;align-items:center;gap:.45em;padding:.45em .8em;border-radius:999px;font-weight:700;line-height:1.15}.fresh-oo-status-badge__icon{display:inline-flex}.fresh-oo-status-badge__icon svg{width:.75em;height:.75em;fill:currentColor}
/* v0.9.7 property image */
.fresh-oo-property-image{position:relative;display:inline-block;margin:0;overflow:hidden;vertical-align:top}.fresh-oo-property-image__link{display:block;color:inherit}.fresh-oo-property-image__img{display:block;width:100%;max-width:100%;height:auto}.fresh-oo-property-image__badge-wrap{--fresh-oo-badge-x:16px;--fresh-oo-badge-y:16px;position:absolute;z-index:3;pointer-events:none}.fresh-oo-property-image__badge-wrap--top-left{top:var(--fresh-oo-badge-y);left:var(--fresh-oo-badge-x)}.fresh-oo-property-image__badge-wrap--top-right{top:var(--fresh-oo-badge-y);right:var(--fresh-oo-badge-x)}.fresh-oo-property-image__badge-wrap--bottom-left{bottom:var(--fresh-oo-badge-y);left:var(--fresh-oo-badge-x)}.fresh-oo-property-image__badge-wrap--bottom-right{bottom:var(--fresh-oo-badge-y);right:var(--fresh-oo-badge-x)}.fresh-oo-property-image__badge{display:inline-flex;align-items:center;padding:.45em .8em;border-radius:999px;font-weight:700;line-height:1.15}
/* Object-specific onOffice inquiry form */
.fresh-oo-inquiry{display:flex;flex-direction:column;gap:20px}
.fresh-oo-inquiry__heading{margin:0}
.fresh-oo-inquiry__context{margin:0}
.fresh-oo-inquiry__form .oo-form{margin:0}

Architecture

High-level modules detected from the verified public snapshot. Protected implementation details are intentionally omitted.

includesmodule
assetsmodule
snapshotsmodule

Technology stack

PHPCSSMarkdownJavaScript
PHP86.6%
CSS5.9%
Markdown4.7%
JavaScript2.7%