/* ==========================================================================
   about-faculty.css - /about/faculty/

   A PORT, NOT A DESIGN. This is the client's own concept page for this route,
   captured verbatim at lab/concept-2026-09-19/about-faculty-ref.html and
   re-expressed here. The instruction was to build it one to one, so the
   default answer to "should this value be nicer" is no.

   THE MAPPING IS MECHANICAL.

     .foo            ->  .abf-foo         every class, no exceptions
     img, a, button  ->  :where(.abf-page) img   anything not rooted in a class
                                                 is scoped to the page
     :root, body     ->  .abf-page        page-wide settings that must not
                                          escape into the shell

   The prefix is not tidiness: site.css already owns .hero, .people, .welcome,
   .visit and .btn for the home page. :root and body are not either - site.css
   defines --ink, --paper and the rest at :root with DIFFERENT values, so
   leaving the concept's tokens at :root would leave two palettes overwriting
   each other by load order.

   WHICH PALETTE. Pages 02/03/04/05/09 deliberately swap their concept's red
   for the repo terracotta #A83226, because those five are one About-family
   design. PAGE 08 DID NOT - /about/student-services/ keeps its concept's own
   #A72820 and its DM Sans / Libre Caslon Display pair, by the client's
   instruction to copy that concept one to one. This page sits directly beside
   08 in the IA, is the same kind of directory page, and was given the same
   instruction, so it follows 08: the tokens below are the FACULTY CONCEPT'S
   OWN, #93211B / #612116 / #EFE8DC, not the repo terracotta and not page 08's
   red either. Two sibling concepts, two near-identical reds, each kept as its
   author drew it.

   THE CONCEPT'S SHELL IS DROPPED, and nothing else is. Its flat seven-link
   bar, its CSS-drawn HUDA lockup, its announcement strip and its own
   four-column footer are all replaced by this site's banner, three-level nav,
   drawer and footer. So .notice, .nav, .nav-side, .brand, .brand-mark,
   .brand-name, .brand-sub, .donate, .mobile-toggle, .skip, footer,
   .footer-grid, .footer-brand, .footer-col and .footer-bottom are not here,
   along with their clauses in all three breakpoints.

   SIX THINGS DEVIATED FROM THE CONCEPT ON PURPOSE; FIVE STILL DO. The first
   five are house rules that already cost this project a bug. The sixth was
   different in kind: the one place where the concept was simply WRONG - a word
   parked outside its own arch and clipped by the `overflow:hidden` that drew
   it. It left with the hero on 2026-09-27, and its arithmetic went with it.

   1. THE THREE DARK GROUNDS ARE GRADIENTS UNDER A NOISE FILM.
      .hero-field and .faith-wrap are flat var(--rust) in the concept (the
      hero field has since retired with the hero, 2026-09-27) and
      .welcome is flat var(--rust-deep). A large flat dark area gets spatially
      dithered by the display pipeline into a visible diagonal hairline right
      across the viewport - CLAUDE.md, "never a flat dark solid". Each is now a
      real two-stop gradient that ENDS on the concept's own value, under
      .abf-noise. See the note at .abf-noise for why isolation:isolate has to
      come with it.

   2. THE REVEAL IS GATED ON html.js.
      The concept ships `[data-reveal]{opacity:0}` unconditionally, so if its
      script fails its page is blank. Ours hides only once the shell's inline
      <head> script has set .js, and this page's own inline <head> script
      carries the 6s failsafe. The attribute is renamed [data-reveal] ->
      [data-rv] to match the four sibling ports and, with them, the static
      gate in tools/check-page-rules.mjs that reads that attribute by name.

   3. body{overflow-x:hidden} IS NOT CARRIED.
      overflow:hidden on body makes it a scroll container and re-parents every
      position:sticky on the page - the site's whole .topstack. site.css
      already ships overflow-x:clip on html,body, which is the one value that
      may legally pair with overflow-y:visible, and it is what contains
      .abf-faith-wrap's negative side margins.

   4. THE IN-PAGE ANCHORS GET A scroll-margin-top.
      The concept's nav is static; this site's .topstack is position:sticky, so
      a jump to #elementary would land the heading underneath the nav. Six
      links on this page are in-page jumps, so this is not optional. Nothing in
      the concept to drift from - it is a rule the concept could not have had.

   5. THE FACULTY EMAILS ARE THE CONCEPT'S, INCLUDING TWO THAT LOOK WRONG.
      Not a CSS matter, but it belongs with the register: the markup carries
      raeda@hudaacademy.org and anssar@hudaacademy.org on the short domain
      while the other fifteen use thehudaacademy.org. Both are reproduced as
      the concept wrote them rather than silently corrected. NOT YET WRITTEN
      INTO docs/CLIENT-BRIEF.md - this build was scoped to this page and its
      stylesheet only, so the brief entry is still owed. The school has to
      confirm both addresses before this page is published.

   6. RETIRED WITH THE HERO, 2026-09-27. .abf-word-one CLEARED THE ARCH.
      "Early learning" sat outside the curve at the concept's own `left:9%`
      and was clipped from 561px up; it was corrected to 13% (10% narrow).
      The word, the arch and the correction are all gone now.

   Everything else is the concept's, including the things that read oddly - the
   `!important`s on .welcome-note, the unused --sand token, the `color:white`
   keyword next to hex everywhere else. The copy is its copy, the names are its
   names, and the numbers are its numbers.
   ========================================================================== */

