/* ==========================================================================
   Huda Academy — About Our School (/about/)

   Loaded ONLY by about/index.html, after site.css and never instead of it.

   WHAT THIS IS. A port of the client's concept page,
   <https://huda-academy-about-concept.ahmed206429.chatgpt.site/>, captured
   2026-09-18. The client asked for it one-to-one, changing only what is clearly
   wrong. The concept's 106 rules are all here; the deviations are each marked
   DEVIATION with the reason, and there are twelve of them (6 is retired, so
   the live count is eleven; the numbers are kept stable rather than renumbered
   so an old note that cites one still points at the right thing).

   EVERYTHING IS NAMESPACED `abt-`, AND THAT IS NOT TIDINESS.
   site.css already owns .hero (13 rules), .stats (5), .cta (5), .btn (9) and
   .stat (8) for the home page. Two of those collisions are actively dangerous:

     - site.js block 3 does querySelectorAll('.stat') and then reads
       .stat__num off each hit. A bare `.stat` here with no .stat__num child
       makes `num` null, `num.getAttribute` throws, and site.js dies at block 3
       — taking the nav drawer, the lightbox and every reveal below it with it.
     - site.css .hero is built around the home page's video and 100svh sizing.

   So the concept's class names all carry the prefix. Nothing on this page can
   be reached by a site.css selector written for the home page, and nothing here
   can reach the home page either.

   TOKENS. The concept's palette is kept as authored, except the two reds —
   see DEVIATION 1. Tokens are declared on .abt rather than :root, because
   :root belongs to site.css and this file is a guest on one page.
   ========================================================================== */

.abt {
  /* The concept's own values, read off its stylesheet.

     DEVIATION 1 — the two reds are the site's, not the concept's.
     Concept: --rust #A72820, --rust2 #7D261B.
     Site:    --terracotta #A83226, --terracotta-deep #86251B.
     Under 3 ΔE apart, so nothing about the concept's look changes — but the
     page now sits under the real nav, which is painted --terracotta. Two reds
     that close together, adjacent on one screen, read as a mistake rather than
     a choice. One red on the page. */
  --abt-rust: var(--terracotta);
  --abt-rust2: var(--terracotta-deep);

  /* Kept as the concept authored them. Each is far enough from its site.css
     neighbour to be a real choice rather than a rounding error: the concept's
     paper is near-white where site.css's is a warm cream, and its gold is
     deeper than the hero's. Mapping them would have repainted the page. */
  --abt-cream: #F4EEE4;   /* site --paper-2 is #EEE7DC — visibly deeper */
  --abt-paper: #F8F4EE;   /* site --paper   is #F8F4EE — visibly warmer */
  --abt-gold: #CFAF82;    /* site --gold    is #F2A33A — visibly lighter */
  --abt-ink: var(--ink);  /* #23160C vs #34231A: same colour, use the token */
  --abt-line: rgba(35,22,12,.18);
  --abt-shadow: 0 24px 60px rgba(64,30,14,.14);

  background: var(--abt-paper);
  color: var(--abt-ink);
  font-family: "DM Sans", Inter, ui-sans-serif, system-ui, sans-serif;
  /* DEVIATION 3 — the concept's `body{overflow-x:hidden}` is NOT copied.
     site.css already sets `html,body{overflow-x:clip}`, and CLAUDE.md is
     explicit that `hidden` must never be used: it makes <body> a scroll
     container, which re-parents every position:sticky on the page. This page
     has one — .abt-section-no, the outlined "01" — so copying the concept
     verbatim would have broken the concept's own sticky numeral. */
}

/* DEVIATION 4 — the concept's global rules are scoped, not global.
   It ships `img{width:100%;height:100%;object-fit:cover}` and
   `a{color:inherit;text-decoration:none}` unscoped. Unscoped here, the img
   rule would stretch the nav's logo lockup and the footer mark to fill their
   boxes. site.css already handles `img{display:block}` and `a{color:inherit}`
   for the shell, so this only adds what the concept's own pictures need. */
.abt img { width: 100%; height: 100%; object-fit: cover; }
.abt a { text-decoration: none; }

/* ---------- reveals ------------------------------------------------------
   DEVIATION 5 — the concept hides content with a bare `[data-reveal]{opacity:0}`
   and nothing else. If its script 404s or throws, the whole page body stays
   invisible forever. That is the exact failure CLAUDE.md's "content visibility
   must never depend on JS or an animation firing" rule was written against.

   Three guards, matching how site.css already does it for `.rv`:
     1. gated on `html.js`, which the inline <head> script sets — so with no
        JS at all, nothing is ever hidden in the first place;
     2. revealed per element by `.is-in`, which the page's own small script
        adds as each one scrolls in — this is what preserves the concept's
        staggered fade-up;
     3. revealed wholesale by `html.abt-revealed`, which a 6s timer in the
        page's inline <head> script sets if the page script never armed.

   WHY NOT REUSE site.css's `.rv`. Because `.rv` is an all-at-once gate keyed
   to `html.in`, and site.js adds `in` IMMEDIATELY on any page with no `.stat`
   elements (block 3 falls into its `else`). This page has none by design, so
   `.rv` would reveal everything on load and the concept's scroll fade would be
   gone. Only content carries these — never a control, per CLAUDE.md. */
