Opens in a new tab
 /* update variables when header is on dark background*/
.on-dark-bg {
   --header-bg: var(--current-header-bg);
   --chevron-clr: white;
   --menu-item-clr: white;
   --menu-item-hover-bg: #172235;
   --menu-item-hover-clr: #bc92e6;
   --menu-toggle-clr: var(--menu-item-clr);
   --dropdown-content-border: solid 1px rgb(220 220 220 / 20%);
   --mobile-menu-bg: var(--header-bg);
 }

 .on-light-bg {
   --menu-item-clr: black;
   /* update variables when header is on light background*/
 }


 /* update variable when on dark or light background */
 .on-dark-bg,
 .on-light-bg {
   --overlay-header-bg-active: var(--current-header-bg);
   --dropdown-content-bg: var(--current-header-bg);
 }

 .on-video-section {
   /* update variables when header is on video section*/
   --menu-item-clr: white;
   --chevron-clr: white;
   --menu-item-hover-bg: rgb(0 0 0 / 30%);
   --menu-item-hover-clr: #bc92e6;
   --dropdown-content-bg: rgb(0 0 0 / 70%);
   --overlay-header-bg: rgb(0 0 0 / 25%);
   --overlay-header-bg-active: var(--dropdown-content-bg);
   --dropdown-content-border: solid 1px rgb(220 220 220 / 20%);
   --current-header-bg: rgb(0 0 0 / 14%) !important;
   --header-bg: rgb(0 0 0 / 70%);
   --menu-toggle-clr: white;
   --mobile-menu-bg: rgb(0 0 0 / 95%);
   --menu-cta-border: var(--dropdown-content-border)
 }


 .on-hero-section {
   /* update variables when header is on hero section*/
 }

 /* header bg blure when on video section */
 html:not(.dwc-mobile) .dwc-nest-header.on-video-section {
   backdrop-filter: blur(var(--overlay-header-blur));
 }

 /* overlay header border when on video section or dark background*/
 .dwc-nest-header:is(.on-dark-bg, .on-video-section)[data-overlay-header="true"] {
   border: 1px solid rgba(255, 255, 255, 0.2);
 }

 /* header bottom border when on dark background or video section*/
 .dwc-nest-header:is(.on-dark-bg, .on-video-section) {
   border-bottom: 1px solid rgba(255, 255, 255, 0.2);
 }


 /* logo color when on dark background*/
 .on-dark-bg .dwc-nest-menu__logo path {
   fill: white;
 }

 /* logo color when on light background*/
 .on-dark-bg .dwc-nest-menu__logo path {
   /*define svg fill when logo is on light background */
 }

 /* logo color when on video background*/
 .on-video-section .dwc-nest-menu__logo path {
   fill: white;
 }

/*custom */

.on-dark-bg .mega-menu-magic__menu-icon-large{
   background-color: var(--current-header-bg);
    fill: #bc92e6;
    color: #bc92e6;
}

.on-video-section .mega-menu-magic__menu-icon-large{
   background-color: var(--current-header-bg);
    fill: #bc92e6;
    color: #bc92e6;
}

.on-video-section .mega-menu-magic__dropdown-title,
.on-dark-bg .mega-menu-magic__dropdown-title{
    color: rgb(210 210 210);   
}
// Constants
const BREAKPOINT_DESKTOP = 0;
const DEBOUNCE_DELAY = 50;

// Configuration object for all header-related selectors
const HEADER_CONFIG = {
  // Main header element
  headerElement: '.dwc-nest-header',
  // Wrapper element selectors (can be classes, IDs, or data attributes)
  wrapperSelectors: [
    // '.dwc-nest-header__container'
  ],
  // Elements to monitor for header styling (can include any CSS selector)
  // Default monitors sections, but you can add footer, divs, or any element
  monitoredElements: 'section, [data-header-zone]',
  // Store original header background color
  originalHeaderBgColor: null
};

