/* SaderLex local site — shared editorial chrome (accent / cream / ink).
   Matches the bespoke home's design language: Almarai, the per-country accent
   (var(--lx-accent) — crimson for Lebanon, gold for the Emirates, declared in
   site-header.css), cream ground, ink text, hairline rules, sharp-ish radii.
   RTL. */
:root{
  --paper:#FFFFFF; --card:#FFFFFF; --ink:#16140F; --muted:#6E6A62;
  --accent:var(--lx-accent); --accent-dark:var(--lx-accent-shade); --hair:#E6E2DB; --near-black:#0C0C0D;
  --r:6px; --r-sm:4px; --font:'Almarai',system-ui,'Segoe UI',sans-serif;
  --shadow:0 1px 2px rgba(20,18,12,.05),0 8px 24px rgba(20,18,12,.05);
  --ease:cubic-bezier(.16,1,.3,1);
  /* glassmorphism: translucent surfaces that float over the animated mesh */
  --glass:rgba(255,255,255,.58); --glass-2:rgba(255,255,255,.74);
  --glass-brd:rgba(255,255,255,.65); --blur:saturate(1.25) blur(14px);
  --float:0 18px 46px -16px rgba(20,18,12,.36),0 6px 18px -8px rgba(20,18,12,.22);
  --float-lg:0 48px 100px -28px rgba(20,18,12,.54),0 18px 40px -16px rgba(20,18,12,.30);
  /* landing-page header tokens (names mirror home.html's inverted scheme) */
  --lx-black:#FFFFFF; --lx-line-d:rgba(20,18,12,.13);
  --lx-on-dark:#16140F; --lx-on-dark-soft:rgba(22,20,15,.60);
  /* --lx-accent (and the rest of the accent family) is NOT redeclared here: it
     is country-dependent now and static/site-header.css owns it. */
  --lx-ease:cubic-bezier(.16,1,.3,1);
  /* ONE reading-column width for the category pages. The search row and the
     results column below it BOTH read this, so the two can never drift out of
     alignment — change it here and they move together. */
  --lx-colw:820px;
}
*{box-sizing:border-box}
html,body{margin:0;padding:0}
body{
  font-family:var(--font); color:var(--ink); background:var(--paper);
  line-height:1.65; -webkit-font-smoothing:antialiased;
  background-image:radial-gradient(1200px 500px at 90% -5%,rgba(var(--lx-accent-rgb),.05),transparent 60%);
}
a{color:inherit;text-decoration:none}
img{max-width:100%}

/* graceful page intro: hidden until ready (JS on), then the primary content
   blocks fade + rise in sequence — a gentle cascade, one element after another
   (driven per-element by the Web Animations API in pages.py `_REVEAL_JS`, which
   fires reliably where a CSS transition would get skipped). No-JS / reduced-motion
   show everything normally. */
html.lx-preload body{opacity:0}
@media (prefers-reduced-motion:reduce){ html.lx-preload body{opacity:1} }

/* ---- header: identical to the landing page's .lx-head (solid variant) ---- */
.lx-head{position:sticky;inset-block-start:0;z-index:900;
  display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
  padding-block:clamp(.9rem,2vw,1.4rem);padding-inline:clamp(1rem,3vw,2.75rem);
  background:transparent;border-block-end:1px solid transparent;
  transition:background .4s var(--lx-ease),border-color .4s var(--lx-ease),
    box-shadow .4s var(--lx-ease),backdrop-filter .4s var(--lx-ease)}
.lx-head.is-solid{background:rgba(255,255,255,.68);border-block-end-color:var(--glass-brd);
  box-shadow:0 6px 24px -14px rgba(20,18,12,.28);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur)}
.lx-brand{display:inline-flex;align-items:center;gap:.55rem;color:var(--lx-on-dark)}
.lx-brand__logo{block-size:44px;inline-size:auto;display:block}
.lx-brand__dot{position:relative;flex:0 0 auto;align-self:center;inline-size:9px;
  block-size:9px;border-radius:50%;background:var(--lx-accent)}
.lx-brand__dot::after{content:"";position:absolute;inset:0;border-radius:50%;
  background:var(--lx-accent);animation:lxLive 1.8s ease-out infinite}
@keyframes lxLive{0%{transform:scale(1);opacity:.55}70%{opacity:0}100%{transform:scale(3);opacity:0}}
.lx-nav{display:flex;align-items:center;gap:clamp(1rem,2vw,2.1rem)}
.lx-nav a{position:relative;color:var(--lx-on-dark);font-size:.95rem;font-weight:700;padding-block:.4rem;white-space:nowrap}
.lx-nav a::after{content:"";position:absolute;inset-inline:0;inset-block-end:0;block-size:2px;
  background:var(--lx-accent);transform:scaleX(0);transform-origin:center;
  transition:transform .3s var(--lx-ease)}
.lx-nav a:hover::after,.lx-nav a.is-active::after{transform:scaleX(1)}
.lx-nav a.is-active{color:var(--lx-accent)}
.lx-head__right{display:flex;align-items:center;gap:1.5rem}
.lx-lang{display:flex;align-items:center;gap:.55rem;color:var(--lx-on-dark-soft);
  font-size:.8rem;letter-spacing:.06em}
.lx-lang a{color:inherit;text-decoration:none}
.lx-lang a[aria-current]{color:var(--lx-accent)}
.lx-lang span{inline-size:1px;block-size:11px;background:var(--lx-line-d)}
.lx-burger{display:none;flex-direction:column;gap:5px;padding:8px;background:none;border:0;cursor:pointer;z-index:22}
.lx-burger span{inline-size:24px;block-size:1.5px;background:var(--lx-on-dark);
  transition:transform .32s var(--lx-ease),opacity .2s var(--lx-ease);transform-origin:center}
.lx-burger.is-open span:nth-child(1){transform:translateY(6.5px) rotate(45deg)}
.lx-burger.is-open span:nth-child(2){opacity:0}
.lx-burger.is-open span:nth-child(3){transform:translateY(-6.5px) rotate(-45deg)}

/* Nav layout is chosen by static/nav.js, which MEASURES whether the tabs fit
   rather than guessing a px breakpoint — adding nav tabs needs no change here. */
/* room to centre the nav on the page */
html.nav-centred .lx-nav{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}
/* while measuring, drop it out of flow so it reports its natural row width */
html.nav-measuring .lx-nav{position:absolute;visibility:hidden}

/* doesn't fit: collapse to a hamburger + dropdown */
html.nav-collapsed:not(.nav-measuring) .lx-burger{display:flex}
html.nav-collapsed:not(.nav-measuring) .lx-nav{
  position:absolute;inset-block-start:100%;inset-inline-end:clamp(1rem,3vw,2.75rem);
  inline-size:min(300px,calc(100vw - 2rem));margin-block-start:.55rem;
  flex-direction:column;align-items:stretch;gap:2px;padding:.5rem;
  border-radius:16px;background:rgba(255,255,255,.9);
  -webkit-backdrop-filter:saturate(1.3) blur(20px);backdrop-filter:saturate(1.3) blur(20px);
  border:1px solid rgba(255,255,255,.72);
  box-shadow:0 26px 60px -20px rgba(20,18,12,.45),0 10px 24px -14px rgba(20,18,12,.28);
  opacity:0;transform:translateY(-10px) scale(.98);transform-origin:top left;
  visibility:hidden;pointer-events:none;
  transition:opacity .28s var(--lx-ease),transform .28s var(--lx-ease),visibility 0s linear .28s;
  z-index:21}