html.js .abt [data-rv] {
  opacity: 0;
  transform: translateY(32px);
  transition: opacity .8s ease, transform .8s cubic-bezier(.2, .7, .2, 1);
}
/* SPLIT 2026-09-30 (Codex audit). `.is-in` used to share this rule, so it got
   `transition:none` too and the 0.8s fade-up never played: every element
   jumped. Only the wholesale failsafe needs to cancel the transition; the
   normal reveal keeps it. A fade that stalls is now caught by the head
   script's SWEEP, which ends it with an inline transition:none. */
html.js .abt [data-rv].is-in {
  opacity: 1;
  transform: none;
}
html.abt-revealed .abt [data-rv] {
  /* `transition:none` is the whole point of this rule, not a tidy-up. A
     RUNNING transition outranks author !important, so a 0->1 opacity
     transition that never advances a frame (background tab, bfcache
     restore, throttled timers) pins the element at 0 and no failsafe
     rule can override it. Cancelling it makes the element jump to the
     end value instead of racing toward it, so the failsafe cannot lose. */
  opacity: 1;
  transform: none;
  transition: none;
}
.abt .delay-1 { transition-delay: .1s; }
.abt .delay-2 { transition-delay: .2s; }

/* ---------- hero: MOVED to assets/css/page-hero.css, 2026-09-27 ----------
   This page's hero became the MASTER HERO every interior page uses, so its
   rules left this file: one definition, in page-hero.css, rendered into the
   page by tools/build-pages.py. docs/HERO-STANDARD.md carries the reasoning
   that used to sit here (the fitted height, DEVIATION 7's 420px headline, the
   short-screen treatment, the 2026-09-27 fixes). Do not restyle the hero from
   this file - `.abt` rules still reach inside it, and a page that restyles
   its own hero is exactly the drift the master exists to end.

   Kept below: .abt-eyebrow, .abt-btn and .abt-textlink, which the rest of
   this page still uses. */
.abt-eyebrow {
  color: var(--abt-rust);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .2em;
  margin-bottom: clamp(8px, 2.2svh, 19px);
}

.abt-btn {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  background: var(--abt-rust);
  color: #FFFFFF;
  padding: clamp(10px, 1.8svh, 17px) 22px;
  border-radius: 3px;
  font-size: 14px;
  font-weight: 700;
  transition: background .3s, transform .3s;
}
.abt-btn:hover { background: var(--abt-rust2); transform: translateY(-2px); }
.abt-textlink {
  font-size: 14px;
  font-weight: 700;
  border-bottom: 1px solid var(--abt-ink);
  padding-bottom: 4px;
}

/* DEVIATION 6 IS RETIRED — the scroll cue it was about is gone (client,
   2026-09-19). It recorded that the concept's `animation:bob 2s infinite` was
   not ported, because CLAUDE.md allows exactly one perpetual animation on this
   site and a decorative bob on an About page does not clear that bar. Kept as
   a note rather than deleted: the reasoning still binds anything that tries to
   reintroduce a bobbing affordance here. */
/* ---------- stat band: rules removed 2026-09-19 with the markup. ----
   See the note in about/index.html where the section used to be. */

/* ---------- story --------------------------------------------------------- */
.abt-story {
  padding: clamp(100px, 12vw, 180px) clamp(26px, 8vw, 142px);
  display: grid;
  grid-template-columns: .75fr 1.25fr;
  gap: clamp(55px, 9vw, 150px);
  position: relative;
}
.abt-section-no {
  font-family: "Libre Caslon Display", "Cormorant Garamond", Georgia, serif;
  font-size: clamp(120px, 16vw, 250px);
  line-height: .65;
  color: transparent;
  -webkit-text-stroke: 1px rgba(168,50,38,.25);
  position: sticky;
  /* The concept parks this at 130px, clear of its own 90px nav. Ours is
     --nav-h (88px) once the banner scrolls away, so the same visual gap lands
     at nav-h + 42. Derived from the token rather than restated, so it follows
     the nav if the nav ever moves. */
  top: calc(var(--nav-h) + 42px);
  height: min-content;
}
.abt-section-no small {
  display: block;
  font-family: "DM Sans", Inter, sans-serif;
  -webkit-text-stroke: 0;
  color: var(--abt-rust);
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  margin: 40px 0 0 9px;
}
/* font-weight 400 (2026-09-27): Libre Caslon Display ships ONE weight, 400 (the
   Google Fonts request has no wght axis). Without this the browser's default h2
   bold made Chrome synthesize a 700 by smearing the 400 outlines - letters
   thicken unevenly and the dot of an "i" grows a ring. Never ask this face for
   anything but 400. (The "Continue exploring" headline that used to share this
   rule is assets/css/links-system.css now.) */