// Unified section type configuration
// Add new data attributes here - they will be automatically mapped to header classes
const SECTION_TYPES = {
  'data-hero': 'on-hero-section',
  'data-video': 'on-video-section',
  'data-custom': 'on-custom-section',
  'data-sticky': 'on-media-section'
  // Add new: 'data-feature': 'on-feature-section'
};

// Configuration for excluded sections
const EXCLUSION_CONFIG = {
  // Data attribute that identifies sections to exclude from header styling
  sectionAttribute: 'data-exclude-header'
};

// Text color classes
const TEXT_CLASSES = {
  light: 'on-dark-bg',
  dark: 'on-light-bg'
};

// Generate classes to remove dynamically from SECTION_TYPES and text classes
const ALL_CLASSES_TO_REMOVE = [
  // Add all header classes from section types
  ...Object.values(SECTION_TYPES),
  // Add text color classes
  TEXT_CLASSES.light,
  TEXT_CLASSES.dark
];

// Performance optimization: Cache DOM elements and computed values
const CACHE = {
  headerElement: null,
  wrapperElement: null,
  sections: [],
  sectionsData: new Map(),
  colorCache: new Map(),
  tempColorElement: null,
  lastKnownSection: null,
  isUpdating: false,
  pendingColorUpdate: false
};

// Initialize cache
function initializeCache() {
  // Cache header elements
  CACHE.headerElement = document.querySelector(HEADER_CONFIG.headerElement);
  
  // Try each wrapper selector until one is found
  for (const selector of HEADER_CONFIG.wrapperSelectors) {
    CACHE.wrapperElement = document.querySelector(selector);
    if (CACHE.wrapperElement) break;
  }
  
  // Cache sections and their positions
  CACHE.sections = Array.from(document.querySelectorAll(HEADER_CONFIG.monitoredElements));
  
  // Create reusable element for color calculations
  CACHE.tempColorElement = document.createElement('div');
  CACHE.tempColorElement.style.position = 'absolute';
  CACHE.tempColorElement.style.visibility = 'hidden';
  CACHE.tempColorElement.style.pointerEvents = 'none';
  document.body.appendChild(CACHE.tempColorElement);
  
  // Cache section metadata
  updateSectionsCache();
}

// Update sections cache (call when DOM changes)
function updateSectionsCache() {
  CACHE.sections = Array.from(document.querySelectorAll(HEADER_CONFIG.monitoredElements));
  CACHE.sectionsData.clear();
  
  CACHE.sections.forEach((section, index) => {
    const sectionData = {
      index,
      isExcluded: section.hasAttribute(EXCLUSION_CONFIG.sectionAttribute)
    };
    
    // Dynamically check for all section types defined in SECTION_TYPES
    Object.keys(SECTION_TYPES).forEach(attribute => {
      sectionData[attribute] = section.hasAttribute(attribute);
    });
    
    CACHE.sectionsData.set(section, sectionData);
  });
}

// Function to remove all section classes from :root only
function removeAllSectionClasses() {
  const rootElement = document.documentElement;
  
  // Remove classes from :root only
  rootElement.classList.remove(...ALL_CLASSES_TO_REMOVE);
}

// Function to update the CSS variable on :root
function updateRootBackgroundVariable(color) {
  document.documentElement.style.setProperty('--current-header-bg', color);
}

// Function to apply classes to :root only
function applyClassesToRoot(headerClass, textClass) {
  const rootElement = document.documentElement;
  
  // Apply header class to :root only
  if (headerClass) {
    rootElement.classList.add(headerClass);
  }
  
  // Apply text class to :root only
  if (textClass) {
    rootElement.classList.add(textClass);
  }
}