html.nav-collapsed:not(.nav-measuring) .lx-nav.is-open{opacity:1;transform:none;visibility:visible;pointer-events:auto;transition-delay:0s}
html.nav-collapsed:not(.nav-measuring) .lx-nav a{padding:.72rem .95rem;border-radius:10px;font-size:1rem;text-align:start}
html.nav-collapsed:not(.nav-measuring) .lx-nav a::after{display:none}
html.nav-collapsed:not(.nav-measuring) .lx-nav a:hover{background:rgba(var(--lx-accent-rgb),.07);color:var(--lx-accent)}
html.nav-collapsed:not(.nav-measuring) .lx-nav a.is-active,
html.nav-collapsed:not(.nav-measuring) .lx-nav a.is-active:hover{background:var(--lx-accent);color:#fff}
/* Stagger driven by --i (set in nav.js) so any number of tabs animates in order.
   NOT gated on :not(.nav-measuring) — a re-measure would restart it under the user. */
.lx-nav.is-open a{animation:lxNavItem .34s var(--lx-ease) both;animation-delay:calc(var(--i,0) * .03s)}
@keyframes lxNavItem{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
/* scrim behind the open dropdown (dims the page, click to close) */
.lx-nav-scrim{position:fixed;inset:0;z-index:895;background:rgba(20,18,12,.3);
  opacity:0;visibility:hidden;transition:opacity .28s var(--lx-ease),visibility 0s linear .28s}
.lx-nav-scrim.is-on{opacity:1;visibility:visible;transition-delay:0s}
html:not(.nav-collapsed) .lx-nav-scrim{display:none}
@media (prefers-reduced-motion:reduce){
  .lx-burger span,.lx-nav-scrim{transition:none}
  .lx-nav{transition:opacity .12s linear,visibility 0s}
  /* Kill only the DROPDOWN's entry transform. A blanket transform:none here also
     cancelled the centring translate(-50%,-50%), dropping the nav's left edge onto
     the 50% mark so it overlapped the logo for reduced-motion users. */
  html.nav-collapsed .lx-nav{transform:none!important}
  .lx-nav.is-open a{animation:none}
}

/* ---- category hero ---- */
.page{min-height:60vh}
.cat-hero{border-bottom:1px solid var(--hair);overflow-x:clip;
  background:transparent}
/* TOP PADDING IS THE LANDING'S OFFSET MINUS THE CLEARANCE ALREADY GIVEN.
   The ١٨٦٣ stamp row is the first thing in here, exactly as it is the first
   thing in the landing's .lx-hero__inner, and the two must sit at the same
   height under the fixed header. The landing pushes its hero down by
   --lx-hero-pad from the top of the viewport, full stop. Here `main.page`
   has already given back --lx-head-h (the fixed header reserves no space of
   its own), so this padding only has to make up the difference — a flat
   2.6rem was ADDED to that clearance instead, which is what left the eyebrow
   floating ~34px lower than on the landing.
   max() because on short viewports --lx-hero-pad clamps below the header
   height and the difference goes negative. */
.cat-hero-inner{max-width:1200px;margin:0 auto;text-align:center;
  padding:max(0px, calc(var(--lx-hero-pad) - var(--lx-head-h))) 1.5rem 2.2rem}
/* A page rendered `bare` — shell(bare=True), which today is the cassation tree
   framed in the corpus reader's popup (the محكمة التمييز icon). There is no
   fixed header over it and no footer under it, so the hero's clearance is not
   making up for anything: it becomes ordinary padding, and the page ends where
   its content does. */
body.lx-bare .cat-hero-inner{padding-top:1.5rem}
body.lx-bare .page{min-height:0}
/* ١٨٦٣ heritage stamp with red stride lines bleeding to the screen edges (from the landing) */
.lx-stamp-row{display:flex;align-items:center;gap:1rem;inline-size:100%;margin-bottom:1.1rem}
.lx-stride{flex:1 1 auto;min-inline-size:0;block-size:1px;opacity:.85}
.lx-stride--l{margin-inline-end:calc(50% - 50vw);
  background:linear-gradient(to left,var(--accent) 0%,var(--accent) 22%,transparent 96%)}
.lx-stride--r{margin-inline-start:calc(50% - 50vw);
  background:linear-gradient(to right,var(--accent) 0%,var(--accent) 22%,transparent 96%)}
.lx-stamp{display:inline-flex;align-items:center;gap:.7rem;color:var(--accent);
  font-size:.8rem;font-weight:700;letter-spacing:.04em;flex:0 0 auto;white-space:nowrap}
.lx-stamp .ltr{direction:ltr;unicode-bidi:isolate}
/* the "صادر" glyphs lifted from the wordmark itself (static/logo/sader-mark.svg),
   recoloured via mask so it stays the eyebrow's crimson, same as the digits it replaces */
.lx-stamp__mark{display:inline-block;block-size:1.6em;aspect-ratio:1731/472;
  background-color:currentColor;
  -webkit-mask-image:url(/static/logo/sader-mark.svg);mask-image:url(/static/logo/sader-mark.svg);
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;
  -webkit-mask-size:contain;mask-size:contain}
/* eyebrow load animation: red stride lines wipe outward from the ١٨٦٣ stamp to both
   screen edges + stamp fades up (same feel as the landing hero). JS adds .is-armed AFTER
   first paint so the wipe is seen; .has-js hides them up front (no flash); no-JS = static. */
.has-js .lx-stamp-row .lx-stride--l{clip-path:inset(0 0 0 100%)}
.has-js .lx-stamp-row .lx-stride--r{clip-path:inset(0 100% 0 0)}
.has-js .lx-stamp-row .lx-stamp{opacity:0}
.lx-stamp-row.is-armed .lx-stride--l{animation:lx-stride-l 1.6s cubic-bezier(.16,1,.3,1) both}
.lx-stamp-row.is-armed .lx-stride--r{animation:lx-stride-r 1.6s cubic-bezier(.16,1,.3,1) both}
.lx-stamp-row.is-armed .lx-stamp{animation:lx-stamp-in .9s cubic-bezier(.16,1,.3,1) both}
@keyframes lx-stride-l{from{clip-path:inset(0 0 0 100%)}to{clip-path:inset(0 0 0 0%)}}
@keyframes lx-stride-r{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0%)}}
@keyframes lx-stamp-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .has-js .lx-stamp-row .lx-stride--l,.has-js .lx-stamp-row .lx-stride--r{clip-path:none}
  .has-js .lx-stamp-row .lx-stamp{opacity:1}
  .lx-stamp-row.is-armed .lx-stride--l,.lx-stamp-row.is-armed .lx-stride--r,.lx-stamp-row.is-armed .lx-stamp{animation:none}
}
.eyebrow{display:inline-block;font-size:.72rem;font-weight:700;letter-spacing:.12em;
  color:var(--accent);text-transform:uppercase;margin-bottom:.5rem}
.cat-title{font-size:clamp(1.8rem,4vw,2.7rem);font-weight:800;margin:.1rem 0 .3rem;
  letter-spacing:-.01em}
/* the second half (word-wise) of the hero title is crimson */
.cat-title-hl{color:var(--lx-accent)}