.abt-story h2,
.abt-experience h2 {
  font-family: "Libre Caslon Display", "Cormorant Garamond", Georgia, serif;
  font-weight: 400;
  font-size: clamp(43px, 5vw, 73px);
  line-height: 1.03;
  letter-spacing: -.025em;
  margin: 0 0 30px;
}
.abt-dropcap::first-letter {
  font-family: "Libre Caslon Display", "Cormorant Garamond", Georgia, serif;
  color: var(--abt-rust);
  font-size: 82px;
  float: left;
  line-height: .72;
  margin: 12px 12px 0 0;
}
/* DEVIATION 9 — min-width:0 on the two grid children that can refuse to shrink.
   Not in the concept, which leaves both at the `auto` default. A grid item at
   min-width:auto will not go narrower than the widest unbreakable thing inside
   it, and inside these two are headlines set in a display serif at
   clamp(43px,5vw,73px). Between about 900px and 1100px the story column won
   that argument, pushed past its track, and took the document sideways —
   the same shape of bug as the events-carousel bleed in CLIENT-BRIEF §7, and
   caught the same way, by sweeping the widths rather than by eye. */
.abt-story__body,
.abt-experience__head > * { min-width: 0; }

/* DEVIATION 11 — the body-copy rule is scoped to the body, not to the section.
   The concept writes this as `.story p`, which is fine for the concept because
   its eyebrow and its big outlined numeral are both <div>. Written that way
   here it reaches anything in the section that is ever marked up as a
   paragraph, and a tag in the selector outranks a bare class: `.abt-story p`
   is (0,1,1) and `.abt-section-no` is (0,1,0), so the numeral rendered at 18px
   in body brown instead of 250px and transparent. Measured, not spotted — with
   `.abt-eyebrow`'s letter-spacing and text-transform still applying, the
   result looked plausible in a screenshot.

   Scoped to `.abt-story__body` so it can only reach the two prose paragraphs
   it was written for. The same reasoning applies to `.abt-cta p` and
   `.abt-experience__head p` below; those two are already tight enough because
   the elements they could reach are all <div> again, as the concept has them. */
