/* ============================================================================
   CHROME — the builder's own controls.

   Loaded AFTER the active theme's stylesheets (see the load-order block in
   Public/Page.aspx), which is the whole point: a theme owns the look of the
   site, but it must not be able to render the language picker, the dark/light
   switch or the admin link unreadable. Ordering settles that, so nothing in
   here needs !important or specificity games to win.

   Colours are stated outright instead of inherited. Inheriting is what broke
   this before — the block landed on whatever background the theme's header
   happened to use and came out grey-on-grey.

   Everything is driven by two variables so a theme CAN still restyle the
   controls deliberately, by setting --chrome-* on :root, without being able
   to break them by accident.
   ============================================================================ */

/* Component tokens — thin aliases over the semantic tokens in tokens.css.
   There is NO second set of values for dark mode: the semantic tokens already
   flipped, so these follow automatically. A theme can still restyle the
   controls on purpose by redefining --chrome-* on :root. */
:root {
    --chrome-bg: var(--bg-surface);
    --chrome-bg-hover: var(--bg-hover);
    --chrome-fg: var(--text-body);
    --chrome-fg-hover: var(--text-heading);
    --chrome-border: var(--border);
    --chrome-border-hover: var(--border-strong);
    --chrome-accent: var(--accent);
    --chrome-menu-bg: var(--bg-surface);
    --chrome-menu-shadow: var(--shadow-menu);
    --chrome-radius: 999px;
    --chrome-height: 36px;
}

/* ---------------------------------------------------------------------------
   Placement: the trio lives inside the main menu as its last item, so it keeps
   one fixed home across themes and collapses with the menu on mobile.
   --------------------------------------------------------------------------- */
.menu-utility {
    display: flex;
    align-items: center;
    list-style: none;
    position: relative;
    z-index: 1200;
}

.utility-menu {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-inline-start: 12px;
}

/* A dropdown inside a header must not be clipped: theme headers commonly set
   overflow:hidden on these wrappers, which would cut the language menu off. */
.menu-utility,
.utility-menu,
.navbar-nav,
.navbar-collapse,
#main-navigation,
#main-navigation #menu,
.header .nav-item,
.header .menu-wrap,
.header .top-header {
    overflow: visible;
}

/* ---------------------------------------------------------------------------
   The three controls share one pill so they read as a single unit.
   --------------------------------------------------------------------------- */
.lang-dropdown-toggle,
.theme-toggle-btn,
.admin-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: var(--chrome-height);
    padding: 0 14px;
    border: 1px solid var(--chrome-border);
    border-radius: var(--chrome-radius);
    background: var(--chrome-bg);
    color: var(--chrome-fg);
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}

.lang-dropdown-toggle:hover,
.theme-toggle-btn:hover,
.admin-link:hover,
.lang-dropdown-toggle:focus-visible,
.theme-toggle-btn:focus-visible,
.admin-link:focus-visible {
    background: var(--chrome-bg-hover);
    border-color: var(--chrome-border-hover);
    color: var(--chrome-fg-hover);
}

.lang-dropdown-toggle:focus-visible,
.theme-toggle-btn:focus-visible,
.admin-link:focus-visible {
    outline: 2px solid var(--chrome-accent);
    outline-offset: 2px;
}

/* Square button for the icon-only dark/light switch. */
.theme-toggle-btn {
    width: var(--chrome-height);
    padding: 0;
}

.lang-dropdown-toggle i,
.admin-link i {
    font-size: 12px;
    opacity: .8;
    color: currentColor;
}

/* The icons and labels are spans/i inside links — make sure a theme's
   "#header a { color: ... }" rule cannot repaint them mid-pill. */
.lang-dropdown-toggle span,
.admin-link span {
    color: currentColor;
}

/* ---------------------------------------------------------------------------
   Language menu. A dropdown, not a pipe-separated list, because the builder is
   meant to take new languages with no layout change.
   --------------------------------------------------------------------------- */
.lang-dropdown { position: relative; }

.lang-dropdown-menu.dropdown-menu {
    min-width: 190px;
    padding: 6px;
    margin-top: 8px;
    background: var(--chrome-menu-bg);
    border: 1px solid var(--chrome-border);
    border-radius: 14px;
    box-shadow: var(--chrome-menu-shadow);
    z-index: 1300;
}

.lang-dropdown-menu .dropdown-item {
    display: block;
    padding: 9px 12px;
    border-radius: 9px;
    font-size: 14px;
    color: var(--chrome-fg);
    text-decoration: none;
}

.lang-dropdown-menu .dropdown-item:hover,
.lang-dropdown-menu .dropdown-item:focus {
    background: var(--chrome-bg-hover);
    color: var(--chrome-fg-hover);
}

.lang-dropdown-menu .dropdown-item.active {
    background: var(--chrome-accent);
    color: #ffffff;
}

/* RTL: open toward the start edge instead of off-screen. */
[dir="rtl"] .lang-dropdown-menu.dropdown-menu {
    right: auto;
    left: 0;
}

/* ---------------------------------------------------------------------------
   Mobile: inside the collapsed menu the trio takes its own full-width row.
   --------------------------------------------------------------------------- */
@media (max-width: 991px) {
    .menu-utility {
        width: 100%;
        padding: 12px 0;
    }
    .utility-menu {
        margin-inline-start: 0;
        justify-content: flex-start;
        flex-wrap: wrap;
    }
}

/* ============================================================================
   ROW ONE — logo, phone/email, social, dark-mode switch.

   Deliberately its own line above the menu: identity and contact on one row,
   navigating the site on the next. Emitted as one unit so a theme places it
   with {{info_bar}} and cannot scatter the pieces.
   ============================================================================ */
.info-bar {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
    padding: 10px 0;
}

.info-bar-logo { display: inline-flex; align-items: center; flex: 0 0 auto; }
.info-bar-logo img { height: var(--logo-height, 44px); width: auto; }

/* 08D3-B. The whole header pinned, for HeaderStyle = fixed.
   The wrapper is emitted only for that value, so this rule has nothing to fight: under
   `sticky` the nav positions itself and no wrapper exists, and under `static` neither does.
   Sticky rather than fixed on purpose — measured, `position: fixed` needs the flow compensated
   by the header's height, and 08D2 made that height author-controlled through LogoHeight, so any
   constant here would be wrong the moment somebody resized their logo. Sticky keeps the space
   and produces identical geometry with nothing to compensate. */
.a1-site-header.is-pinned {
    position: sticky;
    top: 0;
    z-index: 1030;
}

.info-bar-contact {
    display: inline-flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
    font-size: 14px;
    color: var(--chrome-fg);
}
.info-bar-contact span { display: inline-flex; align-items: center; gap: 7px; }
.info-bar-contact i { opacity: .7; }

/* Every control sits together at the far end of the row, in one run: social
   icons, then the dark/light switch, the language picker and the admin link.
   Grouping them means a visitor finds all the controls in a single place. */