// Optimized color conversion using cached temp element
function getRGBValues(color) {
  const cacheKey = color;
  if (CACHE.colorCache.has(cacheKey)) {
    return CACHE.colorCache.get(cacheKey);
  }
  
  CACHE.tempColorElement.style.color = color;
  const computedColor = window.getComputedStyle(CACHE.tempColorElement).color;
  
  // Extract RGB values
  const match = computedColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
  const result = match ? {
    r: parseInt(match[1]),
    g: parseInt(match[2]),
    b: parseInt(match[3])
  } : { r: 255, g: 255, b: 255 };
  
  // Cache the result
  CACHE.colorCache.set(cacheKey, result);
  return result;
}

// Function to check if a background color is transparent or empty
function isBackgroundTransparent(color) {
  if (!color) return true;
  
  const transparentValues = [
    'transparent',
    'rgba(0, 0, 0, 0)',
    'rgba(0,0,0,0)',
    'initial',
    'inherit',
    ''
  ];
  
  return transparentValues.includes(color.toLowerCase().replace(/\s/g, ''));
}

// Function to determine if a color is dark or light
function isColorDark(color) {
  if (color === 'transparent' || color === 'rgba(0, 0, 0, 0)') {
    return false;
  }
  
  const rgb = getRGBValues(color);
  const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
  return luminance < 0.5;
}

// Optimized section detection using cached data
function getCurrentSection() {
  if (!CACHE.headerElement || CACHE.sections.length === 0) return null;
  
  const headerHeight = CACHE.headerElement.offsetHeight;
  
  // Quick check if we're still in the same section
  if (CACHE.lastKnownSection) {
    const rect = CACHE.lastKnownSection.getBoundingClientRect();
    if (rect.top <= headerHeight && rect.bottom > headerHeight) {
      return CACHE.lastKnownSection;
    }
  }
  
  // Binary search would be ideal here, but simple loop is sufficient for most cases
  for (const section of CACHE.sections) {
    const rect = section.getBoundingClientRect();
    if (rect.top <= headerHeight && rect.bottom > headerHeight) {
      CACHE.lastKnownSection = section;
      return section;
    }
  }
  
  const firstSection = CACHE.sections[0] || null;
  CACHE.lastKnownSection = firstSection;
  return firstSection;
}

// Function to get computed background color with caching
function getComputedBackgroundColor(element) {
  const cacheKey = element;
  if (CACHE.colorCache.has(cacheKey)) {
    return CACHE.colorCache.get(cacheKey);
  }
  
  const bgColor = window.getComputedStyle(element).backgroundColor;
  CACHE.colorCache.set(cacheKey, bgColor);
  return bgColor;
}

// Function to initialize original header background color
function initializeOriginalHeaderBgColor() {
  if (CACHE.headerElement) {
    HEADER_CONFIG.originalHeaderBgColor = window.getComputedStyle(CACHE.headerElement).backgroundColor;
  }
}

// Function to determine header style configuration based on section
function determineHeaderConfig(section) {
  if (!section) return null;
  
  const sectionData = CACHE.sectionsData.get(section);
  if (!sectionData) return null;
  
  // If section is excluded, return null to skip styling
  if (sectionData.isExcluded) {
    return null;
  }
  
  // Dynamically check for any section type defined in SECTION_TYPES
  for (const [attribute, headerClass] of Object.entries(SECTION_TYPES)) {
    if (sectionData[attribute]) {
      return {
        backgroundColor: null,
        headerClass: headerClass,
        needsWhiteText: null,
        isSpecialSection: true
      };
    }
  }
  
  // Get the actual background color of the section
  const sectionBgColor = getComputedBackgroundColor(section);
  
  if (isBackgroundTransparent(sectionBgColor)) {
    return {
      backgroundColor: HEADER_CONFIG.originalHeaderBgColor || 'rgb(255, 255, 255)',
      headerClass: null,
      needsWhiteText: isColorDark(HEADER_CONFIG.originalHeaderBgColor || 'rgb(255, 255, 255)'),
      isSpecialSection: false
    };
  }
  
  const needsWhiteText = isColorDark(sectionBgColor);
  
  return {
    backgroundColor: sectionBgColor,
    headerClass: null,
    needsWhiteText: needsWhiteText,
    isSpecialSection: false
  };
}