.abt-story__body p { font-size: 18px; line-height: 1.8; color: #5C4C46; max-width: 720px; }
.abt-quote {
  margin: 70px 0;
  border-top: 1px solid var(--abt-line);
  border-bottom: 1px solid var(--abt-line);
  padding: 45px 0;
  font-family: "Libre Caslon Display", "Cormorant Garamond", Georgia, serif;
  font-size: clamp(28px, 3vw, 42px);
  line-height: 1.25;
}
.abt-quote::before {
  content: "\201C";
  color: var(--abt-rust);
  font-size: 70px;
  line-height: 0;
  vertical-align: -.27em;
  margin-right: 8px;
}

.abt-collage { height: 560px; position: relative; margin-top: 74px; }
.abt-collage__main {
  width: 78%;
  height: 100%;
  margin-left: auto;
  box-shadow: var(--abt-shadow);
}
.abt-collage__small {
  position: absolute;
  width: 42%;
  height: 49%;
  left: 0;
  bottom: -44px;
  border: 10px solid var(--abt-paper);
  box-shadow: var(--abt-shadow);
}
/* DEVIATION 10 — no backdrop-filter on the caption.
   The concept sets `backdrop-filter:blur(8px)` here. site.css §nav records what
   that costs on this project: a blurred sticky layer over moving content stalled
   the renderer hard enough to freeze screenshots, and the nav's backdrop-filter
   was removed for it. This page would have stacked FOUR of the things that
   caused that — a blurred plate, a position:sticky numeral, a scroll handler
   writing transforms, and a blended noise layer — and it froze the renderer on
   scroll while it did.

   The plate is opaque instead, which is exactly what site.css's own
   `@supports not (backdrop-filter...)` branch falls back to. On an 11px
   uppercase label sitting on a photograph the blur was never doing visible
   work; the opacity is lifted .82 -> .88 to make up the small contrast the
   blur was contributing. */
.abt-caption {
  position: absolute;
  right: 18px;
  bottom: 16px;
  background: rgba(29,15,7,.88);
  color: #FFFFFF;
  padding: 11px 14px;
  font-size: 11px;
  letter-spacing: .09em;
  text-transform: uppercase;
}

/* ---------- the green band -----------------------------------------------
   DEVIATION 2 — the concept's flat `background:#203429` is a two-stop gradient
   plus a noise layer.

   This is the standing bug in the user's global CLAUDE.md, not a preference.
   A perfectly flat dark solid makes the display pipeline spatial-dither it,
   and the dither shows as a diagonal hairline at slope ~0.13 spanning the full
   viewport — in screenshots too, because on Windows the dither is applied
   before the framebuffer is read. Break up the flat colour and there is
   nothing for the pattern to latch onto.

   The two stops bracket the original: #24392D is (36,57,45) and #1B2D23 is
   (27,45,35), which average to (31.5,51,40) against the concept's #203429 at
   (32,52,41). The band is the colour the client picked; it simply is not flat.

   The green itself is a deliberate exception the client made. DESIGN-LIBRARY.md
   records the palette as closed after three rejected attempts at a third
   colour, ending in "do not propose a fourth colour". This one was asked and
   confirmed on 2026-09-18 before any of it was built. It is scoped to this one
   band on this one page and is not a reopening of the palette. */
.abt-experience {
  background: linear-gradient(180deg, var(--abt-green-hi), var(--abt-green-lo));
  color: #F6F1E9;
  padding: clamp(95px, 11vw, 170px) clamp(28px, 8vw, 140px);
  position: relative;
  overflow: hidden;
}
.abt-experience__noise {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: .035;
  mix-blend-mode: overlay;
  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 concept's decorative ring, kept. It sits above the noise, so it needs
   its own stacking context or the blend mode eats it. */
.abt-experience::before {
  content: "";
  position: absolute;
  width: 520px;
  height: 520px;
  border: 1px solid rgba(207,175,130,.15);
  border-radius: 50%;
  right: -170px;
  top: -220px;
  pointer-events: none;
}
/* The content sits above the noise. Named explicitly rather than written as
   `.abt-experience > *`, which was the first attempt and was wrong: the noise
   layer is ALSO a direct child, the two selectors have identical specificity
   (0,1,0), and the later one won — so `position:absolute;inset:0` on the noise
   silently became `position:relative;inset:0` and the layer stopped covering
   the band it exists to break up. */
.abt-experience__head,
.abt-principles { position: relative; }
.abt-experience__head {
  display: grid;
  grid-template-columns: 1.1fr .9fr;
  gap: 80px;
  align-items: end;
  margin-bottom: 65px;
}
.abt-experience__head p {
  color: #D2DAD3;
  font-size: 17px;
  line-height: 1.75;
  max-width: 590px;
}
.abt-principles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid rgba(255,255,255,.22);
  /* `isolation` gives the photograph and the scrim a stacking context of their
     own, so their negative z-indexes stay behind the cards and in front of the
     band - without it they would fall behind .abt-experience's background and
     disappear entirely. */
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: clamp(520px, 44vw, 700px);
}
.abt-principles__art {
  position: absolute;
  z-index: -2;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Two scrims, not one. The vertical pass buys the copy its contrast at the
   bottom of the cards where the copy actually is; the horizontal pass only
   darkens the two outer edges, so the middle of the photograph stays a
   photograph. Same reasoning as the hero: one scrim cannot serve two parts of
   a frame with different brightness.

   THE STOPS ARE MEASURED, NOT CHOSEN. Composited against the real pixels of
   abt-guides.webp - each text block sampled on a 10x6 grid of its own
   footprint, keeping the BRIGHTEST patch, then run through both passes at that
   patch's own position. The first attempt (.42 at 48%) read fine and failed:

       block                 .42@48%   .60@38%   floor
       em   (numeral, 15px)    3.19      4.86     4.5   <- the one that failed
       small(eyebrow, 10px)    6.23      8.31     4.5
       h3   (31px)             9.79     12.04     3.0
       p    (15px)            10.10     10.37     4.5

   The gold numeral is the binding constraint and nothing else came close to
   its floor - it is the thinnest light thing on the page and it sits highest
   in the copy block, where the scrim is still opening up. Deepening it further
   buys almost nothing (.64@36% moves em to 5.26) and costs the photograph, so
   38%/.60 is where this stops. Re-measure if the photograph is ever swapped:
   these numbers are about THAT image's bright patches, not about the gradient. */
.abt-principles::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(20,26,18,.10) 16%, rgba(20,26,18,.60) 38%, rgba(20,26,18,.93) 100%),
    linear-gradient(90deg, rgba(20,26,18,.30), transparent 26%, transparent 74%, rgba(20,26,18,.26));
}
/* The cards are laid out from the bottom now that they sit on a picture: the
   top of each column is the photograph's, the bottom is the card's. */