.info-bar-actions {
    margin-inline-start: auto;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.info-bar-social {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-inline-end: 4px;
}

/* A theme ancestor may set font-size:0 to kill inline-block gaps (the school
   theme does exactly that on its contact strip). Restate a real size here or
   every label in this row silently collapses to nothing. */
.info-bar,
.info-bar * { font-size: revert; }
.info-bar-contact,
.info-bar-contact span { font-size: 14px; }

/* ============================================================================
   SOCIAL ICONS — each network in its own brand colour.
   ============================================================================ */
.social-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, .10);
    font-size: 15px;
    line-height: 1;
    text-decoration: none;
    transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.social-icon i { color: inherit; }
.social-icon:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0, 0, 0, .18); }

.social-icon-facebook  { color: #1877F2; }
.social-icon-instagram { color: #E1306C; }
.social-icon-linkedin  { color: #0A66C2; }
.social-icon-tiktok    { color: #010101; }
.social-icon-twitter   { color: #000000; }
.social-icon-youtube   { color: #FF0000; }
.social-icon-whatsapp  { color: #25D366; }
.social-icon-snapchat  { color: #FFFC00; text-shadow: 0 0 2px rgba(0,0,0,.35); }
.social-icon-telegram  { color: #26A5E4; }

/* On hover each fills with its own brand colour. Instagram takes the gradient
   its logo actually uses rather than a flat pink. */
.social-icon-facebook:hover  { background: #1877F2; color: #fff; }
.social-icon-instagram:hover { background: linear-gradient(45deg, #F58529, #DD2A7B, #8134AF, #515BD4); color: #fff; }
.social-icon-linkedin:hover  { background: #0A66C2; color: #fff; }
.social-icon-tiktok:hover    { background: #010101; color: #fff; }
.social-icon-twitter:hover   { background: #000000; color: #fff; }
.social-icon-youtube:hover   { background: #FF0000; color: #fff; }
.social-icon-whatsapp:hover  { background: #25D366; color: #fff; }
.social-icon-snapchat:hover  { background: #FFFC00; color: #000; text-shadow: none; }
.social-icon-telegram:hover  { background: #26A5E4; color: #fff; }

html.dark-mode .social-icon {
    background: rgba(255, 255, 255, .10);
    border-color: rgba(255, 255, 255, .18);
}

/* ============================================================================
   Keep the menu visible.

   Theme stylesheets built for a jQuery mobile-menu plugin hide the real nav
   below their breakpoint and expect their own script to clone it elsewhere.
   The builder does not load that script, so the menu — and the language and
   login controls that live inside it — would simply vanish. Bootstrap's
   collapse already handles small screens here.

   MEASURED 2026-08-24 — this rule did not work, for one missing token.

   The theme sheet hides the nav with `display: none !important`
   (UCA-Theme/assets/css/responsive.css:174, inside @media max-width:992px).
   An important declaration beats a normal one no matter which sheet loads
   last, so loading chrome.css after the theme — the mechanism this whole layer
   relies on — could not win here. Measured on the live page: at 360/390/600/
   767/768/769/991/992 the nav computed to `display:none`, height 0, ZERO
   visible links; it only appeared from 993px up. A site with no navigation
   below 993px is not shippable, and no burger exists to replace it.

   So this one declaration is important on purpose. It is scoped to the
   container only: `> ul` deliberately stays normal, because the ≤991 block
   below switches it to flex-wrap and an important here would freeze it as
   block and undo the wrapping.
   ============================================================================ */
#main-navigation {
    display: block !important;
}

#main-navigation > ul {
    display: block;
}

@media (max-width: 991px) {
    #main-navigation > ul {
        display: flex;
        flex-wrap: wrap;
        gap: 4px;
    }
    .info-bar { gap: 12px; }
    .info-bar-social { margin-inline-start: 0; }
}

/* ============================================================================
   DEFAULT SITE FONT — Calibri.

   Declared here rather than in css/vendor/fonts.css because this layer loads
   after the active theme. site.css sets --font-body to Cairo, and theme sheets
   set their own families outright (the school theme forces Poppins/Rubik), so a
   declaration earlier in the cascade never survived.

   Calibri is a Microsoft font and is not redistributable, so it is not shipped:
   local() picks it up on machines that have it, and Carlito — the metric-
   compatible open clone vendored under css/webfonts — covers everyone else.
   The two are metrically identical, so the layout is unchanged either way.

   Arabic: Calibri and Carlito both carry Arabic glyphs, but Cairo/Tajawal read
   better at UI sizes, so RTL keeps them right behind Calibri.
   ============================================================================ */
:root {
    --font-body: "Calibri Local", "Carlito", "Cairo", "Tajawal", "Segoe UI", sans-serif;
    --font-heading: "Calibri Local", "Carlito", "Cairo", "Tajawal", "Segoe UI", sans-serif;
}

[dir="rtl"] {
    --font-body: "Calibri Local", "Carlito", "Cairo", "Tajawal", "Segoe UI", sans-serif;
    --font-heading: "Calibri Local", "Carlito", "Cairo", "Tajawal", "Segoe UI", sans-serif;
}

body,
button,
input,
select,
textarea,
h1, h2, h3, h4, h5, h6,
.navbar-brand,
.section-title,
.uca-menu > li > a {
    font-family: var(--font-body);
}

/* The imported UCA theme (style.css) hardcodes Poppins/Rubik/Heebo/Montserrat
   on class-scoped selectors (`.week-event h6`, `[class*="scaption"]`,
   `.accordion .a-title`, ...). Their specificity beats the plain-element list
   above, so those elements kept the theme font and the site read as a mix.
   This sweep forces the Calibri token on every text-bearing element regardless
   of the theme's specificity.

   Icon fonts carry their glyph BY font-family: Font Awesome (.fa/.fas/.far/.fab)
   and Linearicons (.lnr) set it on the element itself, so they are excluded —
   forcing Calibri there would blank the icon. Fontello sets it on ::before, so
   an element-level rule never reaches the glyph and needs no exclusion. Bare
   <i> is excluded too (it is the icon tag) and simply inherits Calibri. */
body :not(i):not(.fa):not(.fas):not(.far):not(.fab):not(.lnr):not([class*="icon-"]):not([class^="icon-"]):not([class*="lnr"]):not(h1):not(h2):not(h3):not(h4):not(h5):not(h6) {
    font-family: var(--font-body) !important;
}

/* Headings are the one thing this sweep must not swallow. The Builder has a
   Heading Font control, it is stored, and SiteManager emits --font-heading from
   it - but the sweep above forced --font-body onto every descendant of <body>
   with !important, so the control changed nothing on any site in the product.
   Measured 2026-08-25: FontHeading = "Poppins" in the theme row, --font-heading
   = Poppins at :root, and every h2 on the page computed to Rubik, the body font.

   Excluding the six heading elements above is what makes this rule reachable;
   it then only has to beat an imported theme's plain `h2 { font-family: ... }`,
   which it does on specificity and on !important both. */
body h1, body h2, body h3, body h4, body h5, body h6 {
    font-family: var(--font-heading) !important;
}

/* Gallery album grid: Bootstrap's g-4 gutter rides on a negative row margin +
   per-column margin-top, both of which the imported theme's `.row{margin:0}`
   wipes out — so the album tiles touched top-to-bottom. `.row` stays
   display:flex, and row-gap on a flex-wrap container spaces the wrapped rows
   regardless of margins, so it survives the theme. The caption band sits on a
   token surface so the album name is legible in both themes. */
.row.gallery-db {
    row-gap: 1.75rem;
}
.gallery-album-inner {
    background: var(--bg-surface, #fff);
    transition: box-shadow .2s, transform .2s;
}
.gallery-album-card:hover .gallery-album-inner {
    box-shadow: 0 10px 28px rgba(0, 0, 0, .16) !important;
    transform: translateY(-3px);
}

/* Icon fonts are deliberately NOT touched here.
   Font Awesome picks its glyphs from family AND weight together (.fas needs
   weight 900, .fab needs 400). Restating only the family — which an earlier
   version of this file did — drops the weight and the icons come out blank or
   wrong. Their own stylesheet already sets both, and the font-family rules
   above list concrete elements rather than "*", so nothing leaks into them. */

/* ============================================================================
   LEGACY THEME BRIDGE — the ONLY place that reaches into a theme's own rules.

   Token-driven components flip with the theme by themselves. Theme stylesheets
   written before the token system do not: they hardcode colours and target the
   header through ID selectors (`#header { background:#fff }`,
   `#main-navigation > ul > li > a { color:... }`). An ID beats any number of
   classes, so load order alone never wins against them — later CSS only beats
   an EQUAL-specificity rule.

   So these selectors carry an ID of their own, and they assign nothing but
   tokens. Everything stays defined in tokens.css; this block only forwards it
   into markup the builder does not control. Keep it small — a new component
   belongs in the token system, not here.
   ============================================================================ */

#header,
#header:before,
.uca-header,
.top-bar,
.navbar {
    /* Two names for one meaning, and the site's own choice was the one that lost.
       SiteManager derives --bg-header from the Builder's Nav Background control;
       tokens.css declares --header-bg as the product's generic default. This rule
       named only the default, carries an ID, and sits last in the cascade - so it
       beat every other header rule on the page and the control changed nothing.
       Measured 2026-08-26: --bg-header resolved to #15803D at #header itself while
       the header painted white.

       Read in order: the site's setting first, the product default second. A site
       that has never chosen a header background is unchanged. */
    background: var(--bg-header, var(--header-bg));
    border-bottom-color: var(--header-border);
}

#main-navigation > ul > li > a,
#menu > li > a,
.uca-menu > li > a,
.navbar-nav > li > a,
.navbar-nav .nav-link {
    color: var(--header-fg);
}

#main-navigation > ul > li > a:hover,
#menu > li > a:hover,
.uca-menu > li > a:hover,
.navbar-nav .nav-link:hover {
    color: var(--header-fg-hover);
    background: var(--bg-hover);
}

#main-navigation > ul > li.current > a,
#menu > li.active > a,
.uca-menu > li.active > a,
.uca-menu > li.current > a {
    color: var(--header-fg-hover);
    box-shadow: inset 0 -3px 0 var(--accent-warm);
}

#menu .dropdown-menu,
.uca-menu .dropdown-menu,
.navbar-nav .dropdown-menu {
    background: var(--bg-surface);
    border-color: var(--border);
    box-shadow: var(--shadow-menu);
}
#menu .dropdown-menu a,
.uca-menu .dropdown-menu a,
.navbar-nav .dropdown-menu a { color: var(--text-body); }
#menu .dropdown-menu a:hover,
.uca-menu .dropdown-menu a:hover,
.navbar-nav .dropdown-menu a:hover { background: var(--bg-hover); color: var(--text-heading); }

/* Row one follows the same tokens. */
.info-bar { border-bottom-color: var(--border-subtle); }
.info-bar-contact,
.info-bar-contact span,
.info-bar-contact a { color: var(--text-body); }

/* ---- footer, same bridge, same reason (themes style it via #footer) ----
   The variant class matters: a theme writes `#footer.footer-3 .top-footer`
   (id + class + class), which outranks a plain `#footer .top-footer`. So the
   variants are matched explicitly here rather than relying on `#footer` alone. */
#footer,
#footer[class*="footer"],
#footer.footer-1, #footer.footer-2, #footer.footer-3,
#footer.footer-1 .top-footer, #footer.footer-2 .top-footer, #footer.footer-3 .top-footer,
#footer.footer-1 .copyright-section, #footer.footer-2 .copyright-section, #footer.footer-3 .copyright-section,
#footer .top-footer,
#footer .copyright-section,
.site-footer,
/* Two things were wrong here, and each on its own was enough to make the
   Builder's Footer Style control do nothing.

   The SELECTOR assumed the footer element carries both `.site-footer` and the
   style class. It does not: the style class goes on <body> - measured, the page
   renders `<body class="header-sticky footer-colored ...">` - and a theme's own
   footer can be anything, `<footer id="footer" class="footer-3">` here. Keying
   off the body class and the conventional #footer id reaches both shapes.

   The VARIABLE was --footer-bg, the product's generic default, while SiteManager
   derives --bg-footer from the site's own colours. Two names for one meaning, and
   the site's choice was the one that lost. Read in order now: the site's, then
   the default. A site that configures nothing is unchanged. */
.site-footer,
.site-footer.footer-dark,
.site-footer.footer-light,
.site-footer.footer-colored,
body.footer-dark #footer,
body.footer-light #footer,
body.footer-colored #footer {
    background: var(--bg-footer, var(--footer-bg)) !important;
    background-image: none;   /* some variants paint a photo behind the footer */
    color: var(--footer-ink, var(--footer-fg)) !important;
    border-color: var(--footer-border);
}

/* The footer's own text, headings and links follow the same derived ink, so a
   light footer is readable instead of white-on-white. SiteManager chooses the
   ink from the footer background's luminance - it is not a colour anyone typed.
   These carry !important because they replace rules that had it, and because a
   theme's footer typically hardcodes its own foreground. */
.site-footer h4, .site-footer h5,
body.footer-dark #footer h4, body.footer-dark #footer h5,
body.footer-light #footer h4, body.footer-light #footer h5,
body.footer-colored #footer h4, body.footer-colored #footer h5,
body.footer-dark #footer .widget-title,
body.footer-light #footer .widget-title,
body.footer-colored #footer .widget-title {
    color: var(--footer-ink, var(--footer-fg)) !important;
}

.site-footer a, .site-footer p, .site-footer small,
body.footer-dark #footer a, body.footer-dark #footer p, body.footer-dark #footer small,
body.footer-light #footer a, body.footer-light #footer p, body.footer-light #footer small,
body.footer-colored #footer a, body.footer-colored #footer p, body.footer-colored #footer small {
    color: var(--footer-ink-muted, var(--footer-fg)) !important;
}

.site-footer a:hover,
body.footer-dark #footer a:hover,
body.footer-light #footer a:hover,
body.footer-colored #footer a:hover {
    color: var(--footer-ink, var(--footer-fg)) !important;
}

/* The overlay a theme lays over that photo has to go with it. */
#footer[class*="footer"]:before,
#footer[class*="footer"]:after {
    background: none;
    content: none;
}

#footer h1, #footer h2, #footer h3, #footer h4, #footer h5, #footer h6,
#footer .widget-title,
.site-footer h4, .site-footer h5,
.site-footer.footer-dark h4, .site-footer.footer-dark h5,
.site-footer.footer-colored h4, .site-footer.footer-colored h5 {
    color: var(--footer-heading);
}

#footer p,
#footer span,
#footer li,
.site-footer p,
.site-footer small {
    color: var(--footer-fg);
}

#footer a,
.site-footer a,
.site-footer.footer-dark a,
.site-footer.footer-light a,
.site-footer.footer-colored a {
    color: var(--footer-link);
    text-decoration: none;
}
#footer a:hover,
.site-footer a:hover,
.site-footer.footer-dark a:hover,
.site-footer.footer-light a:hover,
.site-footer.footer-colored a:hover {
    color: var(--footer-link-hover);
}

/* The copyright strip is the one genuinely secondary line down there. */
#footer .copyright,
.site-footer .text-center small { color: var(--footer-muted); }

/* ============================================================================
   ROW THREE — the product sub-menu.

   Appears only while the visitor is inside a product's pages; the markup is
   emitted once by the master, so a product's pages carry no menu code of their
   own. Sticky, because these pages are long and the sub-menu is how you move
   between them.

   Per-product colours: scope tokens to the group rather than writing a theme
   or per-page CSS, e.g.

       body[data-page-group="a1erp"] { --accent: #7c3aed; }

   Everything token-driven — including this bar — follows automatically.
   ============================================================================ */
.sub-menu-bar {
    position: sticky;
    top: 0;
    z-index: 1100;
    background: var(--bg-raised);
    border-bottom: 1px solid var(--border-subtle);
    box-shadow: 0 1px 0 var(--border-subtle);
}

.sub-menu-list {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 2px;
    width: min(1200px, 100% - 32px);
    margin: 0 auto;
    padding: 0;
    list-style: none;
}

.sub-menu-list > li { display: inline-flex; }

.sub-menu-list a {
    display: inline-flex;
    align-items: center;
    padding: 12px 16px;
    color: var(--text-muted);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    border-bottom: 3px solid transparent;
}

.sub-menu-list a:hover {
    color: var(--text-heading);
    background: var(--bg-hover);
}

.sub-menu-list a.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

@media (max-width: 991px) {
    /* Scroll sideways rather than wrapping into several rows on a phone. */
    .sub-menu-list {
        justify-content: flex-start;
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
    }
    .sub-menu-list::-webkit-scrollbar { display: none; }
    .sub-menu-list a { padding: 10px 12px; white-space: nowrap; }
}

/* ============================================================================
   DROPDOWN CARET.

   Theme sheets draw this with a glyph from their own icon font
   (`content:'\e8e7'; font-family:'fontello'`). When that font is not loaded —
   and it should not have to be, just for one arrow — the browser prints the
   missing-glyph box instead. Bootstrap's .dropdown-toggle::after has the same
   problem in reverse: it disappears under a theme's rule.

   So the caret is drawn here in plain CSS: a rotated square with two borders.
   No font, no icon file, nothing to fail to load, and it inherits the link's
   colour automatically.
   ============================================================================ */

/* Silence whatever the theme was drawing. */
#main-navigation > ul > li.dropdown > a:after,
#menu > li.dropdown > a:after,
.uca-menu > li.dropdown > a:after,
.navbar-nav .dropdown-toggle::after {
    content: none;
}

/* One caret, drawn as a rotated corner. */
#main-navigation > ul > li.dropdown > a::before,
#menu > li.dropdown > a::before,
.uca-menu > li.dropdown > a::before,
.navbar-nav .dropdown-toggle::before {
    content: "";
    display: inline-block;
    width: .42em;
    height: .42em;
    margin-inline-start: .55em;
    border-inline-end: 2px solid currentColor;
    border-block-end: 2px solid currentColor;
    border-radius: 1px;
    transform: rotate(45deg) translateY(-.12em);
    opacity: .6;
    transition: transform .15s ease, opacity .15s ease;
    vertical-align: middle;
}

/* Point it up while the menu is open. */
#menu > li.dropdown:hover > a::before,
.uca-menu > li.dropdown:hover > a::before,
.navbar-nav .dropdown-toggle[aria-expanded="true"]::before,
.navbar-nav .show > .dropdown-toggle::before {
    transform: rotate(-135deg) translateY(-.12em);
    opacity: 1;
}

/* ============================================================================
   DROPDOWN ALIGNMENT — logical, so it follows the writing direction.

   Bootstrap and most theme sheets hardcode `text-align: left` on dropdown
   items, which leaves Arabic text hugging the wrong edge. `start` means "the
   edge the text begins at": left in English, right in Arabic — one rule for
   both instead of a mirrored RTL override.
   ============================================================================ */
.dropdown-menu,
.dropdown-menu li,
.dropdown-menu .dropdown-item,
.dropdown-menu a,
#menu .sub-menu-wrap,
#menu .sub-menu-wrap a,
.uca-menu .dropdown-menu a,
.sub-menu-list a {
    text-align: start;
}

/* Icon then label, in that order from the start edge, whichever side that is. */
.dropdown-menu .dropdown-item,
.dropdown-menu a,
#menu .sub-menu-wrap a {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* The menu itself should open from the start edge of its parent item. */
[dir="rtl"] .dropdown-menu {
    right: 0;
    left: auto;
}
[dir="ltr"] .dropdown-menu {
    left: 0;
    right: auto;
}

/* The language menu is the exception: it sits at the end of the row, so it
   opens toward the end edge to stay on screen. */
[dir="rtl"] .lang-dropdown-menu.dropdown-menu {
    right: auto;
    left: 0;
}
[dir="ltr"] .lang-dropdown-menu.dropdown-menu {
    left: auto;
    right: 0;
}

/* ============================================================================
   STICKY HEADER.

   The chrome stays pinned to the top while the page scrolls — the controls
   (language, dark/light, admin) and the menu are needed at any scroll position,
   and a header that scrolls away means scrolling back up to reach them.

   The theme's HeaderStyle already says "sticky"; until now nothing acted on it.
   Applied through the same body class the theme sets, so a theme can opt out by
   choosing a different HeaderStyle.
   ============================================================================ */
body.header-sticky #header,
body.header-sticky .uca-header {
    position: sticky;
    top: 0;
    z-index: 1050;
}

/* `fixed` used to be routed to position:sticky along with `sticky`, so the two
   options were one option wearing two names - measured 2026-08-26: the editor
   offered sticky/fixed/static and the browser computed sticky for both.

   Fixed means fixed: out of flow, pinned to the viewport, full width in either
   reading direction (left/right rather than inset-inline, because the header
   spans the whole viewport in both). The space it no longer occupies is given
   back below, from a height that is MEASURED - see js/header-offset.js - because
   the header's height follows the logo size, the menu wrap and the viewport, and
   any number written here would be wrong the moment one of them changed. */
body.header-fixed #header,
body.header-fixed .uca-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1050;
}

/* Until the script has measured, this is 0 and the page simply renders with the
   header overlapping - the same as before this rule existed. It is never a
   guessed height. */
body.header-fixed {
    padding-top: var(--header-height, 0px);
}

/* The sub-menu row sits directly under the header when both are present. */
body.header-sticky .sub-menu-bar,
body.header-fixed .sub-menu-bar {
    top: 0;
    z-index: 1040;
}

/* A sticky ancestor traps position:sticky children, and an overflow other than
   visible on an ancestor disables it outright — both are common in theme CSS. */
body.header-sticky,
body.header-fixed,
body.header-sticky #wrapper,
body.header-fixed #wrapper {
    overflow: visible;
}

/* Anchor links must not land under the pinned header. */
:target {
    scroll-margin-top: 120px;
}

/* ============================================================================
   PAGE FLOW.

   Theme sheets from the sticky-footer era pin `html, body { height: 100% }` so a
   short page could push its footer to the bottom of the viewport. On a page that
   is LONGER than the viewport that same rule caps the body at one screen, and
   everything past the first screen — including the footer — stacks on top of the
   content instead of following it. That is what put the footer in mid-page.

   min-height gives the short-page behaviour the theme wanted without capping a
   long one.
   ============================================================================ */
html,
body {
    height: auto;
    min-height: 100%;
}

/* Keep the footer at the bottom on pages too short to fill the screen, without
   taking it out of the flow. */
body {
    display: flex;
    flex-direction: column;
}

body > main,
body > form {
    flex: 1 0 auto;
}

/* WebForms wraps everything in one <form>, so the column has to live there too. */
body > form {
    display: flex;
    flex-direction: column;
}

body > form > main {
    flex: 1 0 auto;
}

/* THE header and footer MUST NOT SHRINK.
   A flex item defaults to flex-shrink:1. Once the page is taller than the
   container, the browser takes the difference out of whatever may shrink — so
   the footer's BOX was being squeezed, sometimes to almost nothing, while its
   text and logo still painted at full size. That is what looked like "the footer
   is drawn on top of the page": it was not positioned over anything, it had been
   crushed and its contents spilled out.
   It got worse the shorter the window, because that is when the container has
   the biggest shortfall to make up. */
body > form > header,
body > form > footer,
body > header,
body > footer,
#footer,
.site-footer {
    flex-shrink: 0;
}

/* A section must be able to grow with its content. */
.site-section {
    height: auto;
    min-height: 0;
    overflow: visible;
}

/* ============================================================================
   NEWS LIST — the dated headline list used beside a calendar.

   Cards belong in a full-width row; in a narrow column they become tall boxes
   with an oversized button, which is what made the school's home page look
   nothing like its original.
   ============================================================================ */
.news-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.news-list-item {
    padding: 14px 0;
    border-bottom: 1px solid var(--border-subtle);
}
.news-list-item:last-child { border-bottom: none; }

.news-date {
    display: block;
    margin-bottom: 4px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: var(--track-label, .04em);
    text-transform: uppercase;
    color: var(--accent-warm);
}

.news-title {
    display: block;
    font-size: 17px;
    font-weight: 600;
    line-height: 1.45;
    color: var(--text-heading);
    text-decoration: none;
}
.news-title:hover { color: var(--accent); }

.news-excerpt {
    margin: 6px 0 0;
    font-size: 14px;
    line-height: 1.6;
    color: var(--text-muted);
    /* Two lines is enough to tell the story apart; the rest is on the article. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.news-more {
    display: inline-block;
    margin-top: 12px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: var(--track-label, .06em);
    text-transform: uppercase;
    color: var(--accent-warm);
    text-decoration: none;
}
.news-more:hover { color: var(--accent); }

/* ============================================================================
   COLUMN SECTIONS — a section nested in a column needs its own rhythm.
   ============================================================================ */
.column-title {
    margin: 0 0 18px;
    font-size: 22px;
    font-weight: 700;
    color: var(--text-heading);
}

/* Thumbnails inside a column are small by definition. */
.section-columns .gallery-db .gallery-album-card img {
    aspect-ratio: 1 / 1;
}

/* A column must not be allowed to run away with the page height. */
.section-columns > .container > .row > [class*="col-"] {
    min-width: 0;
}

/* ============================================================================
   MINI CALENDAR — a 7-column CSS grid, no library.

   The full FullCalendar widget sizes itself with JS and needs a whole section's
   width; dropped into a narrow column it overflowed and painted over the footer.
   This is the sidebar shape: a month header, weekday row, the days, and a dot
   under any day carrying an event.
   ============================================================================ */
.mini-cal {
    max-width: 100%;
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    overflow: hidden;
    background: var(--bg-surface);
}

.mini-cal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 12px 14px;
    background: var(--accent-warm);
    color: #fff;
}

.mini-cal-title {
    text-align: center;
    font-weight: 700;
    line-height: 1.15;
    text-transform: uppercase;
    letter-spacing: var(--track-label, .04em);
}
.mini-cal-title span {
    display: block;
    font-size: 12px;
    font-weight: 500;
    opacity: .9;
    letter-spacing: 0;
}

.mini-cal-nav {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    color: #fff;
    font-size: 18px;
    line-height: 1;
    text-decoration: none;
    background: rgba(255, 255, 255, .18);
}
.mini-cal-nav:hover { background: rgba(255, 255, 255, .32); color: #fff; }

.mini-cal-grid { padding: 10px; }

/* Seven equal columns — the whole layout, in one line. */
.mini-cal-row {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}

.mini-cal-dow span {
    padding: 6px 0;
    text-align: center;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--text-muted);
}

.mini-cal-day {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1 / 1;
    border-radius: 8px;
    font-size: 13px;
    color: var(--text-body);
}
.mini-cal-day.is-empty { visibility: hidden; }

.mini-cal-day.is-today {
    background: var(--accent);
    color: #fff;
    font-weight: 700;
}

/* A dot marks a day with something on it; the day's title is in the tooltip. */
.mini-cal-dot {
    position: absolute;
    bottom: 4px;
    left: 50%;
    transform: translateX(-50%);
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--accent-warm);
}
.mini-cal-day.is-today .mini-cal-dot { background: #fff; }

.mini-cal-more {
    display: inline-block;
    margin-top: 10px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: var(--track-label, .06em);
    text-transform: uppercase;
    color: var(--accent-warm);
    text-decoration: none;
}
.mini-cal-more:hover { color: var(--accent); }

/* ============================================================================
   FOOTER must never be painted over.

   A section whose content overflows used to land on top of it. Giving the footer
   its own stacking context above the sections settles it regardless of what a
   section's content does, and clearing floats stops an old float-based theme
   pulling the footer up beside the content.
   ============================================================================ */
#footer,
.site-footer {
    position: relative;
    z-index: 2;
    clear: both;
    width: 100%;
}

/* Sections stay in the flow.
   NOT overflow-x:clip — when one axis is clipped the other stops being `visible`
   and computes to `auto`, which turns every section into a scroll container and
   changes how its height is resolved. */
.site-section {
    position: relative;
    z-index: 1;
}

/* ============================================================================
   TABS — styling the markup the renderer actually emits.

   site.css styles `.tabs-nav` and `.tab-btn`, from an earlier hand-rolled tab
   widget. The section renderer emits Bootstrap's `.nav.nav-tabs` / `.nav-link`,
   so none of that styling ever applied and the strip fell back to the browser
   default. Same editor-vs-renderer drift that hid the panes themselves.

   Shaped like the school's own tab block: a bordered rounded box with the active
   tab joined to the panel below it.
   ============================================================================ */
.section-tabs .nav-tabs {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    justify-content: center;
    border: none;
    margin-bottom: 0;
    padding: 6px;
    border-radius: 14px 14px 0 0;
    background: var(--bg-raised);
}

.section-tabs .nav-tabs .nav-link {
    border: 1px solid transparent;
    border-radius: 10px;
    padding: 10px 22px;
    font-size: 15px;
    font-weight: 600;
    color: var(--text-muted);
    background: transparent;
}

.section-tabs .nav-tabs .nav-link:hover {
    color: var(--text-heading);
    background: var(--bg-hover);
}

.section-tabs .nav-tabs .nav-link.active {
    color: var(--accent);
    background: var(--bg-surface);
    border-color: var(--border-subtle);
    box-shadow: 0 -2px 0 var(--accent) inset;
}

/* The panel reads as one piece with the strip above it. */
.section-tabs .tab-content {
    max-width: 900px;
    margin: 0 auto;
    padding: 26px 28px;
    border: 1px solid var(--border-subtle);
    border-radius: 0 14px 14px 14px;
    background: var(--bg-surface);
    text-align: start;
}

.section-tabs .tab-content > .tab-pane {
    color: var(--text-body);
}

/* ============================================================================
   FOOTER STAYS IN THE FLOW.

   The school theme's responsive.css carries, inside @media (min-width:1281px):

       #footer[class*="footer"] { position: fixed; bottom: 0; width: 100%; }

   — a Bootstrap-3-era "footer glued to the bottom of the window" pattern. Our
   footer is <footer id="footer" class="footer-3">, so the attribute selector
   matches it exactly: the footer left the flow, sat at the bottom of the
   viewport, and the page's own sections ran underneath it. It only bit on wide
   screens, which is why the same page looked fine at one window size and broken
   at another.

   Undone here rather than by editing the theme's file, so the theme stays the
   vendor's and the reason lives with the fix. Matched at equal-or-higher
   specificity (attribute selector + the same media condition is not needed —
   this sheet loads after) so it wins.
   ============================================================================ */
#footer,
#footer[class*="footer"],
.site-footer {
    position: relative;
    bottom: auto;
    z-index: 2;
}

/* ============================================================================
   GALLERY ALBUM — one album's photos, rendered by the gallery-album section.

   Replaces the standalone GalleryAlbum.aspx, which carried its own <html> and
   its own stylesheet and therefore appeared outside the site's chrome.
   ============================================================================ */
.album-head {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 22px;
}
.album-back { color: var(--accent); font-weight: 600; text-decoration: none; }
.album-back:hover { color: var(--accent-warm); }
.album-title { margin: 0; font-size: 1.6rem; font-weight: 800; color: var(--text-heading); }
.album-count { color: var(--text-muted); font-size: 14px; }

.album-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 14px;
}
.album-photo {
    padding: 0;
    border: 0;
    background: none;
    border-radius: 12px;
    overflow: hidden;
    cursor: zoom-in;
    box-shadow: 0 3px 14px rgba(0, 0, 0, .10);
}
.album-photo img {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    transition: transform .4s ease;
}
.album-photo:hover img { transform: scale(1.07); }
.album-photo:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

/* --- lightbox --- */
.album-lb {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: none;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    background: rgba(0, 0, 0, .92);
}
.album-lb.open { display: flex; }
.album-lb img { max-width: 90vw; max-height: 78vh; border-radius: 8px; }
.album-lb-cap { margin-top: 14px; max-width: 80vw; text-align: center; color: #fff; }

.album-lb button {
    position: absolute;
    min-width: 48px;
    min-height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .12);
    color: #fff;
    font-size: 1.8rem;
    line-height: 1;
    cursor: pointer;
}
.album-lb button:hover { background: rgba(255, 255, 255, .28); }
.album-lb button:focus-visible { outline: 3px solid #fff; outline-offset: 2px; }
.album-lb-x { top: 16px; inset-inline-end: 20px; }
.album-lb-prev { top: 50%; transform: translateY(-50%); inset-inline-start: 20px; }
.album-lb-next { top: 50%; transform: translateY(-50%); inset-inline-end: 20px; }

/* ============================================================================
   HEADER EXTRAS — accreditation badges and one call-to-action.

   A school is judged partly by who accredits it, so the marks sit beside the
   logo where a parent looks first. Both are driven by settings, not baked into
   a theme, so another site can carry different marks or none at all.
   ============================================================================ */
.info-bar-accred {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
}
.info-bar-accred img {
    height: 40px;
    width: auto;
    object-fit: contain;
}

.header-cta {
    display: inline-flex;
    align-items: center;
    height: var(--chrome-height);
    padding: 0 18px;
    border-radius: var(--chrome-radius);
    background: var(--accent);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
}
.header-cta:hover {
    background: var(--accent-warm);
    color: #fff;
}

@media (max-width: 767px) {
    /* On a phone the badges cost more room than they earn. */
    .info-bar-accred { display: none; }
}

/* ============================================================================
   FOOTER COLUMNS — link lists and the brand block.
   ============================================================================ */
.info-links {
    list-style: none;
    margin: 0;
    padding: 0;
}
.info-links li { margin-bottom: 8px; }
.info-links a {
    color: var(--footer-link);
    font-size: 14px;
    text-decoration: none;
}
.info-links a:hover { color: var(--footer-link-hover); }

#footer .widget-title {
    margin-bottom: 16px;
    font-size: 16px;
    font-weight: 700;
    color: var(--footer-heading);
}

#footer .footer-logo { display: inline-block; margin-bottom: 12px; }
/* 56px was a literal, and it was the winner: the Builder's Logo Height control
   is stored and SiteManager emits --logo-height from it, but this rule outranked
   the consumer that reads the variable, so setting a height in the editor moved
   nothing in the footer. The literal stays as the fallback, which is what a site
   that has never set one gets - unchanged. */
#footer .footer-logo img { height: var(--logo-height, 56px); width: auto; }
#footer .footer-tagline { color: var(--footer-muted); font-size: 14px; }

/* The accreditation marks repeat in the footer, as on the school's own site. */
#footer .info-bar-accred {
    display: flex;
    gap: 10px;
    margin-top: 14px;
}
#footer .info-bar-accred img {
    height: 46px;
    /* The marks are dark-on-white; on a dark footer they need their own plate. */
    background: #fff;
    border-radius: 8px;
    padding: 4px;
}

/* ============================================================================
   LONG-FORM CONTENT — imported documents, policies, handbooks.

   Applies the readability rules these pages actually need:
   line length capped at ~70 characters (past that the eye loses the next line),
   generous line height, left-aligned body text (ragged-right reads faster than
   justified and avoids rivers of white space), and a heading scale that steps
   down clearly instead of relying on weight alone.
   ============================================================================ */
.site-section .section-body,
.section-content .content-text,
.news-article-body {
    /* ch units track the font, so the measure stays right at any size. */
    max-width: 70ch;
    margin-inline: auto;
    font-size: 1.05rem;
    line-height: 1.75;
    text-align: start;
}

.section-content h2,
.section-content h3,
.news-article-title {
    max-width: 70ch;
    margin-inline: auto;
    line-height: 1.25;
    text-wrap: balance;
}

/* A heading that has been jumped to must not hide under the sticky header. */
.site-section[id] { scroll-margin-top: 130px; }

/* ============================================================================
   IN-PAGE INDEX — the contents list for a long document.

   Built from the page's own section headings, so it cannot drift out of step
   with them, and every entry is a real anchor link.
   ============================================================================ */
.page-index {
    max-width: 70ch;
    margin: 0 auto 34px;
    padding: 20px 24px;
    border: 1px solid var(--border-subtle);
    border-radius: 14px;
    background: var(--bg-raised);
}
.page-index h2 {
    margin: 0 0 12px;
    font-size: 15px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: var(--track-label, .06em);
    color: var(--text-muted);
}
.page-index ol {
    margin: 0;
    padding-inline-start: 1.2em;
    columns: 2;
    column-gap: 32px;
}
.page-index li { margin-bottom: 7px; break-inside: avoid; }
.page-index a {
    color: var(--text-body);
    text-decoration: none;
    font-size: 15px;
}
.page-index a:hover { color: var(--accent); text-decoration: underline; }

@media (max-width: 767px) {
    .page-index ol { columns: 1; }
}

/* ============================================================================
   PRINT — a handbook exists to be printed.

   Drop the chrome, drop the index (it is navigation, useless on paper), print
   in black on white, and let the reader see where a link actually goes.
   ============================================================================ */
@media print {
    /* 11-1. nav.navbar is the canonical Builder navigation — the menu row of the two-row header
       Public/Page.aspx emits on EVERY page. It was missing from this list, so measured under
       print emulation it stayed display:flex and every printed page carried the site menu.

       ⛔ .utility-menu was removed and nothing else was: measured at PRODUCT level, the other
       selectors that match nothing on THIS site all have live emitters —
         .sub-menu-bar   Page.aspx.vb:499, row 3 inside a product's pages
         .page-index     SectionRenderer.Data.vb:541
         .header-cta     Page.aspx.vb:648
         .cookie-banner  PluginManager.vb:108, the `cookies` plugin
         .whatsapp-float PluginManager.vb:82, the `whatsapp` plugin
         #header · .uca-header · #footer-scroll   Themes/UCA-Theme/header.html and footer.html
       They are absent from this configuration, not from the product. Deleting them would break
       print for any site that enables those features.
       .utility-menu is different: UtilityMenuHtml() returns "" into a literal marked
       Visible="false", so nothing can ever produce it. */
    #header, .info-bar, nav.navbar, .sub-menu-bar, #footer, .site-footer,
    .page-index, .header-cta, #footer-scroll,
    .cookie-banner, .whatsapp-float {
        display: none !important;
    }

    html, body {
        background: #fff !important;
        color: #000 !important;
        font-size: 11pt;
    }

    .site-section {
        padding: 0 0 12pt !important;
        background: none !important;
        break-inside: auto;
    }

    /* Never strand a heading at the foot of a page. */
    h1, h2, h3, h4 { break-after: avoid; page-break-after: avoid; }
    img, figure, table { break-inside: avoid; }

    .site-section .section-body { max-width: none; }

    /* On paper a link is just words unless its target is spelled out. */
    a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; color: #444; }
    a[href^="/"]::after,
    a[href^="#"]::after { content: ""; }
}

/* ============================================================================
   IMPORTED PROSE — paragraphs and lists rebuilt from a PDF.

   A numbered rule must start its own line: run together mid-paragraph, a list of
   twenty school rules is unreadable. Direction is set per paragraph because
   these documents mix Arabic and English on the same page.
   ============================================================================ */
.content-text p {
    margin: 0 0 1em;
    max-width: 70ch;
}
.content-text p[dir="rtl"] { margin-inline: auto 0; }
.content-text p[dir="ltr"] { margin-inline: 0 auto; }

.content-list {
    max-width: 70ch;
    margin: 0 auto 1.4em;
    padding-inline-start: 1.6em;
}
.content-list li {
    margin-bottom: .55em;
    line-height: 1.7;
}
/* The marker belongs on the text's own side. */
.content-list[dir="rtl"] { padding-inline-start: 1.6em; text-align: right; }
.content-list[dir="ltr"] { text-align: left; }

/* A heading followed immediately by a list should not float away from it. */
.content-text h2 + .content-list,
.content-text h3 + .content-list { margin-top: .4em; }

/* Document prose reads from the text's own side. A content section's column
   carries Bootstrap's `.text-center` (the section's default align control), and
   `.text-center{text-align:center!important}` would otherwise centre Arabic body
   copy AND strand every list marker far to the right of its centred text. These
   win because they are more specific than `.text-center` while also !important.
   Scoped to `.section-content`, so hero and feature-card centring stay intact. */
.section-content .content-text,
.section-content .content-text p,
.section-content .content-list,
.section-content .content-list li,
.section-content .content-subheading { text-align: start !important; }

/* Restore a real, direction-aware bullet on the imported-prose list. `site.css`
   styles every `.content-text ul` with `list-style:none` + `li{display:flex}`
   (for icon lists) and `.section-content ul` with a physical-`left` ::before dot
   — both strip or mis-place the marker on an Arabic `.content-list`. Winning on
   specificity here gives back the native disc, which sits on the text's own side. */
.section-content .content-text ul.content-list {
    list-style: disc;
    padding-inline-start: 1.4em;
}
.section-content .content-text ul.content-list > li {
    display: list-item;
    padding: 4px 0;
    gap: 0;
}
.section-content .content-text ul.content-list > li::before { content: none; }

/* Card grids: guarantee a vertical gap between wrapped rows. The active theme
   ships a global `.row{margin:0}` that cancels Bootstrap's vertical gutter, so
   the second row of cards ends up touching the first. chrome.css loads AFTER the
   theme, so set an explicit flex `row-gap` here (which neither the theme nor
   Bootstrap uses) and zero the Bootstrap child margin so the two never stack. */
.section-features .row,
.section-team .row,
.section-testimonials .row,
.section-pricing .row,
.section-stats .row { row-gap: 2.25rem; }
.section-features .row > *,
.section-team .row > *,
.section-testimonials .row > *,
.section-pricing .row > *,
.section-stats .row > * { margin-top: 0; }

/* --- sub-headings inside imported text ------------------------------------
   A run-in label ("Preparation:", "EMERGENCY PROCEDURES") is a heading, not a
   paragraph. Weight and colour separate it; size stays close to the body so the
   page keeps one clear hierarchy: section title > sub-heading > text.
   -------------------------------------------------------------------------- */
.content-subheading {
    max-width: 70ch;
    margin: 1.8em auto .5em;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.4;
    color: var(--accent);
}
.content-subheading[dir="rtl"] { margin-inline: auto 0; text-align: right; }
.content-subheading[dir="ltr"] { margin-inline: 0 auto; text-align: left; }

/* First thing in a section needs no gap above it. */
.content-text > .content-subheading:first-child { margin-top: 0; }

/* The number/letter carries the emphasis in a list of rules. */
.content-list li::marker {
    font-weight: 700;
    color: var(--accent-warm);
}

@media print {
    .content-subheading { color: #000; }
    .content-list li::marker { color: #000; }
}

/* --- team cards ------------------------------------------------------------
   A member with no photo gets their initials rather than a broken image icon.
   Drawn in CSS so it needs no file and cannot 404 — see RenderTeam.
   -------------------------------------------------------------------------- */
.team-card { padding: 1.2rem 1rem; }

.team-initials {
    width: 120px;
    height: 120px;
    margin: 0 auto .8rem;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--accent-soft);
    color: var(--accent-strong);
    font-size: 2.2rem;
    font-weight: 700;
    letter-spacing: .02em;
    /* Latin initials in a right-to-left card would otherwise reverse. */
    direction: ltr;
}

.team-card h5 { margin: 0 0 .2rem; font-size: 1.05rem; color: var(--text-heading); }
.team-card p  { margin: 0; color: var(--text-muted); font-size: .9rem; }
.team-bio { margin-top: .45rem; font-size: .85rem; line-height: 1.6; color: var(--text-muted); }

/* ============================================================================
   MOBILE NAVIGATION TOGGLE                                 A1-NAV-TOGGLE-01
   Pairs with js/a1-nav.js. Central builder component, theme-agnostic.

   EVERY collapse rule below is scoped under [data-a1-nav="on"], and only
   js/a1-nav.js sets that attribute. This is deliberate and is the whole safety
   property: if the script never runs, none of these rules match, the button
   does not exist, and the navigation renders exactly as it does today — a
   wrapped list that works. CSS is never allowed to hide the menu on its own.

   The bars are drawn here rather than pulled from an icon font: a font is a
   second thing that can fail, and remote icon CDNs are blocked in-region.
   ============================================================================ */

/* Hidden until the script proves it can drive it, and never on desktop. */
.a1-nav-toggle { display: none; }

[data-a1-nav="on"] .a1-nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin: 6px 0;
    padding: 9px 14px;
    border: 1px solid var(--chrome-border, rgba(0, 0, 0, .15));
    border-radius: 8px;
    background: transparent;
    color: inherit;
    font: inherit;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
}

[data-a1-nav="on"] .a1-nav-toggle:hover {
    background: rgba(0, 0, 0, .05);
}

/* Focus must be SEEN, not merely present — this is the keyboard user's cursor. */
[data-a1-nav="on"] .a1-nav-toggle:focus-visible {
    outline: 3px solid var(--chrome-accent, #F97316);
    outline-offset: 2px;
}

/* Three bars from one element: the box is the middle bar, the two pseudo
   elements are the outer ones. */
.a1-nav-toggle-bars {
    position: relative;
    display: block;
    width: 20px;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
}
.a1-nav-toggle-bars::before,
.a1-nav-toggle-bars::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
}
.a1-nav-toggle-bars::before { top: -6px; }
.a1-nav-toggle-bars::after  { top:  6px; }

/* Open: the bars become an X. Driven by aria-expanded so the visual state and
   the state assistive technology is told can never disagree — there is only one
   source of truth, and it is the accessible one. */
[data-a1-nav="on"] .a1-nav-toggle[aria-expanded="true"] .a1-nav-toggle-bars {
    background: transparent;
}
[data-a1-nav="on"] .a1-nav-toggle[aria-expanded="true"] .a1-nav-toggle-bars::before {
    top: 0;
    transform: rotate(45deg);
}
[data-a1-nav="on"] .a1-nav-toggle[aria-expanded="true"] .a1-nav-toggle-bars::after {
    top: 0;
    transform: rotate(-45deg);
}

@media (max-width: 991px) {
    /* Collapsed by default. Outranks the `#main-navigation { display: block
       !important }` guard above: that rule is one id (1,0,0); this is an
       attribute plus an id (1,1,0), so it wins without needing to be louder. */
    [data-a1-nav="on"] #main-navigation {
        display: none !important;
    }

    [data-a1-nav="on"][data-a1-nav-open="1"] #main-navigation {
        display: block !important;
    }

    /* Open on a phone: one item per row. A wrapped grid of nine links is what
       this component exists to replace. */
    [data-a1-nav="on"][data-a1-nav-open="1"] #main-navigation > ul {
        display: block;
    }
    [data-a1-nav="on"][data-a1-nav-open="1"] #main-navigation > ul > li {
        display: block;
        width: 100%;
    }
    [data-a1-nav="on"][data-a1-nav-open="1"] #main-navigation > ul > li > a {
        display: block;
        width: 100%;
        padding: 12px 14px;
    }
}

@media (min-width: 992px) {
    /* Desktop keeps the menu it already had, and the button goes away entirely. */
    [data-a1-nav="on"] .a1-nav-toggle { display: none; }
}

html.dark-mode [data-a1-nav="on"] .a1-nav-toggle,
html[data-theme="dark"] [data-a1-nav="on"] .a1-nav-toggle {
    border-color: rgba(255, 255, 255, .22);
}
html.dark-mode [data-a1-nav="on"] .a1-nav-toggle:hover,
html[data-theme="dark"] [data-a1-nav="on"] .a1-nav-toggle:hover {
    background: rgba(255, 255, 255, .08);
}


/* ============================================================================
   VERTICAL GRID GUTTER — restored with the one mechanism a theme cannot veto

   Bootstrap 5 spaces wrapped grid rows with `.row > * { margin-top:
   var(--bs-gutter-y) }`; `g-4` only sets the variable. The imported school
   theme ships:

       form .row,
       form .row > [class*="col-"] { margin-top: 0px !important; }   style.css:3231

   Every builder page is WebForms, so EVERYTHING lives inside <form runat=
   "server">. That selector therefore matches every grid on every page, and
   `!important` beats source order and any specificity this layer can reach —
   a restated `margin-top` here was measured and did nothing.

   Measured on /news 2026-08-24: --bs-gutter-y = 1.5rem as intended, column
   margin-top = 0px, and consecutive card rows sat 0px apart at 1200 and 1440 —
   cards touching, which reads as overlap.

   `row-gap` on the flex container is the way out: the theme's rule targets
   margin, so it cannot reach this, and the gap belongs to the row rather than
   to each child. It is the same escape chrome.css already used for
   `.row.gallery-db` and the stats grid; this generalises it instead of adding
   a third one-off.

   Children are zeroed deliberately, so exactly ONE mechanism ever applies. On
   a site whose theme never broke margin-top, leaving both would double every
   gutter.

   A plain `.row` keeps --bs-gutter-y at 0, so rows with no g-* class are
   untouched.
   ============================================================================ */
.row[class*="g-"] {
    row-gap: var(--bs-gutter-y);
}
.row[class*="g-"] > * {
    margin-top: 0;
}