// Function to apply styles (background color to header, classes to :root only)
function applyHeaderStyles(config) {
  if (!CACHE.headerElement || !config) return;
  
  const elementsToStyle = [CACHE.headerElement, CACHE.wrapperElement].filter(Boolean);
  
  // Use requestAnimationFrame for smooth visual updates
  requestAnimationFrame(() => {
    // First, remove all section classes and text classes from :root only
    removeAllSectionClasses();
    
    // Update the root CSS variable with background color
    if (config.backgroundColor !== null) {
      const appliedBgColor = config.backgroundColor || '';
      updateRootBackgroundVariable(appliedBgColor);
    } else {
      updateRootBackgroundVariable('');
    }
    
    // Determine text class to apply
    const textClass = config.needsWhiteText !== null 
      ? (config.needsWhiteText ? TEXT_CLASSES.light : TEXT_CLASSES.dark)
      : null;
    
    // Apply classes to :root only
    applyClassesToRoot(config.headerClass, textClass);
    
    // Handle background color on header elements only
    elementsToStyle.forEach(element => {
      if (config.backgroundColor !== null) {
        const appliedBgColor = config.backgroundColor || '';
        element.style.backgroundColor = appliedBgColor;
      } else {
        element.style.backgroundColor = '';
      }
    });
    
    // For special sections, allow CSS to apply first, then get computed background color
    if (config.isSpecialSection && config.headerClass) {
      // Use setTimeout(0) to ensure CSS has been applied, but batch multiple calls
      if (!CACHE.pendingColorUpdate) {
        CACHE.pendingColorUpdate = true;
        setTimeout(() => {
          // Process all elements that need color updates in this batch
          elementsToStyle.forEach(el => {
            // Check if element has any of the section classes (though they're not applied anymore)
            const hasSectionClass = Object.values(SECTION_TYPES).some(className => 
              el.classList.contains(className)
            );
            
            if (hasSectionClass) {
              const computedBgColor = getComputedBackgroundColor(el);
              updateRootBackgroundVariable(computedBgColor);
            }
          });
          CACHE.pendingColorUpdate = false;
        }, 50);
      }
    }
    
    CACHE.isUpdating = false;
  });
}

// Throttled update function using requestAnimationFrame
function updateHeaderStyles() {
  // Prevent multiple updates in the same frame
  if (CACHE.isUpdating) return;
  
  // Apply only on screens larger than the breakpoint
  if (window.innerWidth <= BREAKPOINT_DESKTOP) {
    return;
  }
  
  CACHE.isUpdating = true;
  
  const currentSection = getCurrentSection();
  if (!currentSection) {
    CACHE.isUpdating = false;
    return;
  }
  
  const headerConfig = determineHeaderConfig(currentSection);
  if (!headerConfig) {
    CACHE.isUpdating = false;
    return;
  }
  
  applyHeaderStyles(headerConfig);
}

// Debounce function for resize events (less frequent)
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

// RAF-based throttle for scroll events
let rafId = null;
function throttleWithRAF(func) {
  return function(...args) {
    if (rafId) return;
    
    rafId = requestAnimationFrame(() => {
      func.apply(this, args);
      rafId = null;
    });
  };
}

// Initialize everything
function initialize() {
  initializeCache();
  initializeOriginalHeaderBgColor();
  updateHeaderStyles();
}

// Cleanup function
function cleanup() {
  if (CACHE.tempColorElement && CACHE.tempColorElement.parentNode) {
    CACHE.tempColorElement.parentNode.removeChild(CACHE.tempColorElement);
  }
  if (rafId) {
    cancelAnimationFrame(rafId);
  }
}

// Initialize on page load
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', initialize);
} else {
  initialize();
}

// Create optimized event handlers
const throttledUpdateHeaderStyles = throttleWithRAF(updateHeaderStyles);
const debouncedUpdateHeaderStyles = debounce(() => {
  updateSectionsCache(); // Refresh cache on resize
  updateHeaderStyles();
}, DEBOUNCE_DELAY);