/* ===== Featured "latest per category" section (landing + inner pages) ===== */
.subjects{padding:clamp(3.5rem,7vw,6rem) clamp(1rem,4vw,3rem);background:transparent;border-block-start:1px solid var(--glass-brd)}
.subjects-inner{max-width:1240px;margin-inline:auto}
.subjects-head{text-align:center;max-width:56ch;margin:0 auto clamp(2rem,4vw,3rem)}
.subjects-kicker{display:inline-block;color:var(--lx-accent);font-weight:700;font-size:.72rem;letter-spacing:.22em;margin-bottom:.7rem}
.subjects-title{font-family:'Almarai',system-ui,sans-serif;font-weight:800;color:#16140F;font-size:clamp(1.7rem,3.4vw,2.5rem);line-height:1.15;letter-spacing:-.01em;margin:0 0 .6rem}
.subjects-sub{color:#6E6A62;font-size:1rem;line-height:1.7;margin:0}
.subjects-grid{display:grid;gap:clamp(.9rem,1.6vw,1.4rem);grid-template-columns:repeat(2,1fr)}
@media (min-width:660px){.subjects-grid{grid-template-columns:repeat(3,1fr)}}
@media (min-width:1024px){.subjects-grid{grid-template-columns:repeat(5,1fr)}}
.subj-card{display:flex;flex-direction:column;background:var(--glass-2);-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);border:1px solid var(--glass-brd);border-radius:10px;overflow:hidden;box-shadow:var(--float);transition:transform .4s cubic-bezier(.16,1,.3,1),box-shadow .4s cubic-bezier(.16,1,.3,1),border-color .4s}
.subj-card:hover{transform:translateY(-9px);box-shadow:var(--float-lg);border-color:rgba(255,255,255,.9)}
.subj-media{position:relative;aspect-ratio:16/10;overflow:hidden;background:#f2efea}
.subj-media__link{display:block;inline-size:100%;block-size:100%}
.subj-media img{inline-size:100%;block-size:100%;object-fit:cover;display:block;transition:transform .6s cubic-bezier(.16,1,.3,1);filter:saturate(.92)}
.subj-card:hover .subj-media img{transform:scale(1.06)}
.subj-media::after{content:"";position:absolute;inset:0;background:linear-gradient(to top,rgba(12,10,12,.5),rgba(12,10,12,0) 58%);pointer-events:none}
.subj-cat{position:absolute;inset-block-end:12px;inset-inline-start:12px;z-index:2;display:inline-flex;align-items:center;background:var(--lx-accent);color:#fff;font-family:'Almarai',system-ui,sans-serif;font-weight:700;font-size:.8rem;padding:.34em .8em;border-radius:3px;text-decoration:none;box-shadow:0 6px 16px -9px rgba(var(--lx-accent-rgb),.8);transition:background .3s}
.subj-cat:hover{background:var(--lx-accent-deep)}
.subj-body{display:flex;flex-direction:column;gap:.5rem;padding:1.05rem 1.1rem 1.2rem;flex:1}
.subj-meta{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;min-block-size:1.1em}
.subj-date{color:#6E6A62;font-size:.8rem;font-weight:700}
.subj-type{color:var(--lx-accent);background:rgba(var(--lx-accent-rgb),.08);font-size:.72rem;font-weight:700;padding:.2em .6em;border-radius:2px}
.subj-title{margin:0;font-family:'Almarai',system-ui,sans-serif;font-weight:800;font-size:1rem;line-height:1.4}
.subj-title a{color:#16140F;text-decoration:none;transition:color .3s;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.subj-card:hover .subj-title a{color:var(--lx-accent)}
.subj-snip{margin:0;color:#6E6A62;font-size:.88rem;line-height:1.7;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.subj-more{margin-block-start:auto;padding-block-start:.35rem;color:var(--lx-accent);font-weight:700;font-size:.85rem;text-decoration:none;display:inline-flex;align-items:center;gap:.35em}
.subj-more__x{font-size:1.1em;transition:transform .3s}
.subj-card:hover .subj-more__x{transform:translateX(-4px)}
@media (prefers-reduced-motion:reduce){
  .subj-card,.subj-media img,.subj-more__x{transition:none}
  .subj-card:hover,.subj-card:hover .subj-media img{transform:none}
}
.cat-blurb{color:var(--muted);margin:0 auto 1.4rem;max-width:60ch}
.cat-search{display:flex;max-width:640px;margin-inline:auto;border:1px solid var(--glass-brd);
  border-radius:999px;overflow:hidden;background:var(--glass-2);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);box-shadow:var(--float)}
.cat-search input{flex:1;border:0;outline:0;padding:.9rem 1.5rem;font:inherit;
  background:transparent;color:var(--ink)}
.cat-search button{border:0;background:var(--accent);color:#fff;font:inherit;
  font-weight:700;padding:0 2rem;cursor:pointer;transition:background .2s var(--ease)}
.cat-search button:hover{background:var(--accent-dark)}
.cat-search__clear{display:flex;align-items:center;padding:0 1rem;color:var(--muted);
  font-size:1.05rem;font-weight:700;text-decoration:none;transition:color .2s var(--ease)}
.cat-search__clear:hover{color:var(--accent)}
/* Search-pill busy state. The pill submits as a plain GET NAVIGATION, so the
   server runs the whole search before the next page paints — for those 1-3s
   the click used to produce no feedback at all. nav.js stamps `is-busy` on
   the form at submit; the button trades its label for a spinner so the click
   visibly took. A bfcache back-navigation restores the stamped DOM, which is
   why nav.js also clears the class on pageshow. */
.cat-search.is-busy input{opacity:.55}
.cat-search.is-busy button{pointer-events:none;color:transparent;position:relative}
.cat-search.is-busy button::after{content:"";position:absolute;inset:0;margin:auto;
  width:1.05rem;height:1.05rem;border-radius:50%;
  border:2px solid rgba(255,255,255,.45);border-top-color:#fff;
  animation:lx-spin .7s linear infinite}
@keyframes lx-spin{to{transform:rotate(360deg)}}
.studies-clear{display:inline-flex;align-items:center;gap:.3rem;color:var(--accent);
  font-weight:800;text-decoration:none;margin-inline-start:.5rem}
.studies-clear:hover{text-decoration:underline}

/* ---- search pill + folded filter button (category pages only) ----
   .cat-search keeps its own rounded/overflow:hidden pill exactly as the pages
   WITHOUT filters (/studies /majalla /authors) need it. The filter dropdown is a
   SIBLING of the form inside .cat-searchrow, so its absolutely-positioned panel
   is never clipped by the pill. Native <details> => no JavaScript. */
.cat-searchrow{display:flex;align-items:stretch;justify-content:center;gap:.55rem;
  max-width:var(--lx-colw);margin-inline:auto}
/* max-width:none releases the pill's own 640px cap — without it the row could
   never actually reach --lx-colw and the results column below would sit wider
   than the search bar it belongs to. Inside the row the token is the sole
   width authority. */
.cat-searchrow .cat-search{flex:1 1 640px;min-width:0;max-width:none;margin-inline:0}
.cat-filters{position:relative;flex:0 0 auto;text-align:start}
.cat-filters__btn{display:flex;align-items:center;gap:.45rem;block-size:100%;
  padding-inline:1.05rem;border:1px solid var(--glass-brd);border-radius:999px;
  background:var(--glass-2);-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  box-shadow:var(--float);color:var(--ink);font-weight:800;font-size:.9rem;
  white-space:nowrap;cursor:pointer;list-style:none;
  transition:background .2s var(--ease),color .2s var(--ease),border-color .2s var(--ease)}
.cat-filters__btn::-webkit-details-marker{display:none}
.cat-filters__btn::marker{content:""}
.cat-filters__btn:hover{border-color:var(--accent);color:var(--accent)}
.cat-filters__ico{flex:0 0 auto}
.cat-filters.is-active>.cat-filters__btn{background:var(--accent);border-color:var(--accent);color:#fff}
.cat-filters__n{display:inline-flex;align-items:center;justify-content:center;
  min-inline-size:1.3em;padding:.05rem .35rem;border-radius:999px;
  background:rgba(255,255,255,.92);color:var(--accent);font-size:.72rem;font-weight:800}
/* the facet list scrolls; "clear filters" is pinned under it so it stays reachable */
/* The panel opens OUTWARD, away from the search input, so it sits over the page
   margin instead of over the results. `inset-inline-start` (not -end) is what
   makes it hang off the button's outer edge: in RTL that is the visual LEFT,
   and it mirrors correctly to the right under html[lang="en"], because the
   button is at the row's inline-end in both directions. */
.cat-filters__panel{position:absolute;z-index:40;inset-block-start:calc(100% + .55rem);
  inset-inline-start:0;inline-size:min(320px,calc(100vw - 2rem));
  max-block-size:min(70vh,460px);display:flex;flex-direction:column;
  text-align:start;overflow:hidden;border:1px solid var(--glass-brd);
  border-radius:12px;background:var(--paper);box-shadow:var(--float-lg)}
/* Wide enough for the panel to clear the column entirely: it moves BESIDE the
   button (top-aligned) and lands in the outer gutter, overlapping nothing. The
   gutter is (100vw - --lx-colw)/2, so the width is derived from it rather than
   guessed — the query threshold is just the width where that leaves a panel
   still worth reading. Below it the panel drops down as above, hanging outward
   so it covers only the button's own width of the results. */
@media (min-width:1240px){
  .cat-filters__panel{inset-block-start:0;inset-inline-start:calc(100% + .6rem);
    inline-size:min(320px,calc((100vw - var(--lx-colw)) / 2 - 1.6rem))}
}
.cat-filters__list{overflow:auto;padding:1rem 1.05rem}
/* the facet blocks lose their own card chrome inside the panel */
.cat-filters__panel .fc-block{background:none;border:0;box-shadow:none;padding:0;
  max-height:none;-webkit-backdrop-filter:none;backdrop-filter:none}
.cat-filters__panel .fc-block+.fc-block{margin-block-start:.85rem;padding-block-start:.85rem;
  border-block-start:1px solid var(--hair)}
.fc-clear{flex:0 0 auto;display:block;padding:.75rem 1.05rem;font-size:.82rem;
  font-weight:800;color:var(--accent);text-decoration:none;
  border-block-start:1px solid var(--hair);background:var(--paper)}
.fc-clear:hover{text-decoration:underline}


/* ---- layout: main column (the filters <aside> folded into the search pill) ----
   With the sidebar gone there is nothing beside the results, so the column is
   centred UNDER THE SEARCH BAR rather than stretched across 1200px. Both use
   --lx-colw, so they share one axis and one width by construction.
   Only the COLUMN is centred: card titles, snippets and facet rows stay
   start-aligned (this is RTL Arabic — centred body text would read as broken).
   `margin-inline:auto` (not `justify-items`) so it behaves the same LTR/RTL,
   and below the breakpoint the max-width simply stops applying and the column
   fills the padded content box. */
.cat-layout{max-width:1200px;margin:0 auto;padding:1.8rem 1.5rem 3rem;
  display:grid;grid-template-columns:1fr;gap:1.8rem;align-items:start}
.cat-main{min-width:0;max-width:var(--lx-colw);inline-size:100%;margin-inline:auto}
.cat-count{color:var(--muted);font-size:.9rem;font-weight:700;margin-bottom:1rem}

/* ---- facet blocks (rendered inside .cat-filters__panel) ---- */
.fc-block{background:var(--glass-2);-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border:1px solid var(--glass-brd);border-radius:10px;box-shadow:var(--float);
  padding:.9rem 1rem;max-height:360px;overflow:auto}
.fc-title{font-size:.72rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
  color:var(--accent);margin-bottom:.6rem}
.fc-item{display:flex;align-items:center;gap:.5rem;padding:.4rem .5rem;border-radius:var(--r-sm);
  font-size:.88rem;font-weight:700;color:var(--ink);transition:.15s var(--ease)}
.fc-item:hover{background:rgba(var(--lx-accent-rgb),.06);color:var(--accent-dark)}
.fc-item.is-active{background:var(--accent);color:#fff}
.fc-item.is-active .fc-n{color:#fff;opacity:.85}
.fc-n{margin-inline-start:auto;font-size:.75rem;font-weight:700;color:var(--muted);
  background:rgba(255,255,255,.5);padding:.05rem .45rem;border-radius:999px}
.fc-folder{font-size:.85rem;filter:grayscale(.2)}
.fc-empty{color:var(--muted);font-size:.82rem;padding:.3rem 0}
.bc-row{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem;margin-bottom:.6rem;
  padding-bottom:.6rem;border-bottom:1px solid var(--hair)}
.bc{font-size:.82rem;font-weight:700;color:var(--accent)}
.bc.is-active{color:var(--ink)}
.bc-sep{color:var(--muted);font-size:.8rem}

@media (max-width:860px){
  .fc-block{max-height:none}
  /* keep the pill usable when the filter button eats into the row (category
     pages only — /studies /majalla /authors have no .cat-searchrow) */
  .cat-searchrow .cat-search{flex:1 1 auto}
  .cat-searchrow .cat-search input{padding-inline:1rem}
  .cat-searchrow .cat-search button{padding-inline:1.25rem}
  .cat-filters__btn{padding-inline:.8rem}
}
/* legacy single-column results block (unused now, kept harmless) */
.cat-body{max-width:1200px;margin:0 auto;padding:1.8rem 1.5rem 3rem}
.res-list{display:grid;gap:.9rem}
.res-card{display:block;background:var(--glass-2);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border:1px solid var(--glass-brd);box-shadow:var(--float);
  border-radius:10px;padding:1.1rem 1.25rem;transition:.22s var(--ease);
  position:relative;overflow:hidden}
.res-card::before{content:"";position:absolute;inset-inline-start:0;top:0;bottom:0;
  width:3px;background:var(--accent);transform:scaleY(0);transform-origin:top;
  transition:transform .22s var(--ease)}
.res-card:hover{border-color:rgba(255,255,255,.9);box-shadow:var(--float-lg);transform:translateY(-6px)}
.res-card:hover::before{transform:scaleY(1)}
/* A card the reader's own words were found in, kept above the smart-search
   ranking (browse.js pins these; see _fts_phrase in lib/pages.py). It earns the
   accent edge at rest rather than on hover — the distinction worth showing is
   "this document literally contains what you typed", not a hover affordance. */
.res-card--exact::before{transform:scaleY(1)}
/* unicode-bidi:plaintext on every DATA-driven title (here and below): the DB
   carries some English/French titles, and inside our RTL pages their
   punctuation and numbers shuffled. plaintext lets each title's FIRST STRONG
   character pick its direction — Arabic stays put, Latin reads left-to-right.
   Our own (always-Arabic) UI labels deliberately don't get this. */
.res-title{margin:0 0 .5rem;font-size:1.12rem;font-weight:800;line-height:1.4;color:var(--ink);unicode-bidi:plaintext}
.res-meta{display:flex;flex-wrap:wrap;gap:.4rem;margin-bottom:.5rem}
/* The IDENTITY line, above the title: what kind of text this is, which number,
   which year. It leads the card because that is how a legal text is cited and
   recognised — the wording comes after you know what you are looking at. */
.res-meta--lead{margin:0 0 .45rem;gap:.35rem;align-items:center}
.res-meta--lead:empty{display:none}                 /* undated/untyped rows */
.res-chip{display:inline-flex;align-items:baseline;gap:.3rem;
  font-size:.78rem;font-weight:700;padding:.2rem .58rem;border-radius:999px;
  border:1px solid var(--hair);color:var(--muted);background:rgba(255,255,255,.5)}
.res-chip i{font-style:normal;font-weight:600;opacity:.7;font-size:.92em}
.res-chip b{font-weight:800;color:var(--ink)}
/* the type carries the accent: it is the single most identifying field */
.res-chip--type{background:rgba(var(--lx-accent-rgb),.09);border-color:rgba(var(--lx-accent-rgb),.16);
  color:var(--accent-dark)}
.pill{background:rgba(var(--lx-accent-rgb),.08);color:var(--accent-dark);font-size:.75rem;
  font-weight:700;padding:.18rem .6rem;border-radius:999px}
.meta{color:var(--muted);font-size:.8rem;font-weight:700;
  padding:.18rem .5rem;border:1px solid var(--hair);border-radius:999px}
.res-snip{margin:0;color:var(--muted);font-size:.9rem;line-height:1.7}
/* Subscriber-only excerpt. THE BLUR IS DECORATION, NOT THE PROTECTION: the real
   text was never sent — this is meaningless filler of about the right shape, so
   removing the blur in devtools reveals filler. See lib/gate.py. */
.lx-lock-snip{display:block;filter:blur(4px);-webkit-filter:blur(4px);
  user-select:none;-webkit-user-select:none;pointer-events:none;
  color:var(--muted)}
.empty{padding:3rem 1rem;text-align:center;color:var(--muted);
  border:1px dashed var(--hair);border-radius:var(--r)}

/* ---- pager ---- */
.pager{display:flex;gap:.4rem;justify-content:center;margin-top:2rem;flex-wrap:wrap}
.pg{min-width:2.4rem;text-align:center;padding:.5rem .7rem;border:1px solid var(--glass-brd);
  border-radius:var(--r-sm);font-weight:700;font-size:.9rem;background:var(--glass);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);box-shadow:var(--float);
  transition:.18s var(--ease)}
.pg:hover{border-color:var(--accent);color:var(--accent)}
.pg.is-current{background:var(--accent);color:#fff;border-color:var(--accent)}
.pg-prev,.pg-next{color:var(--accent)}

/* ---- document viewer ---- */
.doc-view{max-width:860px;margin:0 auto;padding:2.4rem 1.5rem 4rem}
.dv-back{display:block;width:fit-content;color:var(--accent);font-weight:700;margin-bottom:1rem}
.dv-title{font-size:clamp(1.5rem,3.5vw,2.2rem);font-weight:800;margin:.2rem 0 1rem;line-height:1.35}
.dv-metarow{display:flex;flex-wrap:wrap;gap:.5rem;padding-bottom:1.3rem;
  margin-bottom:1.6rem;border-bottom:1px solid var(--hair)}
.dv-meta{display:flex;gap:.4rem;align-items:center;font-size:.85rem;
  background:#fff;border:1px solid var(--hair);border-radius:999px;padding:.25rem .8rem}
.dv-meta span{color:var(--muted);font-weight:700}
.dv-meta b{color:var(--ink)}
.dv-content{font-size:1.02rem;line-height:1.9;color:#26221b;
  /* Whole words only: a word that doesn't fit moves ENTIRELY to the next line
     (never split mid-word). break-word/hyphens:none guarantee no character-level
     breaking of real words; only a genuinely unfittable token (e.g. a very long
     URL) breaks as a last resort. The &nbsp;-glued sentences are un-glued
     server-side (_unnbsp) so normal word wrapping does the rest. Every child is
     also capped to the column so wide media/tables can't force sideways scroll. */
  overflow-wrap:break-word;word-break:normal;hyphens:none}
.dv-content *{max-width:100%;box-sizing:border-box}

/* The ORIGINAL exported document, shown in an iframe (see render_viewer).
   It has to be an iframe, not inlined markup: these are complete HTML 4.0 pages
   with their own <head>, their own 396 KB stylesheet and even a <script>, so
   inlining would let a third-party document restyle and script OUR page. The
   frame keeps its CSS scoped and the sandbox attribute keeps it inert.
   `height` can't be content-driven across the boundary, so it gets a tall
   viewport-relative box and scrolls internally. */
/* Selector must out-rank `.dv-content iframe{height:auto}` a few rules below —
   that is element+class, so a bare `.dv-frame` loses to it and the frame
   collapses to the 150px default iframe height. */
.dv-content iframe.dv-frame{inline-size:100%;block-size:min(78vh,1100px);
  border:1px solid #e6e0d5;border-radius:10px;background:#fff;display:block}
/* Fallback notice when the source file was never exported */
.dv-note{margin:0 0 1rem;padding:.7rem .9rem;border-radius:8px;
  background:rgba(var(--lx-accent-rgb),.06);border:1px solid rgba(var(--lx-accent-rgb),.22);color:var(--lx-accent);font-size:.92rem}
/* …but when we rebuilt the full document from the DB nothing is actually
   missing, so that note is information, not a warning. */
.dv-note--info{background:#f6f4ef;border-color:var(--hair);color:var(--muted)}

/* ---- document rebuilt from its database blocks (lib/docbuild.py) ----
   Typeset to read like the exported original: the number and date lead, the
   subject is the title, and each article is a labelled block. */
.dv-rebuilt{margin-top:.4rem}
.dv-rebuilt .dvr-num{font-size:clamp(1.3rem,2.6vw,1.7rem);font-weight:800;
  margin:0 0 .3rem;line-height:1.4}
.dv-rebuilt .dvr-date{color:var(--muted);font-size:.95rem;margin-bottom:1.1rem}
.dv-rebuilt .dvr-subj{font-size:clamp(1.05rem,2vw,1.25rem);font-weight:700;
  line-height:1.6;margin:0 0 1.4rem;padding-bottom:1.1rem;
  border-bottom:1px solid var(--hair)}
.dv-rebuilt .dvr-head{font-size:1.05rem;font-weight:800;margin:1.8rem 0 .6rem}
.dv-rebuilt .dvr-art{margin:0 0 1.35rem;padding-inline-start:.9rem;
  border-inline-start:2px solid var(--hair)}
.dv-rebuilt .dvr-arth{font-size:1rem;font-weight:800;margin:0 0 .35rem;
  color:var(--accent)}
.dv-rebuilt .dvr-blk{margin:0 0 1rem}
.dv-rebuilt p{margin:0 0 .55rem}
.dv-rebuilt p:last-child{margin-bottom:0}
/* the block the reader clicked through from (e.g. a search hit on one article) */
.dv-rebuilt .is-here{scroll-margin-top:5rem}
.dv-rebuilt .dvr-art.is-here{border-inline-start-color:var(--accent);
  background:#fbf8f2;border-radius:0 6px 6px 0}
.dv-content img,.dv-content svg,.dv-content video,.dv-content iframe,
.dv-content embed,.dv-content object{height:auto}
.dv-content pre{white-space:pre-wrap;overflow-wrap:break-word;overflow-x:auto}
.dv-content h1,.dv-content h2,.dv-content h3{font-weight:800;line-height:1.4}
.dv-content p{margin:0 0 1rem}
.dv-content table{border-collapse:collapse;width:100%;margin:1rem 0;overflow-x:auto;display:block}
.dv-content td,.dv-content th{border:1px solid var(--hair);padding:.5rem .7rem}
.dv-content a{color:var(--accent);text-decoration:underline}
/* Study bodies: justify so every line is flush to BOTH column edges — the text
   block then lines up exactly with the hero image's left + right borders. */
.study-view .dv-content{text-align:justify;text-justify:inter-word}
.study-view .dv-content p{text-align:justify}
/* subject published as an uploaded document (scanned PDF) instead of HTML body */
.subject-doc{margin-block-start:1.6rem;border:1px solid var(--hair);border-radius:10px;overflow:hidden;background:var(--card)}
.subject-doc__bar{display:flex;align-items:center;justify-content:space-between;gap:1rem;
  padding:.7rem 1rem;background:#FAF8F5;border-block-end:1px solid var(--hair);
  font-size:.85rem;font-weight:700;color:var(--ink)}
.subject-doc__dl{color:var(--accent);text-decoration:none;white-space:nowrap}
.subject-doc__dl:hover{text-decoration:underline}
.subject-doc__frame{display:block;inline-size:100%;block-size:min(85vh,1000px);border:0;background:#F3F1EE}
@media (max-width:640px){.subject-doc__frame{block-size:min(70vh,640px)}}
.subject-doc__pages{display:flex;flex-direction:column;gap:.9rem;padding:.9rem;background:#F3F1EE}
.subject-doc__page{display:block;inline-size:100%;block-size:auto;border:1px solid var(--hair);
  border-radius:4px;background:#fff;box-shadow:0 2px 10px -6px rgba(22,20,15,.5)}

/* ---- المجلة القضائية (the page) ----
   Two bodies of material under one masthead: the studies, then the doctrine
   corpus. They stay visually separate because they ARE different things — a
   signed article versus an article-level slice of a reference work — and a
   single ranked list that mixed them would be harder to read, not easier. */
.mj-hero__mark{margin:.4rem 0 .2rem}
.mj-hero__svg{display:block;margin-inline:auto;inline-size:clamp(190px,26vw,320px)}
.mj-hero__svg svg{display:block;inline-size:100%;block-size:auto}
/* the accessible name for the mark; English shows it as real type instead */
.mj-hero__txt{position:absolute;inline-size:1px;block-size:1px;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap}
html[lang="en"] .mj-hero__svg{display:none}
html[lang="en"] .mj-hero__txt{position:static;inline-size:auto;block-size:auto;
  overflow:visible;clip-path:none;white-space:normal;
  font-size:clamp(2rem,1.3rem + 2.4vw,3.2rem);font-weight:800;letter-spacing:-.02em;
  font-family:"Fraunces",Georgia,serif}
/* المؤلفون — the ex-nav tab, now a button under the magazine's search box
   (lib/pages._authors_link). Deliberately quieter than the search button: it is
   a side door out of the magazine, not the thing you came here to do. */
.mj-authors{margin-block-start:1rem;text-align:center}
.mj-authors__btn{display:inline-flex;align-items:center;gap:.5rem;
  padding:.55rem 1.35rem;border:1px solid var(--glass-brd);border-radius:999px;
  background:var(--glass-2);-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  color:var(--ink);font-weight:800;font-size:.95rem;text-decoration:none;
  box-shadow:var(--float);
  transition:color .2s var(--ease),border-color .2s var(--ease),transform .2s var(--ease)}
.mj-authors__btn:hover{color:var(--accent);border-color:var(--accent);transform:translateY(-1px)}
.majalla-wrap{max-width:1200px;margin:0 auto;padding:1.8rem 1.5rem 3rem;
  display:flex;flex-direction:column;gap:2.6rem}
.mj-block__head{display:flex;align-items:baseline;flex-wrap:wrap;gap:.75rem;
  padding-block-end:.7rem;margin-block-end:1.1rem;border-block-end:1px solid var(--hair)}
.mj-block__h{margin:0;font-size:1.3rem;font-weight:800;color:var(--ink)}
.mj-block__n{color:var(--muted);font-size:.88rem;font-weight:700}

/* ---- الكتّاب (the authors index) ---- */
.au-grid{display:grid;gap:1rem;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,220px),1fr))}
.au-card{display:flex;flex-direction:column;align-items:center;text-align:center;gap:.55rem;
  padding:1.6rem 1.1rem 1.4rem;background:var(--glass-2);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border:1px solid var(--glass-brd);border-radius:12px;box-shadow:var(--float);
  transition:.22s var(--ease)}
.au-card:hover{transform:translateY(-5px);box-shadow:var(--float-lg);
  border-color:rgba(255,255,255,.9)}
.au-card__ph{display:block;inline-size:96px;block-size:96px}
.au-card__img{inline-size:96px;block-size:96px;border-radius:50%;object-fit:cover;
  object-position:top center;border:2px solid #fff;box-shadow:0 6px 18px -10px rgba(20,18,12,.6)}
/* authors with no vendored headshot get an initial, not a broken image box */
.au-card__img.lx-mono{display:grid;place-items:center;background:rgba(var(--lx-accent-rgb),.1);
  color:var(--accent-dark);font-size:2.2rem;font-weight:800;line-height:1}
.au-card__body{display:flex;flex-direction:column;gap:.3rem;min-inline-size:0;inline-size:100%}
.au-card__name{font-size:1rem;font-weight:800;color:var(--ink);line-height:1.4}
.au-card:hover .au-card__name{color:var(--accent)}
.au-card__pos{color:var(--muted);font-size:.8rem;line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.au-card__n{color:var(--accent-dark);font-size:.76rem;font-weight:700;margin-block-start:.2rem}

/* ---- stub / error ---- */
.stub{max-width:640px;margin:0 auto;padding:5rem 1.5rem;text-align:center}
.stub h1{font-size:2rem;font-weight:800;margin:.3rem 0 .8rem}
.stub p{color:var(--muted);margin-bottom:1.8rem}
.btn{display:inline-block;background:var(--accent);color:#fff;font-weight:700;
  padding:.7rem 1.6rem;border-radius:var(--r-sm);transition:background .2s var(--ease)}
.btn:hover{background:var(--accent-dark)}

/* ---- "SaderConstructing…" — where the dormant store lands ---- */
.soon{padding-block:clamp(5rem,16svh,9rem)}
/* A crimson surveyor's mark: two strides meeting a dot, the same vocabulary as
   the hero's ١٨٦٣ stamp row, so the holding page still reads as this site. */
.soon__mark{display:block;inline-size:min(280px,60%);block-size:2px;margin:0 auto 1.6rem;
  background:linear-gradient(to right,transparent,var(--accent) 40%,var(--accent) 60%,transparent);
  position:relative}
.soon__mark::after{content:"";position:absolute;inset-block-start:-3px;inset-inline-start:calc(50% - 4px);
  inline-size:8px;block-size:8px;border-radius:50%;background:var(--accent)}
/* The word is a coined one ("Sader" + "constructing"), so it is NOT translated
   and NOT wrapped — it is set as a single lockup in both languages. */
.soon__h{font-size:clamp(1.9rem,1.2rem + 2.6vw,3.1rem);font-weight:800;line-height:1.1;
  margin:.2rem 0 .9rem;letter-spacing:-.02em;direction:ltr;unicode-bidi:isolate}
.soon__h1{color:var(--ink)}
/* (no ::first-letter accent here — it only applies to block containers, and this
   is an inline span inside the h1; the crimson ellipsis carries the accent.) */
.soon__dots{color:var(--accent);margin-inline-start:.06em}
.soon__p{color:var(--muted);font-size:1.05rem;margin-bottom:2rem}
html[lang="en"] .soon__h{font-family:"Fraunces",Georgia,serif}

/* ---- footer ---- */
.site-footer{background:rgba(255,255,255,.68);color:var(--ink);margin-top:2rem;
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border-block-start:1px solid var(--glass-brd);box-shadow:0 -6px 24px -14px rgba(20,18,12,.28)}
.foot-inner{max-width:1200px;margin:0 auto;padding:2.6rem 1.5rem;
  display:flex;flex-wrap:wrap;gap:1.5rem;align-items:center;justify-content:space-between}
.foot-logo{height:34px;opacity:.95}
.foot-brand p{margin:.5rem 0 0;font-size:.85rem;color:var(--muted)}
.foot-nav{display:flex;gap:1.2rem;flex-wrap:wrap}
.foot-nav a{font-weight:700;font-size:.9rem;color:var(--ink);transition:color .2s}
.foot-nav a:hover{color:var(--accent)}
.foot-copy{width:100%;border-top:1px solid var(--glass-brd);padding-top:1.2rem;margin:0;
  font-size:.8rem;color:var(--muted)}

@media (max-width:760px){
  .hdr-inner{flex-wrap:wrap;gap:.6rem}
  .main-nav{order:3;width:100%}
  .dv-content{font-size:.98rem}
}

/* ====================== STUDIES ("Dirasat") inner pages ====================== */
.studies-wrap{max-width:1200px;margin:0 auto;padding:1.6rem 1.5rem 3rem}

/* all-studies + author study grid */
.study-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:1.4rem}
.study-card{display:flex;flex-direction:column;background:var(--glass-2);
  -webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  border:1px solid var(--glass-brd);box-shadow:var(--float);
  border-radius:10px;overflow:hidden;
  transition:border-color .2s var(--ease),box-shadow .25s var(--ease),transform .2s var(--ease)}
.study-card:hover{border-color:rgba(255,255,255,.9);box-shadow:var(--float-lg);transform:translateY(-8px)}
.study-card__media{display:block;aspect-ratio:16/10;overflow:hidden;background:var(--hair)}
.study-card__media img,.study-card__media svg{inline-size:100%;block-size:100%;object-fit:cover;transition:transform .6s var(--ease)}
.study-card__media .lx-inlinesvg{display:block;inline-size:100%;block-size:100%}
.study-card:hover .study-card__media img,.study-card:hover .study-card__media svg{transform:scale(1.05)}
.study-card__media.is-empty{position:relative;
  background:linear-gradient(135deg,rgba(var(--lx-accent-rgb),.10),rgba(var(--lx-accent-rgb),.02)),var(--card)}
.study-card__media.is-empty::after{content:"صادرلكس";position:absolute;inset:0;display:grid;
  place-items:center;color:rgba(var(--lx-accent-rgb),.26);font-weight:800;letter-spacing:.08em;font-size:1.05rem}
.study-card__body{padding:1rem 1.1rem 1.2rem;display:flex;flex-direction:column;gap:.5rem;flex:1}
.study-card__meta{color:var(--accent);font-weight:700;font-size:.76rem}
.study-card__title{margin:0;font-size:1.05rem;font-weight:800;line-height:1.45;color:var(--ink);unicode-bidi:plaintext;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.study-card:hover .study-card__title{color:var(--accent)}
.study-card__snip{color:var(--muted);font-size:.86rem;line-height:1.7;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

/* single study */
.study-view .study-byline{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem 1rem;
  padding-bottom:1.2rem;margin-bottom:1.5rem;border-bottom:1px solid var(--hair)}
.study-author{display:inline-flex;align-items:center;gap:.6rem;font-weight:800;color:var(--ink)}
.study-author:hover{color:var(--accent)}
.study-author__img{inline-size:44px;block-size:44px;border-radius:50%;object-fit:cover;object-position:top center;
  border:1px solid var(--hair);flex:0 0 auto}
/* initials monogram shown when an author has no headshot */
.lx-mono{display:flex;align-items:center;justify-content:center;line-height:1;
  color:var(--accent);font-weight:800;overflow:hidden;
  background:linear-gradient(135deg,rgba(var(--lx-accent-rgb),.16),rgba(var(--lx-accent-rgb),.04))}
.study-author__img.lx-mono{font-size:1.15rem}
.author-hero__img.lx-mono{font-size:2.8rem}
.study-author__pos{color:var(--muted);font-size:.85rem;font-weight:400}
.study-byline__date{color:var(--muted);font-size:.85rem;font-weight:700;margin-inline-start:auto}
.study-hero{margin:0 0 1.6rem;border-radius:var(--r);overflow:hidden;border:1px solid var(--hair)}
.study-hero__img,.study-hero img,.study-hero svg{display:block;inline-size:100%;block-size:auto}
.study-hero .lx-inlinesvg{display:block}
/* Licence credit under the study photo. Quiet, but it has to be legible:
   CC BY / CC BY-SA require the photographer and licence to be named. */
.study-hero__credit{padding:.5rem .75rem;font-size:.78rem;line-height:1.5;
  color:var(--muted,#8A8A8E);border-block-start:1px solid var(--hair);
  background:var(--panel,transparent)}
.study-hero__credit a{color:inherit;text-decoration:underline;
  text-underline-offset:2px}
.study-hero__credit a:hover{color:var(--fg,inherit)}
.study-src{display:flex;gap:.5rem;align-items:center;font-size:.88rem;margin-bottom:1.4rem}
.study-src span{color:var(--muted);font-weight:700}
.study-src b{color:var(--ink)}

/* author header */
.author-hero-wrap{text-align:start}
.author-hero-wrap .lx-stamp-row{margin-inline:auto}
.author-hero{max-width:1000px;margin:1.4rem auto 0;display:flex;align-items:center;gap:1.5rem;text-align:start}
.author-hero__img{inline-size:110px;block-size:110px;border-radius:50%;object-fit:cover;object-position:top center;
  border:2px solid var(--hair);flex:0 0 auto;box-shadow:var(--shadow)}
.author-hero__img--ph{background:linear-gradient(135deg,rgba(var(--lx-accent-rgb),.14),rgba(var(--lx-accent-rgb),.03))}
.author-hero__id{min-inline-size:0}
.author-hero__name{font-size:clamp(1.5rem,3vw,2.2rem);font-weight:800;margin:.2rem 0 .3rem;line-height:1.25}
.author-hero__pos{color:var(--muted);margin:0 0 .5rem;font-size:1rem}
.author-hero__count{margin:0;color:var(--accent);font-weight:700;font-size:.9rem}
@media (max-width:640px){
  .author-hero{flex-direction:column;text-align:center}
  .study-byline__date{margin-inline-start:0}
}

/* ====================== BROWSE: TABS + TREE + DOC POPUP ======================
   The tab strip is centred (only .cat-main uses it) so the centre axis runs
   unbroken from the stamp row through the title, blurb and search bar into the
   column; the hairline under it still spans the column, marking its edges. The
   switch to start-aligned reading happens one step lower, at the count line. */
.browse-tabs{display:flex;justify-content:center;gap:.2rem;border-bottom:1px solid var(--hair);
  margin-bottom:1.1rem;flex-wrap:wrap}
.btab{appearance:none;background:none;border:0;cursor:pointer;font:inherit;font-weight:800;
  color:var(--muted);padding:.6rem .9rem;border-bottom:2px solid transparent;margin-bottom:-1px;
  display:inline-flex;align-items:center;gap:.4rem;transition:color .2s,border-color .2s}
.btab:hover{color:var(--ink)}
.btab.is-active{color:var(--accent);border-bottom-color:var(--accent)}
.bpanel[hidden]{display:none}
/* A short browse panel (e.g. a small folder tree, now the default landing view)
   must not reveal the footer on first paint: fill the viewport so the footer
   waits below the fold until the reader scrolls to it. */
.bpanel:not([hidden]){min-height:calc(100svh - 12rem)}

.tree{display:flex;flex-direction:column;gap:.05rem}
.tnode{display:flex;flex-direction:column}
.trow{display:flex;align-items:center;gap:.5rem;padding:.35rem .4rem;border-radius:var(--r-sm);
  transition:background .15s var(--ease)}
.trow:hover{background:rgba(var(--lx-accent-rgb),.05)}
.ttog{appearance:none;background:none;border:0;cursor:pointer;flex:0 0 auto;
  inline-size:1.5rem;block-size:1.5rem;display:grid;place-items:center;color:var(--muted);
  border-radius:4px;padding:0}
.ttog:hover{color:var(--accent);background:rgba(var(--lx-accent-rgb),.08)}
/* +/−, not a rotating caret: the glyph itself is swapped in browse.js, so
   nothing here may rotate it — a rotated − is a vertical bar. */
.tcaret{display:inline-block;font-size:1rem;font-weight:700;line-height:1}
.tname{display:flex;align-items:center;gap:.5rem;flex:1;min-inline-size:0;cursor:pointer;
  font-weight:700;color:var(--ink)}
.tname:hover .tlabel{color:var(--accent)}
.tlabel{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tn{flex:0 0 auto;font-size:.72rem;font-weight:700;color:var(--muted);background:rgba(255,255,255,.5);
  border:1px solid var(--hair);padding:.05rem .55rem;border-radius:999px}
.tkids{display:flex;flex-direction:column;gap:.05rem;padding-inline-start:1.25rem;
  margin-inline-start:1rem;border-inline-start:1px solid var(--hair);margin-block:.1rem}
.tkids[hidden]{display:none}

.tdoc{appearance:none;background:none;border:0;cursor:pointer;font:inherit;text-align:start;
  display:flex;align-items:flex-start;gap:.5rem;padding:.4rem .5rem;border-radius:var(--r-sm);
  inline-size:100%;transition:background .15s var(--ease)}
.tdoc:hover{background:rgba(var(--lx-accent-rgb),.06)}
.tdoc-ic{flex:0 0 auto;opacity:.5;font-size:1rem;line-height:1.4;color:var(--muted)}
.tdoc-main{display:flex;flex-direction:column;min-inline-size:0;gap:.1rem}
.tdoc-title{font-weight:700;color:var(--ink);line-height:1.4;unicode-bidi:plaintext;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.tdoc:hover .tdoc-title{color:var(--accent)}
.tdoc-sub{font-size:.78rem;color:var(--muted)}
.ltrn{direction:ltr;unicode-bidi:isolate}

.tload,.tempty{color:var(--muted);font-size:.85rem;padding:.5rem .4rem}
/* The smart-search progress line (browse.js streams the engine's @@STEP text
   into it). It USED to share .tload's muted look above — one small gray line
   on a page whose keyword results had already painted, which is exactly why
   nobody noticed the engine was still working and the swap felt like the page
   "randomly changed". Now an unmissable banner: glass card, accent spine,
   spinning marker beside the live step text. browse.js removes it on success
   and stamps `hs-done` on failure (spinner stops, message stays readable). */
.hs-progress{display:flex;align-items:center;gap:.65rem;
  margin:0 0 .85rem;padding:.7rem 1rem;border-radius:var(--r-sm);
  border:1px solid var(--glass-brd);border-inline-start:3px solid var(--accent);
  background:var(--glass-2);-webkit-backdrop-filter:var(--blur);backdrop-filter:var(--blur);
  color:var(--ink);font-size:.95rem;font-weight:600}
.hs-progress::before{content:"";flex:0 0 auto;width:1rem;height:1rem;border-radius:50%;
  border:2px solid var(--hair);border-top-color:var(--accent);
  animation:lx-spin .7s linear infinite}
.hs-progress.hs-done{color:var(--muted);font-weight:400}
.hs-progress.hs-done::before{animation:none;border-color:var(--hair)}
.tmore{appearance:none;background:none;border:1px dashed var(--hair);border-radius:var(--r-sm);
  cursor:pointer;font:inherit;font-weight:700;color:var(--accent);padding:.45rem .85rem;
  margin:.35rem 0;align-self:flex-start;transition:.15s var(--ease)}
.tmore:hover{background:rgba(var(--lx-accent-rgb),.06);border-color:var(--accent)}
.tmore:disabled{color:var(--muted);cursor:default}


/* ====================== ENGLISH (LTR) PRESENTATION ======================
   The EN|ع toggle flips <html> to lang="en" dir="ltr" (static/i18n.js). In
   English the translated chrome uses the Latin pairing (Fraunces display +
   Inter text) instead of Almarai; the Arabic DB *content* (result titles,
   snippets, document body, sidebar values) is forced back to RTL so it stays
   legible and right-aligned inside the LTR shell. */
html[lang="en"] .lx-nav a,
html[lang="en"] .cat-search input,
html[lang="en"] .cat-search button,
html[lang="en"] .eyebrow,
html[lang="en"] .cat-blurb,
html[lang="en"] .cat-count,
html[lang="en"] .cat-filters__btn,
html[lang="en"] .mj-authors__btn,
html[lang="en"] .fc-clear,
html[lang="en"] .fc-title,
html[lang="en"] .bc,
html[lang="en"] .pg,
html[lang="en"] .btab,
html[lang="en"] .tmore,
html[lang="en"] .tn,
html[lang="en"] .lx-lang,
html[lang="en"] .subjects-kicker,
html[lang="en"] .subjects-sub,
html[lang="en"] .subj-cat,
html[lang="en"] .subj-more,
html[lang="en"] .stub p,
html[lang="en"] .btn,
html[lang="en"] .foot-nav a,
html[lang="en"] .foot-brand p{ font-family:"Inter",system-ui,-apple-system,sans-serif; }
html[lang="en"] .cat-title,
html[lang="en"] .subjects-title,
html[lang="en"] .stub h1{ font-family:"Fraunces",Georgia,serif; letter-spacing:-.015em; }

/* keep Arabic DB content right-to-left within the English shell */
html[lang="en"] .res-card,
html[lang="en"] .dv-title,
html[lang="en"] .dv-content,
html[lang="en"] .subj-title,
html[lang="en"] .subj-snip,
html[lang="en"] .study-card,
html[lang="en"] .study-card__title,
html[lang="en"] .study-card__snip,
html[lang="en"] .study-byline,
html[lang="en"] .author-hero__name,
html[lang="en"] .author-hero__pos{ direction:rtl; text-align:right; }
/* the browse trees hold Arabic folder/doc names — flow the whole tree RTL in
   English too (tabs above stay LTR); numeric year labels keep LTR via .ltrn */
html[lang="en"] .tree{ direction:rtl; text-align:right; }
/* the "All" / translated facet rows follow the page direction; only the
   Arabic value labels within a facet keep RTL */
html[lang="en"] .fc-item{ text-align:start; }