.abt-principle {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}
.abt-principle {
  padding: 40px 34px 24px 0;
  border-right: 1px solid rgba(255,255,255,.22);
  position: relative;
  min-height: 250px;
  transition: background .35s, transform .35s;
}
.abt-principle:not(:first-child) { padding-left: 34px; }
.abt-principle:last-child { border-right: 0; }
.abt-principle em {
  font-family: "Libre Caslon Display", "Cormorant Garamond", Georgia, serif;
  color: var(--abt-gold);
  font-size: 15px;
}
/* The eyebrow under the numeral, and the corner arrow, are both from the
   2026-09-19 concept export. The arrow is a ::after on the card rather than a
   glyph in the markup on purpose: it is decoration on a link that already
   announces itself, so putting it in the DOM would have a screen reader read
   "up-right arrow" after every card title. */
.abt-principle small {
  display: block;
  margin-top: 11px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #DFD4BA;
}
.abt-principle::after {
  content: "↗";
  position: absolute;
  right: 34px;
  bottom: 24px;
  font-size: 22px;
  line-height: 1;
  color: var(--abt-gold);
  transition: transform .3s;
}
.abt-principle:hover::after,
.abt-principle:focus-visible::after { transform: translate(4px, -4px); }
.abt-principle h3 {
  font-family: "Libre Caslon Display", "Cormorant Garamond", Georgia, serif;
  font-weight: 400;
  font-size: 31px;
  margin: 26px 0 14px;
}
.abt-principle p { color: #C2CDC3; line-height: 1.65; font-size: 15px; }
.abt-principle:hover { background: rgba(255,255,255,.04); transform: translateY(-7px); }

/* ---------- continue exploring: MOVED to assets/css/links-system.css ------
   2026-09-27. This page's related-pages section became the MASTER every
   content page will carry (site-links*, rendered by tools/build-pages.py into
   the LINKS region of about/index.html). Its rules left this file - every one
   of .abt-links, .abt-linkgrid, .abt-feature and .abt-arrow - so there is one
   definition. Do not restyle it from here: `.abt` rules still reach inside it,
   and a page that restyles its own copy is the drift the master exists to end.
   Reference: docs/LINKS-STANDARD.md. */

/* ---------- closing CTA --------------------------------------------------- */
.abt-cta {
  margin: 0;
  background: var(--abt-paper);
  padding: clamp(90px, 10vw, 150px) 25px;
  text-align: center;
  position: relative;
  overflow: hidden;
}
.abt-cta .abt-eyebrow { margin-bottom: 20px; }
.abt-cta h2 {
  font-family: "Libre Caslon Display", "Cormorant Garamond", Georgia, serif;
  font-size: clamp(48px, 7vw, 95px);
  line-height: .96;
  max-width: 970px;
  margin: 0 auto 30px;
  letter-spacing: -.04em;
}
.abt-cta p {
  font-size: 18px;
  color: #62514A;
  max-width: 620px;
  margin: 0 auto 35px;
  line-height: 1.65;
}
.abt-cta .abt-btn { font-size: 15px; }
.abt-orbit {
  position: absolute;
  width: 420px;
  height: 420px;
  border: 1px solid rgba(168,50,38,.14);
  border-radius: 50%;
  left: -280px;
  top: 20px;
  pointer-events: none;
}
.abt-orbit.two {
  left: auto;
  right: -300px;
  top: 120px;
  width: 510px;
  height: 510px;
}

/* ---------- 1100 and down -------------------------------------------------
   The concept's own breakpoints, kept at its own widths. Its nav rules are
   dropped because the nav is ours now and site.css already handles it at 900. */
@media (max-width: 1100px) {
  .abt-story { grid-template-columns: .45fr 1.55fr; }
}

@media (max-width: 760px) {
  .abt-story { display: block; padding: 95px 24px 125px; }
  .abt-section-no {
    position: relative;
    top: auto;
    font-size: 130px;
    margin-bottom: 66px;
  }
  .abt-collage { height: 430px; margin-top: 55px; }
  .abt-collage__main { width: 88%; }
  .abt-collage__small { width: 54%; height: 43%; bottom: -48px; border-width: 7px; }
  .abt-experience { padding: 90px 24px; }
  .abt-experience__head { grid-template-columns: 1fr; gap: 20px; }
  .abt-principles {
    grid-template-columns: 1fr;
    min-height: 0;
    isolation: auto;
  }
  .abt-principles__art {
    position: relative;
    z-index: 0;
    height: auto;
    aspect-ratio: 2.2 / 1;
  }
  .abt-principles::after { display: none; }
  .abt-principle,
  .abt-principle:not(:first-child) {
    padding: 30px 0;
    border-right: 0;
    border-bottom: 1px solid rgba(255,255,255,.2);
    min-height: 0;
  }
  .abt-principle h3 { margin: 18px 0 10px; }
  .abt-principle::after { right: 0; bottom: 18px; }
}

/* The hero headline's 420px step (DEVIATION 7) moved to page-hero.css with
   the hero. */
@media (max-width: 420px) {
  .abt-cta h2 { font-size: clamp(34px, 11vw, 48px); }
  .abt-section-no { font-size: clamp(88px, 28vw, 130px); }
}

/* DEVIATION 8 — reduced motion.
   The concept's own block is kept, and one thing is added: it kills every
   transition with !important, which would ordinarily strand [data-rv] at
   opacity 0 forever, because the reveal IS a transition. The reveal state is
   forced open here instead. */
@media (prefers-reduced-motion: reduce) {
  .abt *,
  .abt *::before,
  .abt *::after {
    animation: none !important;
    transition: none !important;
  }
  html.js .abt [data-rv] { opacity: 1; transform: none; }
}

/* ========================================================================
   CLIENT REFRESH — 2026-09-19
   The About body now favors compact editorial structure over decorative
   devices: no sticky chapter numeral, no overlapping collage, no off-palette
   green band, and no interaction styling on non-navigation content.
   ======================================================================== */

/* Story: heading first, then a balanced prose/image spread. */
.abt-story {
  display: block;
  padding: clamp(82px, 9vw, 132px) clamp(24px, 5vw, 72px);
}
.abt-story__head {
  display: block;
  max-width: 1380px;
  margin: 0 auto clamp(42px, 4.5vw, 62px);
}
.abt-story__head .abt-eyebrow { margin: 0 0 18px; }
.abt-story__head h2 {
  max-width: 940px;
  margin: 0;
}
.abt-story__head > *,
.abt-story__content > * { min-width: 0; }
.abt-story__content {
  display: grid;
  grid-template-columns: minmax(310px, .76fr) minmax(0, 1.34fr);
  gap: clamp(46px, 6vw, 82px);
  align-items: start;
  max-width: 1380px;
  margin: 0 auto;
}
.abt-story__prose { max-width: 420px; }
.abt-story__prose p {
  max-width: none;
  font-size: 17px;
  line-height: 1.78;
  color: #5C4C46;
}
.abt-story__prose p:first-child { margin-top: 0; }
.abt-quote {
  margin: 42px 0 0;
  padding: 34px 0 0;
  border-top: 1px solid var(--abt-line);
  border-bottom: 0;
  font-size: clamp(25px, 2.35vw, 36px);
  line-height: 1.28;
}
.abt-collage {
  position: relative;
  height: 590px;
  min-height: 0;
  margin-top: 0;
  display: block;
}
.abt .abt-collage__main,
.abt .abt-collage__small {
  position: absolute;
  margin: 0;
  border: 0;
  object-fit: cover;
  border-radius: 14px;
}
.abt .abt-collage__main {
  inset: 0 auto auto 0;
  z-index: 1;
  width: 72%;
  height: 78%;
  margin-left: 0;
  box-shadow: var(--abt-shadow);
}
.abt .abt-collage__small {
  z-index: 2;
  inset: auto 0 0 auto;
  right: 0;
  bottom: 0;
  width: 49%;
  height: 64%;
  border: 0;
  box-shadow: 0 22px 46px rgba(50,26,13,.15);
}
.abt-caption {
  left: 18px;
  right: auto;
  top: calc(76% - 48px);
  bottom: auto;
}

/* Principles: static information, not faux cards or destinations. */
.abt-experience {
  background: var(--abt-cream);
  color: var(--abt-ink);
}
.abt-experience::before {
  width: 460px;
  height: 460px;
  border-color: rgba(168,50,38,.12);
  right: -210px;
  top: -250px;
}
.abt-experience__noise,
.abt-principles__art { display: none; }
.abt-experience .abt-eyebrow { color: var(--abt-rust) !important; }
.abt-experience__head p { color: #5C4C46; }
.abt-principles {
  min-height: 0;
  overflow: visible;
  isolation: auto;
  border-top: 1px solid var(--abt-line);
  border-bottom: 1px solid var(--abt-line);
}
.abt-principles::after { display: none; }
.abt-principle,
.abt-principle:not(:first-child) {
  display: block;
  min-height: 330px;
  padding: clamp(36px, 4vw, 58px) clamp(24px, 3.1vw, 48px);
  border-right: 1px solid var(--abt-line);
  color: var(--abt-ink);
  transform: none;
  background: transparent;
  transition: none;
}
.abt-principle:first-child { padding-left: 0; }
.abt-principle:last-child { border-right: 0; }
.abt-principle::after { content: none; }
.abt-principle em {
  color: var(--abt-rust);
  font-size: 44px;
  line-height: 1;
  opacity: .32;
}
.abt-principle small {
  margin-top: 22px;
  color: var(--abt-rust);
  font-size: 11px;
}
.abt-principle h3 {
  margin: 34px 0 16px;
  font-size: clamp(29px, 2.6vw, 39px);
}
.abt-principle p { margin: 0; color: #5C4C46; line-height: 1.7; }
.abt-principle:hover { background: transparent; transform: none; }

/* Related pages: MOVED to assets/css/links-system.css, 2026-09-27, with
   their history (DEVIATION 12's destination photographs, the 2026-09-27
   caption plate that replaced the photo tint). See the note where the
   "continue exploring" block used to be, above. */

@media (max-width: 1100px) {
  .abt-story { display: block; }
  .abt-story__content { grid-template-columns: minmax(260px, .82fr) minmax(0, 1.18fr); }
  .abt-collage { height: 540px; }
}

@media (max-width: 760px) {
  .abt-story { padding: 82px 24px; }
  .abt-story__head { display: block; margin-bottom: 42px; }
  .abt-story__head .abt-eyebrow { margin-top: 0; }
  .abt-story__content { display: block; }
  .abt-collage {
    height: 500px;
    margin-top: 46px;
  }
  .abt .abt-collage__main { width: 82%; height: 76%; }
  .abt .abt-collage__small { width: 53%; height: 52%; }
  .abt-principles { display: block; }
  .abt-principle,
  .abt-principle:not(:first-child),
  .abt-principle:first-child {
    min-height: 0;
    padding: 34px 0;
    border-right: 0;
    border-bottom: 1px solid var(--abt-line);
  }
  .abt-principle:last-child { border-bottom: 0; }
}

@media (max-width: 480px) {
  .abt-collage { height: 430px; }
  .abt-caption { left: 12px; right: 12px; text-align: center; }
}

/* What guides us — approved "Type as Weight" direction.
   The three ideas share one field; typographic scale supplies their visual
   weight instead of cards, dividers, or a full-screen interaction. */
.abt-experience {
  padding: clamp(34px, 4vw, 56px) clamp(24px, 5vw, 74px);
  background: var(--abt-cream);
  color: #F8F4EE;
  overflow: hidden;
}
.abt-experience::before { content: none; }
.abt-experience__field {
  position: relative;
  max-width: 1410px;
  min-height: 620px;
  margin: 0 auto;
  padding: clamp(48px, 5.5vw, 82px);
  display: grid;
  grid-template-columns: minmax(300px, .72fr) minmax(610px, 1.28fr);
  gap: clamp(55px, 7vw, 110px);
  align-items: center;
  overflow: hidden;
  border-radius: 4px;
  background: linear-gradient(135deg, #7B1C12, #5F1E14);
}
.abt-experience__field::after {
  content: "";
  position: absolute;
  right: -200px;
  bottom: -310px;
  width: 620px;
  height: 620px;
  border: 1px solid rgba(207,175,130,.14);
  border-radius: 50%;
  box-shadow:
    0 0 0 72px rgba(207,175,130,.024),
    0 0 0 144px rgba(207,175,130,.016);
  pointer-events: none;
}
.abt-experience__field .abt-experience__noise {
  display: block;
  z-index: 0;
  opacity: .025;
}
.abt-experience__head,
.abt-experience__field .abt-principles {
  position: relative;
  z-index: 1;
}
.abt-experience__head {
  display: block;
  margin: 0;
}
.abt-experience .abt-eyebrow {
  color: var(--abt-gold) !important;
}
.abt-experience__head h2 {
  margin: 17px 0 24px;
  color: #F8F4EE;
  font-size: clamp(45px, 5.2vw, 73px);
  line-height: .95;
  letter-spacing: -.045em;
}
.abt-experience__head p {
  max-width: 440px;
  margin: 0;
  color: rgba(248,244,238,.72);
  font-size: 15.5px;
  line-height: 1.65;
}
.abt-experience__field .abt-principles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 40px 50px;
  min-height: 0;
  overflow: visible;
  border: 0;
  isolation: auto;
}
.abt-experience__field .abt-principles::after { display: none; }
.abt-experience__field .abt-principle,
.abt-experience__field .abt-principle:not(:first-child),
.abt-experience__field .abt-principle:first-child {
  display: block;
  min-height: 180px;
  padding: 0;
  border: 0;
  color: #F8F4EE;
  background: transparent;
  transform: none;
  transition: none;
}
.abt-experience__field .abt-principle:last-child {
  grid-column: 1 / -1;
  width: 68%;
  min-height: 155px;
  margin-left: 16%;
}
.abt-experience__field .abt-principle::after { content: none; }
.abt-experience__field .abt-principle em {
  display: block;
  margin-bottom: 12px;
  color: var(--abt-gold);
  font-size: 16px;
  line-height: 1;
  opacity: 1;
}
.abt-experience__field .abt-principle h3 {
  margin: 0;
  color: #F8F4EE;
  font-size: clamp(38px, 3.6vw, 56px);
  line-height: .94;
  letter-spacing: -.035em;
}
.abt-experience__field .abt-principle small {
  display: block;
  margin-top: 13px;
  color: var(--abt-gold);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: .14em;
}
.abt-experience__field .abt-principle p {
  max-width: 330px;
  margin: 9px 0 0;
  color: rgba(248,244,238,.66);
  font-size: 13px;
  line-height: 1.55;
}

@media (max-width: 1000px) {
  .abt-experience__field {
    grid-template-columns: 1fr;
    gap: 45px;
    min-height: 0;
  }
  .abt-experience__head p { max-width: 650px; }
}

@media (max-width: 760px) {
  .abt-experience { padding: 18px; }
  .abt-experience__field { padding: 42px 26px; }
  .abt-experience__head h2 { font-size: 45px; }
  .abt-experience__field .abt-principles {
    grid-template-columns: 1fr;
    gap: 30px;
  }
  .abt-experience__field .abt-principle,
  .abt-experience__field .abt-principle:not(:first-child),
  .abt-experience__field .abt-principle:first-child,
  .abt-experience__field .abt-principle:last-child {
    grid-column: auto;
    width: auto;
    min-height: 0;
    margin: 0;
    padding: 0;
    border: 0;
  }
  .abt-experience__field .abt-principle h3 { font-size: 39px; }
}

/* ---------- how it began (client-approved and live 2026-09-30) ----------------------------
   The founding story, in the school's own words (their site + the 2019-2024
   strategic plan). It mirrors "Our story" above: there the words lead and the
   photographs follow; here the photograph leads and the words follow, so the
   two sections read as a pair. The ground steps to --abt-cream so the section
   edge reads without a rule line (client: no rules as layout). */
.abt-origin {
  background: var(--abt-cream);
  /* Tighter than the page's other sections (client, 2026-09-30: "a lot of white
     space both above and below"): 56-104px instead of 90-170px. */
  padding: clamp(56px, 6.5vw, 104px) clamp(26px, 8vw, 142px);
  display: grid;
  grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr);
  gap: clamp(48px, 6vw, 110px);
  align-items: stretch;
}
.abt-origin > * { min-width: 0; }   /* DEVIATION 9's reason applies here too */
/* The photograph (client swap, 2026-09-30): a carved mosque door with a pair of
   sandals left at the threshold - a beginning, and no people in frame. It is a
   PORTRAIT picture, so it can take the text column's full height and the two
   columns end exactly together; the crop stays close to the picture's own 3:4.
   No caption on it (client: the plate "sitting in the middle of the image" went).
   `order:-1` puts it on the left on desktop only; in the HTML the words come
   first, so a screen reader meets the heading before the photograph. */
.abt-origin__media { position: relative; margin: 0; min-height: 420px; order: -1; }
.abt-origin__media img { position: absolute; inset: 0; border-radius: 14px; box-shadow: var(--abt-shadow); object-position: 50% 60%; }   /* 14px: the Our story collage's own radius; 60% keeps the sandals in frame */
.abt-origin h2 {
  font-family: "Libre Caslon Display", "Cormorant Garamond", Georgia, serif;
  font-weight: 400;                  /* the face ships 400 only; see about.css */
  font-size: clamp(38px, 4.2vw, 62px);
  line-height: 1.05;
  letter-spacing: -.025em;
  margin: 0 0 34px;
}
/* The school's statement, set as the page's pull quote is set: Caslon, the rust
   opening mark, no box. Smaller than .abt-quote because it is three sentences,
   not one line. */
.abt-origin__statement {
  margin: 0;
  font-family: "Libre Caslon Display", "Cormorant Garamond", Georgia, serif;
  font-size: clamp(21px, 1.75vw, 27px);
  line-height: 1.45;
  color: var(--abt-ink);
}
.abt-origin__statement::before {
  content: "“";
  color: var(--abt-rust);
  font-size: 2.6em;                  /* scaled to match the page's .abt-quote mark */
  line-height: 0;
  vertical-align: -.4em;
  margin-right: 8px;
}
.abt-origin__src {
  margin: 18px 0 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #6B5A52;                    /* 6.1:1 on --abt-cream */
}
/* The founders' aim sits in the text column, under the statement (client,
   2026-09-30: "move that to the right"). */
.abt-origin__body {
  margin: 30px 0 0;
  font-size: 18px;
  line-height: 1.8;
  color: #5C4C46;
  max-width: 640px;
}
.abt-origin__body q { quotes: "“" "”"; }
/* Stacks at 1100: below that the text column is too narrow to sit beside the
   photo. Stacked, the words come first (as in Our story, and as in the HTML)
   and the door follows, cropped square and anchored low on the sandals. */
@media (max-width: 1100px) {
  .abt-origin { grid-template-columns: 1fr; }
  .abt-origin__media { order: 0; min-height: 0; aspect-ratio: 1 / 1; }
  .abt-origin__media img { object-position: 50% 88%; }   /* square, anchored low: door, rug and the sandals all in frame */
}