// Add event listeners with passive option for better performance
window.addEventListener('scroll', throttledUpdateHeaderStyles, { passive: true });
window.addEventListener('resize', debouncedUpdateHeaderStyles, { passive: true });

// Cleanup on page unload
window.addEventListener('beforeunload', cleanup);

Politica de Confidențialitate

Regulamentul General privind Protecția Datelor (GDPR) a fost implementat în întreaga Uniune Europeană începând cu 25 mai 2018, punând un accent deosebit pe protejarea drepturilor și confidențialității datelor cu caracter personal ale persoanelor fizice. În cadrul Școala Primară NANNY, ne angajăm să respectăm în mod riguros prevederile GDPR și să asigurăm că datele cu caracter personal ale copiilor, angajaților și părinților sunt procesate într-un mod transparent, legal și sigur.

1. Cine suntem

Suntem Școala Primară NANNY, dedicat furnizării unor servicii educaționale de înaltă calitate și promovării unui mediu de învățare sigur și stimulativ pentru toți participanții.

2. Ce înseamnă date cu caracter personal?

Datele cu caracter personal includ orice informații care pot fi utilizate pentru a identifica direct sau indirect o persoană fizică, cum ar fi numele, adresa, numărul de telefon, adresa de email, fotografiile și alte informații similare.

3. Ce inseamna procesarea datelor cu caracter personal?

„Procesarea” înseamnă orice operațiune sau ansamblu de operațiuni efectuate cu date cu caracter personal sau cu seturi de date cu caracter personal cu sau fără utilizarea de mijloace automate, cum ar fi colectarea, înregistrarea, organizarea, structurarea, stocarea, adaptarea sau modificarea, extragerea, consultarea, utilizarea, divulgarea prin transmitere, diseminarea sau punerea la dispoziție în alt mod, alinierea sau combinarea, restricționarea, ștergerea sau distrugerea.

4. Scopurile și temeiurile prelucrării datelor

Procesăm datele dumneavoastră cu caracter personal în principal în următoarele
scopuri:
a. Încheierea și executarea contractelor de învățământ: Procesăm datele pentru administrarea învățământului, gestionarea activităților școlare și extracurriculare și îndeplinirea obligațiilor contractuale.
b. Respectarea obligațiilor legale și reglementărilor educaționale: Procesăm datele în conformitate cu legislația educațională aplicabilă și cu cerințele autorităților de reglementare.
c. Comunicarea cu părinții și tutorele legali: Pentru a menține o comunicare eficientă și transparentă între instituție și părinți, procesăm datele de contact și alte informații relevante.
d. Ofertarea de servicii educaționale și informaționale si promovarea Grupului: Procesăm datele pentru a vă furniza informații despre serviciile noastre,  evenimente școlare și alte activități relevante si pentru promovarea Școala Primară NANNY.
e. Administrarea activităților școlare și extracurriculare: Procesăm datele pentru organizarea și gestionarea activităților educaționale, precum și a activităților
extracurriculare.
f. Asigurarea securitatii fizice: Procesăm datele pentru a asigura securitatea fizica a copiilor si cadrelor didactice din institutiile noastre de invatamant.

5. Tipurile de date procesate

  • Procesăm diverse categorii de date cu caracter personal, inclusiv, dar fără a se limita la:  Datele personale ale elevilor: Nume, dată și loc de naștere, adresa, numărul de telefon, adresa de email, informații academice, informații  medicale si sexul elevului, fotografii etc.
  • Datele personale ale angajaților: Nume, adresă, număr de telefon, adresa de email, informații legate de angajare, informații financiare, datele din cartea de identitate, studii, fotografii, etc.
  • Datele personale ale părinților și tutorelor legali: Nume, adresa, număr de telefon, adresa de email, informații de contact, carte de identitate si certificate de ecasatorie, fotografii, etc.
  • Pentru vizitatorii website-ului nostru: datele personale colectate prin intermediul cookie-urilor, adresa IP, Preferințele și comportamentul de navigare pe website, datele din formularele de contact, precum nume, adresa, email, telefon, date despre copil precum nume, sex, data nasterii, date academice, etc.