/* ---------- PAGE ROOT - the concept's :root tokens and its body rule, scoped -- */
.abf-page{--ink:#271810;--rust:#93211B;--rust-deep:#612116;--cream:#EFE8DC;--paper:#F8F4EE;--sand:#F7B551;--muted:#726057;--shadow:0 24px 70px rgba(60,27,9,.18)}
:where(.abf-page) *{box-sizing:border-box}
/* line-height:normal is INHERITANCE, not styling, and it is the difference
   between porting a stylesheet and porting a page. The concept sets no
   line-height on <body>, so everything without its own inherits `normal`. Here
   the page sits under site.css, whose body carries line-height:1.6, so without
   this line every element that does not set its own renders ~28% taller - the
   same measurement that was made on /about/student-services/ before it was put
   back there. */
.abf-page{margin:0;background:var(--paper);color:var(--ink);font-family:"DM Sans",sans-serif;line-height:normal}
:where(.abf-page) a{color:inherit;text-decoration:none}
:where(.abf-page) button{font:inherit}
:where(.abf-page) img{display:block;width:100%;height:100%;object-fit:cover}
/* The concept's own, and this page actually uses it: .abf-section-nav is
   five live in-page anchors (six with the retired hero's jump link). DEVIATION 4 is the companion
   rule - smooth travel to a destination parked under a sticky nav is still the
   wrong destination. */
html{scroll-behavior:smooth}
.abf-page [id]{scroll-margin-top:calc(var(--nav-h) + 22px)}

/* ---------- EYEBROW - the one label style the whole page shares ---------- */
.abf-eyebrow{font-size:11px;font-weight:700;letter-spacing:.22em;text-transform:uppercase;color:var(--rust)}

/* ---------- HERO AND ARCH FIELD: MOVED TO THE MASTER, 2026-09-27 ---------
   The concept's hero - the crumbs, "Meet our educators.", the lede, the
   "Explore the faculty" jump and the rust arch field with its five floating
   words - is gone. The client decided that every interior page opens with the
   one master hero, and assets/css/page-hero.css owns it. Do not restyle the
   hero here: a rule in this file that reaches into .page-hero makes this page
   the odd one out, which is exactly what the decision was made to end.
   DEVIATION 6 (.abf-word-one pulled inside the arch) went with the field, and
   DEVIATION 1 now covers two dark grounds rather than three. */

/* ---------- WELCOME - deep band, Arabic watermark, three-cell ribbon -----
   DEVIATION 1 again: flat var(--rust-deep) in the concept. The watermark is
   the concept's own :before and stays exactly where it drew it; .welcome-inner
   carrying position:relative is also the concept's, and it is what keeps the
   copy painting above that watermark. */
.abf-welcome{background:linear-gradient(180deg,#762117 0%,#612116 100%);color:#FDF8F1;padding:clamp(80px,9vw,130px) clamp(24px,7vw,120px) 0;position:relative;overflow:hidden;isolation:isolate}
.abf-welcome:before{content:"تعليم";position:absolute;right:-15px;top:-25px;font-family:"Libre Caslon Display",serif;font-size:clamp(150px,22vw,340px);color:rgba(253,248,241,.04);line-height:1}
.abf-welcome-inner{max-width:1380px;margin:auto;display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(45px,9vw,150px);align-items:end;position:relative}
.abf-welcome .abf-eyebrow{color:#FFC35E}
.abf-welcome h2{font-family:"Libre Caslon Display",serif;font-size:clamp(50px,6vw,91px);font-weight:400;line-height:.98;letter-spacing:-.04em;margin:18px 0 0;max-width:760px}
.abf-welcome-copy{padding-bottom:8px}
.abf-welcome p{font-size:18px;line-height:1.78;color:#DFD0CA;max-width:650px;margin:0}
.abf-welcome-note{font-family:"Libre Caslon Display",serif!important;font-size:clamp(23px,2.3vw,34px)!important;color:#FFD379!important;margin-top:30px!important;max-width:680px;line-height:1.35!important}
.abf-welcome-ribbon{max-width:1380px;margin:clamp(60px,7vw,95px) auto 0;display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid rgba(253,248,241,.2)}
.abf-welcome-ribbon span{padding:29px 20px 34px;font-family:"Libre Caslon Display",serif;font-size:clamp(21px,2vw,29px);color:#F2E0BF;text-align:center}
.abf-welcome-ribbon span+span{border-left:1px solid rgba(253,248,241,.2)}

/* ---------- DIRECTORY - heading, the five jump pills, then the groups ---- */
.abf-directory{background:var(--paper);padding:clamp(85px,9vw,140px) clamp(22px,7vw,120px)}
.abf-directory-shell{max-width:1440px;margin:auto}
.abf-directory-head{display:grid;grid-template-columns:1.15fr .85fr;gap:60px;align-items:end;margin-bottom:48px}
.abf-directory h2{font-family:"Libre Caslon Display",serif;font-size:clamp(53px,6.4vw,96px);font-weight:400;line-height:.96;letter-spacing:-.045em;margin:17px 0 0;max-width:850px}
.abf-directory-head p{font-size:17px;line-height:1.75;color:var(--muted);margin:0;max-width:520px}
/* THESE ARE JUMP LINKS, NOT FILTER TABS, and that is the concept's design.
   Nothing on this page is hidden, by JS or otherwise: all twenty-four people
   are in the document at all times and these five pills scroll to a division.
   A filter would have put "content visibility depends on JS" back on a page
   whose entire job is listing people. */
.abf-section-nav{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:clamp(80px,9vw,135px)}
.abf-section-nav a{padding:11px 17px;border-radius:999px;background:#EBE1D0;color:#664941;font-size:13px;font-weight:600;transition:.25s}
.abf-section-nav a:hover{background:var(--rust);color:white;transform:translateY(-2px)}

/* ---------- A DIVISION - story column left, the name list right ---------- */
.abf-faculty-group{display:grid;grid-template-columns:minmax(260px,.62fr) minmax(0,1.38fr);gap:clamp(48px,8vw,125px);align-items:start;padding:0 0 clamp(78px,9vw,125px);margin:0 0 clamp(78px,9vw,125px);border-bottom:1px solid rgba(39,24,16,.15);position:relative}
.abf-faculty-group:last-child{margin-bottom:0;border-bottom:0;padding-bottom:0}
.abf-group-story{padding-top:7px}
.abf-group-story h3{font-family:"Libre Caslon Display",serif;font-size:clamp(38px,4.2vw,64px);font-weight:400;line-height:1;margin:14px 0 19px}
.abf-group-story>p{font-size:15px;line-height:1.72;color:var(--muted);margin:0;max-width:380px}
.abf-people{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:clamp(35px,5vw,75px)}
.abf-person{min-height:114px;padding:19px 55px 20px 0;border-bottom:1px solid rgba(39,24,16,.18);display:flex;flex-direction:column;justify-content:center;position:relative;transition:padding .3s,color .3s}
.abf-person:after{content:"Email ↗";position:absolute;right:0;top:50%;transform:translateY(-50%);font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--rust);opacity:.6;transition:opacity .25s,transform .25s}
.abf-person:hover{padding-left:10px;color:var(--rust)}
.abf-person:hover:after{opacity:1;transform:translate(3px,-50%)}
/* One person in the concept has no address yet and ships as a <div> rather
   than an <a>, so the "Email" affordance has to come off with it. Do not turn
   this into a mailto: - an invented address is the one failure mode a staff
   directory cannot recover from. */
.abf-person.abf-no-email:after{display:none}
.abf-person-name{font-family:"Libre Caslon Display",serif;font-size:clamp(24px,2.1vw,32px);line-height:1.08}
.abf-person-role{font-size:11px;line-height:1.5;letter-spacing:.12em;text-transform:uppercase;color:#876E61;margin-top:9px}

/* ---------- THE FAITH BAND - one division bled full width ----------------
   DEVIATION 1 for the third time. The negative side margins are the concept's
   and they cancel .abf-directory's own padding exactly (-7vw against 7vw), so
   the band reaches both edges without ever being wider than the viewport;
   site.css's overflow-x:clip is the backstop, not the mechanism.
   `position:relative` and `isolation:isolate` are NOT the concept's - they are
   what the noise film needs, see DEVIATION 1 and .abf-noise. */
.abf-faith-wrap{background:linear-gradient(180deg,#9E231D 0%,#93211B 100%);margin:0 clamp(-120px,-7vw,-22px) clamp(-140px,-9vw,-85px);padding:clamp(85px,9vw,135px) clamp(22px,7vw,120px) clamp(95px,10vw,150px);color:white;position:relative;isolation:isolate}
.abf-faith-wrap .abf-faculty-group{max-width:1440px;margin:0 auto}
.abf-faith-wrap .abf-group-story>p{color:#E6D4CE}
.abf-faith-wrap .abf-eyebrow{color:#FFC662}
.abf-faith-wrap .abf-person{color:white;border-color:rgba(255,255,255,.25)}
.abf-faith-wrap .abf-person-role{color:#E2D0C9}
.abf-faith-wrap .abf-person:after{color:#FFCE70}
.abf-faith-wrap .abf-person:hover{color:#FFD87E}

/* ---------- VISIT - the one call to action ------------------------------- */
.abf-visit{background:var(--cream);padding:clamp(85px,9vw,140px) clamp(24px,7vw,120px);position:relative;overflow:hidden}
.abf-visit-inner{max-width:1260px;margin:auto;display:grid;grid-template-columns:1.15fr .85fr;gap:70px;align-items:center}
.abf-visit h2{font-family:"Libre Caslon Display",serif;font-size:clamp(48px,5.6vw,84px);font-weight:400;line-height:1.02;letter-spacing:-.04em;margin:16px 0 0}
.abf-visit p{font-size:17px;line-height:1.75;color:var(--muted);margin:0 0 28px;max-width:520px}
.abf-btn{display:inline-flex;align-items:center;justify-content:space-between;gap:28px;background:var(--rust);color:white;padding:17px 20px;min-width:225px;border-radius:3px;font-size:14px;font-weight:700;transition:.3s}
.abf-btn:hover{background:var(--rust-deep);transform:translateY(-3px)}

/* ---------- MOTION ------------------------------------------------------
   DEVIATION 2. Three guards, the same shape the sibling ports use:
     1. gated on `html.js`, set by the shell's inline <head> script - with
        scripting off nothing is ever hidden and all twenty-four names are
        simply there;
     2. revealed per element by `.abf-in`, added by this page's own script as
        each block scrolls in, which is what preserves the concept's stagger;
     3. revealed wholesale by `html.abf-revealed`, set by a 6s timer in this
        page's inline <head> script if the page script never armed.
   Only content carries [data-rv], never a control - CLAUDE.md, the burger bug.
   The in-page navigation, .abf-section-nav, is a control and is
   deliberately outside the reveal set, as the hero's .abf-jump was. */
:where(.abf-page) [data-rv]{transition:opacity .75s ease,transform .75s cubic-bezier(.2,.7,.2,1)}
html.js :where(.abf-page) [data-rv]{opacity:0;transform:translateY(24px)}
html.js :where(.abf-page) [data-rv].abf-in{opacity:1;transform:none}

@media(max-width:1100px){
  .abf-faculty-group{grid-template-columns:270px 1fr;gap:55px}
  .abf-people{grid-template-columns:1fr}
}
@media(max-width:800px){
  .abf-welcome-inner{grid-template-columns:1fr}
  .abf-welcome-copy{padding-top:10px}
  .abf-directory-head{grid-template-columns:1fr;gap:22px}
  .abf-faculty-group{grid-template-columns:1fr;gap:30px}
  .abf-group-story{max-width:600px}
  .abf-people{grid-template-columns:repeat(2,minmax(0,1fr))}
  .abf-visit-inner{grid-template-columns:1fr;gap:28px}
}
@media(max-width:560px){
  .abf-welcome{padding-left:22px;padding-right:22px}
  .abf-welcome-ribbon{grid-template-columns:1fr;padding:18px 0}
  .abf-welcome-ribbon span{padding:15px 0;text-align:left}
  .abf-welcome-ribbon span+span{border-left:0}
  .abf-directory{padding-left:16px;padding-right:16px}
  .abf-section-nav{flex-wrap:nowrap;overflow-x:auto;padding-bottom:8px}
  .abf-section-nav a{white-space:nowrap}
  .abf-people{grid-template-columns:1fr}
  .abf-person{min-height:105px}
  .abf-faith-wrap{margin-left:-16px;margin-right:-16px;padding-left:16px;padding-right:16px}
  .abf-visit{padding-left:22px;padding-right:22px}
}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  :where(.abf-page) *,:where(.abf-page) *:before,:where(.abf-page) *:after{animation:none!important;transition:none!important}
  :where(.abf-page) [data-rv]{opacity:1;transform:none}
  /* The one thing the concept's own reduced-motion block cannot know about:
     with motion reduced the reveal must not be left hidden, because our gate
     is a class rather than its observer. */
  html.js :where(.abf-page) [data-rv]{opacity:1;transform:none}
}

/* ==========================================================================
   WHY :where(.abf-page) AND NOT .abf-page

   Scoping a bare element selector to a page is not free: `.abf-page a` is
   (0,1,1) where the concept's `a` is (0,0,1), and that extra class is enough to
   flip the cascade. It did, on the sibling port: `a{color:inherit}` is meant to
   LOSE to `.btn{color:white}`, and as `.ss-page a` it won, so the contact
   button came out cream-on-cream. `:where()` contributes zero specificity, so
   every scoped selector here has exactly the specificity the concept's does and
   the scoping is pure containment.

   THE SAME INFLATION BREAKS THE REVEAL if you let it. The hide rule
   `html.js :where(.abf-page) [data-rv]` is (0,2,1); the per-element reveal
   `html.js :where(.abf-page) [data-rv].abf-in` is (0,3,1) and wins, and the
   wholesale failsafe `html.abf-revealed :where(.abf-page) [data-rv]` is (0,2,1)
   - a tie, won on source order, which is why it is the last rule in this file
   and must stay there.
   ========================================================================== */

/* ---------- the house-rule additions -------------------------------------- */
/* THE NOISE FILM THAT PAYS FOR EVERY GRADIENT ABOVE. Identical turbulence and
   opacity to site.css's `.mission7__noise`, `.footer__noise` and every sibling
   port - the standing fix, not a new effect. There is no shared `.noise-overlay`
   utility in this repo to reuse; the convention is one prefixed copy per page
   stylesheet, and this is that copy.

   z-index:-1 puts it over its band's gradient and under the band's content
   without needing a position on any of that content. A NEGATIVE z-index ONLY
   STAYS INSIDE ITS PARENT IF THAT PARENT IS A STACKING CONTEXT, and
   position:relative alone is not one - this is the bug DESIGN-LIBRARY records
   twice, where the layer rendered with correct geometry and was simply
   invisible underneath. `isolation:isolate` on the two bands (three until the
   hero's arch field retired, 2026-09-27) is what makes
   it hold, and mix-blend-mode needs that same isolation to blend against its
   own band rather than the page. */
.abf-welcome,.abf-faith-wrap{isolation:isolate}
.abf-noise{position:absolute;inset:0;z-index:-1;opacity:.035;
  mix-blend-mode:overlay;pointer-events:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/></svg>")}

/* THE FAILSAFE'S ESCAPE HATCH. The inline <head> script adds .abf-revealed to
   <html> at 6s if the page script never armed, and this is what that class
   does. It is a SEPARATE class from site.css's `.rv`/`html.in` pair on purpose:
   site.js block 3 adds `in` immediately on any page that has no .stat elements,
   and this page has none, so sharing the pair would reveal everything on load
   and throw the concept's scroll fade away entirely.

   `transition:none` IS THE WHOLE POINT OF THE RULE, not tidiness. CLAUDE.md,
   the burger bug of 2026-08-04: a RUNNING css transition is a higher cascade
   origin than author !important, so an element whose opacity 0 -> 1 transition
   has started and never finished - a backgrounded tab, a bfcache restore,
   throttled timers - is pinned at its START value, and a failsafe that only
   sets opacity:1 loses to it. Cancelling the transition makes the element jump
   to the end value instead of racing toward it. `visibility` is belt and
   braces for the same reason. Measured on the sibling pages at t+85s in a
   background tab: 19 of 19 elements still invisible with the transition alive.

   LAST RULE IN THE FILE ON PURPOSE - see the specificity note above. */
html.abf-revealed :where(.abf-page) [data-rv]{opacity:1;visibility:visible;transform:none;transition:none}