6. Procesarea datelor și securitatea informațiilor

Ne angajăm să procesăm datele dumneavoastră cu caracter personal într-un mod sigur și confidențial, utilizând măsuri de securitate tehnice și organizaționale adecvate pentru a proteja împotriva accesului neautorizat, pierderii sau deteriorării datelor.

7. Principii pentru procesarea datelor cu caracter personal

Pentru a asigura protecția și confidențialitatea datelor cu caracter personal ale
utilizatorilor noștri, instituția noastră respectă cu strictețe următoarele principii:

  • Legalitate, echitate și transparență: Toate datele cu caracter personal sunt procesate în conformitate cu legislația aplicabilă și într-un mod corect și transparent pentru subiecții datelor.
  • Scopuri specificate, explicite și legitime: Colectăm și procesăm datele cu caracter personal doar în scopuri clare, explicite și legitime, și nu le utilizăm ulterior într-un mod incompatibil cu aceste scopuri.
  • Minimizarea datelor: Colectăm doar datele strict necesare pentru îndeplinirea scopurilor stabilite și ne asigurăm că acestea sunt relevante și proporționale în raport cu scopurile respective.
  • Exactitate și actualizare: Ne străduim să păstrăm datele cu caracter personal precise și actualizate, iar dacă este necesar, luăm măsuri pentru corectarea  sau actualizarea acestora.
  • Limitarea stocării: Datele cu caracter personal sunt păstrate doar pentru perioada necesară îndeplinirii scopurilor pentru care au fost colectate.
  • Integritate, confidențialitate și disponibilitate: Ne angajăm să procesăm datele cu caracter personal într-un mod care să asigure integritatea, confidențialitatea și disponibilitatea acestora, protejându-le împotriva accesului neautorizat, pierderii sau distrugerii.

8. Transferul datelor către terțe părți

În anumite circumstanțe, putem divulga sau transfera datele dumneavoastră cu caracter personal către persoane afiliate si terțe părți, inclusiv furnizorii de servicii educaționale, autoritățile de reglementare sau alte entități autorizate conform legii. În toate cazurile, ne asigurăm că transferul datelor este efectuat conform prevederilor GDPR și că se iau măsuri adecvate pentru protejarea confidențialității datelor.

9. Drepturile dumneavoastră

Conform prevederilor GDPR, aveți dreptul de a accesa, rectifica, șterge sau restricționa procesarea datelor dumneavoastră cu caracter personal. Aveți, de asemenea, dreptul de a obiecta la prelucrarea datelor sau de a solicita transferul acestora. Pentru a exercita aceste drepturi sau pentru orice întrebări sau solicitări legate de datele dumneavoastră personale, vă rugăm să ne contactați folosind detaliile de contact mentionate in acest website.

10. Actualizări ale politicii

Această politică de confidențialitate poate fi actualizată periodic pentru a reflecta
modificările aduse legislației sau practicilor noastre de protecție a datelor. Vă încurajăm să verificați această politică în mod regulat pentru a fi la curent cu cele mai recente informații.

11. Contact pentru protecția datelor

Pentru a asigura conformitatea cu prevederile GDPR și pentru a răspunde oricăror întrebări sau solicitări legate de protecția datelor cu caracter personal, vă stăm la dispoziție pentru orice nelămurire sau solicitare. Puteți să ne contactați prin datele de contact din cadrul website-ului.

LOGO Nanny

Școala NANNY

Răspundem, de obicei, în 3 minute.

  • Școala NANNY

    Salut,
    Cu ce te pot ajuta?

  • Școala NANNY

    Ia legătura cu noi chiar acum!