/* a7 homepage — v3 REFINED-NATIVE. Current-homepage spine + /about DNA.
   daisyUI theme vars are HSL triplets: hsl(var(--base-100/--base-content/--primary)).
   ⛔ tints ALWAYS via color-mix(in oklch, … , transparent) — never slash-alpha.
   Reveal via home.js IntersectionObserver (.is-in); content visible-by-default. */

/* ── FONTS ────────────────────────────────────────────────────────────────
   core.css (generated by the main binary, loaded BEFORE us) declares font_ar
   and font_en as RAW .ttf straight out of PocketBase: Inter 874,708 B and
   Tajawal 57,360 B = 932 KB before a single pixel of text can paint.
   These three faces re-declare the SAME family names with woff2 subsets. Two
   faces with identical descriptors → the LAST one defined wins, so the .ttf
   faces above are shadowed and never fetched. Deliberately NO font-weight
   descriptor: core.css has none either, so the browser keeps synthesising
   bold exactly as it does today — this is a byte fix, not a look change.
   The latin subset was verified to cover every codepoint the page renders
   (0 misses over the live HTML incl. every data-ar/data-en value); the ext
   face is unicode-ranged so it only downloads if content ever needs it.
   133,592 B instead of 932,068 B → −798 KB.  Regenerate: docs/fonts.md */
@font-face{font-family:'font_en';src:url('/static/home/f/inter-latin.woff2?v=f2') format('woff2');font-display:swap}
@font-face{font-family:'font_en';src:url('/static/home/f/inter-ext.woff2?v=f1') format('woff2');font-display:swap;
  unicode-range:U+0100-02AF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'font_ar';src:url('/static/home/f/tajawal.woff2?v=f1') format('woff2');font-display:swap}

.a7h{
  --card:      color-mix(in oklch, hsl(var(--base-content))  4%, transparent);
  --card-bd:   color-mix(in oklch, hsl(var(--base-content)) 10%, transparent);
  --line:      color-mix(in oklch, hsl(var(--base-content)) 12%, transparent);
  --line2:     color-mix(in oklch, hsl(var(--base-content)) 22%, transparent);
  /* ── text tiers are CONTRAST-BOUND, not taste-bound ───────────────────
     Measured on the live page 2026-07-30, worst case = tier on --card:
       --muted 66% → 5.19 dark / 5.22 light   (was already AA)
       --faint 42% → 2.70 dark / 2.48 light   (AA needs 4.5 — 12 texts failed)
     4.5 forces --faint to ≥62%, which would land 4pt off --muted and erase
     the tier gap, so --muted moves up with it and the hierarchy survives.
     --hair keeps the ORIGINAL 42% for the two purely decorative rules
     (.a7h-tm__dash, .a7h-tm__sub::after) — non-text, no ratio to meet, and
     bumping them would have thickened the timeline for no a11y gain. */
  --muted:     color-mix(in oklch, hsl(var(--base-content)) 78%, transparent);
  --faint:     color-mix(in oklch, hsl(var(--base-content)) 62%, transparent);
  --hair:      color-mix(in oklch, hsl(var(--base-content)) 42%, transparent);
  --tint:      color-mix(in oklch, hsl(var(--primary)) 8%, transparent);
  --tint-bd:   color-mix(in oklch, hsl(var(--primary)) 22%, transparent);
  /* --tint is an 8% wash meant for FILLS. Six :focus-visible rules were
     drawing their ring with it, i.e. 1.05:1 dark / 1.12:1 light — a ring you
     cannot see is not a ring. --ring is the same hue at full strength; WCAG
     2.2 §1.4.11 wants ≥3:1 for a focus indicator and this clears 5.5. */
  --ring:      hsl(var(--primary));
}
/* FontAwesome glyphs now ship as inline <svg class="a7h-ic"> (see fa_icons.py).
   The viewBox is ascent→descent in font units (534 of a 512 em), so height
   1.043em puts one font unit at exactly the pixel size the webfont drew it at,
   and -.146em drops the descent below the baseline the same way. Same outline,
   same size, same position — 184 KB less to download. */
.a7h .a7h-ic{height:1.043em;width:auto;display:inline-block;vertical-align:-.146em;flex:0 0 auto}
.a7h{
  --ink:       hsl(var(--base-content));
  --pri:       hsl(var(--primary));
  --blue:#1473ff;
  --ease:cubic-bezier(.16,1,.3,1);
  --spring:cubic-bezier(.34,1.56,.64,1);
  --gap:clamp(1rem,2vw,1.6rem);
  --band:clamp(3rem,7vw,5.5rem);
  --pad:clamp(1rem,4vw,2rem);
  --r:14px; --r-in:9px;
  --sh1:0 1px 2px color-mix(in oklch, hsl(var(--base-content)) 4%, transparent);
  --sh2:0 8px 30px color-mix(in oklch, hsl(var(--base-content)) 6%, transparent);
  --sh3:0 16px 44px color-mix(in oklch, hsl(var(--base-content)) 9%, transparent);
  color:var(--ink); display:block; overflow-x:clip;
}
/* core.css ships ONE --primary (216deg 100% 45%) for both themes — the same
   blue on a #F0F2F4 page and on a #030C11 one. Measured: 4.55 light (passes)
   but 3.28 dark, so «اظهار الكل» ×11, every band link and every primary chip
   sat under AA in dark mode. Same hue, lifted L → 5.16 on the button fill and
   5.56 on the page. Scoped to .a7h so nothing outside the homepage shifts. */
.dark .a7h, .dark.a7h{ --primary: 216deg 100% 60%; }
.a7h *{box-sizing:border-box}/* bilingual + directional icons */
.a7h .t-en{display:none}.font-english .a7h .t-ar{display:none}.font-english .a7h .t-en{display:inline}.font-english .a7h-band__action svg,.font-english .a7h-focus__go svg,.font-english .a7h-about__link svg,.font-english .a7h-cta svg{transform:scaleX(-1)}/* reveal — the hidden from-state is OPT-IN via .js-reveal, which initReveal()
   stamps on the root as its FIRST statement. Before this, `.a7h .reveal` was
   hidden unconditionally, so anything that stopped home.js — a blocked file, a
   stale nginx upstream after an ASSET_VER bump, or a throw in an earlier init —
   left every band at opacity 0 and the page showing only «مرحبا» (2026-07-29).
   The hidden state can now never outlive the code that removes it. */
.a7h .reveal{transition:opacity .5s var(--ease),transform .5s var(--ease);transition-delay:calc(var(--i,0)*90ms)}.a7h.js-reveal .reveal{opacity:0;transform:translateY(14px)}.a7h.js-reveal .reveal.is-in{opacity:1;transform:none}.a7h.js-reveal .reveal-group.is-in .reveal{opacity:1;transform:none}/* ═════════ HERO ═════════ */
.a7h-hero{position:relative;isolation:isolate;min-height:clamp(19rem,42vh,27rem);
  display:grid;place-items:center;padding:clamp(2.5rem,6vw,5rem) var(--pad);
  background:
    radial-gradient(85% 70% at 50% -8%, color-mix(in oklch, hsl(var(--primary)) 22%, transparent), transparent 62%),
    radial-gradient(60% 55% at 82% 10%, color-mix(in oklch, #f97316 16%, transparent), transparent 60%),
    radial-gradient(66% 62% at 14% 16%, color-mix(in oklch, #7c3aed 18%, transparent), transparent 62%),
    radial-gradient(52% 48% at 62% 44%, color-mix(in oklch, #ec4899 10%, transparent), transparent 60%),
    hsl(var(--base-100));
  -webkit-mask-image:linear-gradient(#000 82%,transparent);mask-image:linear-gradient(#000 82%,transparent)}.dark .a7h-hero,.font-english.dark .a7h-hero,:root[data-theme="dark"] .a7h-hero{
  background:
    radial-gradient(85% 70% at 50% -8%, color-mix(in oklch, hsl(var(--primary)) 26%, transparent), transparent 64%),
    radial-gradient(60% 55% at 82% 10%, color-mix(in oklch, #f97316 16%, transparent), transparent 60%),
    radial-gradient(66% 62% at 14% 16%, color-mix(in oklch, #7c3aed 26%, transparent), transparent 64%),
    radial-gradient(52% 48% at 62% 44%, color-mix(in oklch, #ec4899 14%, transparent), transparent 60%),
    hsl(var(--base-100))}.a7h-hero__inner{width:min(100%,44rem);margin-inline:auto;text-align:center;display:flex;flex-direction:column;align-items:center}.a7h-greet{font-weight:800;font-size:clamp(2.5rem,6vw,4.4rem);line-height:1.02;margin:0;color:var(--ink)}.a7h-sub{margin:.7rem 0 0;color:var(--muted);font-size:clamp(.98rem,.9rem + .4vw,1.15rem);line-height:1.55;max-width:46ch}.a7h-results{position:absolute;inset-inline:0;top:calc(100% + 10px);z-index:60;width:min(100%,40rem);margin-inline:auto;
  max-height:min(62vh,460px);overflow:auto;overscroll-behavior:contain;text-align:start;
  background:hsl(var(--base-100));border:1px solid var(--line2);border-radius:var(--r);box-shadow:var(--sh3);padding:8px}.ah-res__group{padding:6px 6px 10px}.ah-res__gh{font-size:11px;font-weight:800;color:var(--faint);padding:2px 8px 6px}.ah-res__item{display:flex;align-items:center;gap:11px;padding:9px 10px;border-radius:var(--r-in);color:var(--ink);text-decoration:none}.ah-res__item:hover,.ah-res__item[aria-selected="true"]{background:var(--tint)}.ah-res__ic{width:26px;height:26px;flex:0 0 auto;border-radius:8px;display:grid;place-items:center;background:var(--card);font-size:13px;font-weight:800;color:var(--pri)}.ah-res__t{font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ah-res__empty{padding:22px;text-align:center;color:var(--faint);font-size:14px}/* homepage nav (only): pull the section menu toward the centre — with the search's
   own auto-margin this leaves the menu balanced just before the middle, not jammed
   against the A7 brand. Scoped to home.css so other sections' navs are untouched. */
.a7nav-x>ul{margin-inline-start:auto;margin-inline-end:6rem}/* collapse the fixed 1/5 width of the lang/dark cluster so its empty right side
   doesn't leave a gap between «اللغة» and the search — search sits right beside it */
.a7nav-x>div.justify-end{width:auto!important}/* ═════════ search LIVING IN THE NAV (homepage only) — icon by default, expands as an
   OVERLAY (absolute) so widening never reflows the menu ═════════ */
.a7h-navsearch{position:relative;flex:0 0 auto;width:56px;height:33px;margin-inline-start:auto;margin-inline-end:clamp(12px,3.9vw,50px);z-index:5;
  /* re-declare a7 tokens here — the nav lives OUTSIDE the .a7h wrapper, so its
     scoped custom-props don't reach this injected element (else transitions drop
     to instant + dropdown colors break in dark mode). All derive from global daisyUI vars. */
  --card:color-mix(in oklch, hsl(var(--base-content)) 4%, transparent);
  --card-bd:color-mix(in oklch, hsl(var(--base-content)) 10%, transparent);
  --line2:color-mix(in oklch, hsl(var(--base-content)) 22%, transparent);
  --muted:color-mix(in oklch, hsl(var(--base-content)) 66%, transparent);
  --faint:color-mix(in oklch, hsl(var(--base-content)) 42%, transparent);
  --tint:color-mix(in oklch, hsl(var(--primary)) 8%, transparent);
  --tint-bd:color-mix(in oklch, hsl(var(--primary)) 22%, transparent);
  --ink:hsl(var(--base-content));--pri:hsl(var(--primary));
  --ease:cubic-bezier(.16,1,.3,1);--spring:cubic-bezier(.34,1.56,.64,1);
  --r:14px;--r-in:9px;
  --sh2:0 8px 30px color-mix(in oklch, hsl(var(--base-content)) 6%, transparent);
  --sh3:0 16px 44px color-mix(in oklch, hsl(var(--base-content)) 9%, transparent)}/* invisible 44px hit extension (the box's overflow:hidden clips inside it) */
.a7h-navsearch::after{content:"";position:absolute;inset:-6px -4px}.a7h-navsearch__box{position:absolute;top:0;left:0;right:auto;direction:ltr;display:flex;align-items:center;gap:.5rem;height:33px;width:56px;padding-inline:.4rem .35rem;justify-content:flex-start;
  border-radius:999px;overflow:hidden;cursor:text;white-space:nowrap;
  background:color-mix(in oklch, hsl(var(--base-content)) 6%, transparent);
  border:1px solid color-mix(in oklch, hsl(var(--base-content)) 12%, transparent);
  transition:width .4s cubic-bezier(.16,1,.3,1),background-color .2s var(--ease),border-color .2s var(--ease),box-shadow .2s var(--ease)}.a7h-navsearch__box:hover{background:color-mix(in oklch, hsl(var(--base-content)) 9%, transparent);border-color:color-mix(in oklch, hsl(var(--base-content)) 20%, transparent)}.a7h-navsearch__box:focus-within{width:min(230px,72vw);
  background:hsl(var(--base-100));border-color:color-mix(in oklch, hsl(var(--primary)) 45%, transparent);
  box-shadow:0 0 0 3px color-mix(in oklch, hsl(var(--primary)) 13%, transparent),var(--sh2)}.a7h-navsearch__mark{width:18px;height:18px;flex:0 0 auto;color:var(--faint);transition:color .2s var(--ease)}.a7h-navsearch__box:focus-within .a7h-navsearch__mark{color:var(--pri)}.a7h-navsearch #ahSearch{flex:1;min-width:0;width:0;opacity:0;border:0;background:none;font:inherit;font-size:.875rem;color:var(--ink);
  text-align:start;-webkit-appearance:none;appearance:none;transition:opacity .26s var(--ease) .12s}/* kill any global/UA focus ring drawn INSIDE the pill (the box already shows the ring) */
.a7h-navsearch #ahSearch,
.a7h-navsearch #ahSearch:focus,
.a7h-navsearch #ahSearch:focus-visible{outline:none!important;box-shadow:none!important;border:0!important}.a7h-navsearch__box:focus-within #ahSearch{width:auto;opacity:1}.a7h-navsearch #ahSearch::placeholder{color:var(--faint)}.a7h-navsearch__clear{flex:0 0 auto;border:0;background:none;cursor:pointer;font-size:18px;line-height:1;color:var(--faint);padding:6px 10px;margin:-4px -3px;border-radius:50%}.a7h-navsearch__clear:hover{background:color-mix(in oklch, hsl(var(--base-content)) 9%, transparent)}.a7h-results--nav{position:absolute;top:calc(100% + 9px);left:0;right:auto;width:min(92vw,22rem)}@media(max-width:1023px){.a7h-results--nav{width:min(82vw,20rem)}}.a7h-chips{display:flex;flex-wrap:wrap;gap:.5rem;justify-content:center;align-items:center;margin:clamp(1rem,2vw,1.4rem) 0 0;padding:0;list-style:none}.a7h-chips li:first-child{color:var(--faint);font-size:.8125rem;font-weight:700}.a7h-chips a{display:inline-flex;padding:.4rem .85rem;border-radius:999px;font-size:.8125rem;font-weight:600;color:var(--muted);
  text-decoration:none;background:var(--card);border:1px solid var(--card-bd);transition:color .18s var(--ease),border-color .18s var(--ease),transform .18s var(--ease)}.a7h-chips a:hover{color:var(--pri);border-color:var(--tint-bd);transform:translateY(-1px)}.a7h-chips a{position:relative}.a7h-chips a::after{content:"";position:absolute;inset:-8px -2px;border-radius:inherit}@media(hover:none){.a7h-chips{gap:.65rem}}/* ═════════ ABOUT intro ═════════ */
.a7h-about{width:min(100%,62rem);margin:calc(var(--band) * -.2) auto 0;padding-inline:var(--pad);
  display:grid;grid-template-columns:minmax(0,200px) minmax(0,1fr);gap:clamp(1.5rem,4vw,3rem);align-items:center}/* .a7h-about prefix beats the base .a7h-about__portrait{max-width:100%} that
   follows this block in source order (same bug hid every previous shrink) */
@media(max-width:640px){.a7h-about{grid-template-columns:1fr;text-align:center;justify-items:center;gap:1rem}
  /* ⛔ A DEFINITE WIDTH, NOT JUST A CAP. `justify-items:center` makes the <figure> a
     fit-content grid item, so with only `max-width` its inline size resolves from the
     IMAGE FILE's intrinsic width — the aspect-ratio then derives height from that, and
     the whole block resizes itself around whatever the owner uploaded (and collapses
     if the image fails to load). Desktop was never affected: its column track is
     minmax(0,200px), already definite. Confirmed by adversarial audit, measured live. */
  .a7h-about .a7h-about__portrait{width:min(260px,64vw);max-width:100%}
  .a7h-about .a7h-about__role::before{margin-inline:auto}}.a7h-about__portrait{margin:0;max-width:100%}/* ⛔ PIN THE BOX, DO NOT TRACK THE FILE. The markup carries width/height 480x796
   from the SHIPPED portrait; the moment the owner uploads a different ratio those
   numbers lie and the page JUMPS while the image decodes — the exact CLS defect
   already fixed once on this element. Reserving the aspect ratio and letting the
   image cover it means any upload lands in the same hole, no jump, no crop
   surprise beyond the frame. */
/* ⛔ the wave's tail now runs through this box — the portrait has to paint over
   it so the line reads as coming out from BEHIND him, not across his face */
.a7h-about__portrait{aspect-ratio:480/796;position:relative;z-index:1}
/* ⛔ DESKTOP ONLY, AND A TRANSFORM — NOT A MARGIN. The two columns are
   `align-items:center`, so the portrait sat 51px above AND 51px below the copy;
   the owner wanted it lifted («ارفعها لفوق شوي»). A margin would shrink the row and
   move the copy with it; a transform paints it higher and changes no layout, so
   nothing reflows and no jump is introduced. Scoped above 640px — the phone layout
   is a separate design and is being reworked on its own. */
@media(min-width:641px){.a7h-about__portrait{transform:translateY(-58px)}}

.a7h-about__portrait img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block;border-radius:20px;
  /* ⛔ THE BOTTOM FADE IS FOR CUTOUTS ONLY. On a background-removed photo it melts
     into the page; on an ordinary photo it slices the picture in half. Scoped to
     the style the owner picks, defaulting to today's look. */
}
.a7h-about__portrait--cutout img{
  -webkit-mask-image:linear-gradient(to bottom,#000 66%,rgb(0 0 0/.9) 74%,rgb(0 0 0/.6) 86%,transparent 100%);
          mask-image:linear-gradient(to bottom,#000 66%,rgb(0 0 0/.9) 74%,rgb(0 0 0/.6) 86%,transparent 100%);
}
.a7h-about__portrait img{
  /* no shadow (owner spec); hover zoom matched to the prompt cards */
  transition:transform 1.6s var(--ease)}.a7h-about__portrait:hover img{transform:scale(1.03)}@media (prefers-reduced-motion: reduce){
  .a7h-about__portrait img{transition:none}.a7h-about__portrait:hover img{transform:none}
}/* ⛔ THE CHIP BELONGS TO THE NAME, NOT BETWEEN NAME AND BIO. With equal gaps above
   and below it floated as a third separate thing — «مب راكب». Tight above (it is
   the name's subtitle) and open below (a real paragraph break) reads as two groups
   instead of three items. Its weight also drops a notch so it stops competing with
   the name right above it. */
/* ⛔ A RULE + A SUBTITLE, NOT A PILL. Owner: «سوي خط تحت اسمي و تحته اكتب صانع
   محتوى ومطور … الشكل الحالي مب عاجبني». The pill competed with the name for
   attention; a hairline plus quiet text reads as the name's subtitle instead of a
   second badge. The line fades at BOTH ends so it needs no direction handling —
   it looks deliberate in Arabic and English without a mirrored gradient. */
.a7h-about__role{display:block;margin-top:.85rem;padding:0;background:none;border:0;
  border-radius:0;font-size:.82rem;font-weight:600;letter-spacing:.01em;
  color:var(--role-ink)}
/* ⛔ THE TEXT NEVER MOVES AND NEVER DISAPPEARS — it just glows blue, slowly.
   Two cleverer versions failed on the live page and both are recorded here so
   nobody rebuilds them:
     1) a blue duplicate revealed through a moving mask — an absolute child of an
        INLINE element resolves against its line-box fragments, so with Arabic
        shaping the copy sat beside the word and the owner saw it doubled;
     2) painting the glyphs with a travelling gradient (background-clip:text) —
        with `no-repeat` the image leaves the box for most of the cycle and, since
        the fill is transparent, THE WORD VANISHES. Verified by looking at frozen
        frames, not by reading computed styles.
   What ships is the boring version that cannot fail: the colour itself animates.
   No clipping, no masks, nothing to align, nothing to fall outside a box, and the
   text is legible at every single frame.
   ⛔ 7s, glowing for roughly a tenth of it — a slow pulse, not a blinker, and
   prefers-reduced-motion removes it entirely. */
.a7h-about__role{--role-ink:color-mix(in oklch,hsl(var(--base-content)) 62%,transparent)}
.a7h-about__role .t-ar,.a7h-about__role .t-en{
  animation:a7hRoleFlash 7s ease-in-out infinite}
@keyframes a7hRoleFlash{
  0%,74%,100%{color:var(--role-ink);text-shadow:none}
  87%{color:hsl(var(--primary));
      text-shadow:0 0 14px color-mix(in oklch,hsl(var(--primary)) 42%,transparent)}}
@media (prefers-reduced-motion:reduce){
  .a7h .a7h-about__role .t-ar,.a7h .a7h-about__role .t-en{animation:none!important}}
.a7h-about__role::before{content:"";display:block;width:150px;max-width:100%;height:1px;
  margin:0 0 .6rem;
  background:linear-gradient(90deg,transparent,
    color-mix(in oklch,hsl(var(--base-content)) 22%,transparent) 22%,
    color-mix(in oklch,hsl(var(--base-content)) 22%,transparent) 78%,transparent)}.a7h-about__name{margin:0;font-weight:800;font-size:clamp(1.5rem,1.3rem + 1vw,2.2rem);line-height:1.08;letter-spacing:-.01em;color:var(--ink)}.a7h-about__bio{margin:.85rem 0 0;max-width:44ch;color:var(--muted);font-size:clamp(.95rem,.9rem + .2vw,1.05rem);line-height:1.65}.a7h-about__link{display:inline-flex;align-items:center;gap:4px;margin:.15rem -.5rem 0;padding:.75rem .5rem;color:var(--pri);font-weight:700;font-size:.9rem;text-decoration:none;transition:gap .18s var(--ease)}.a7h-about__link:hover{gap:7px}/* ═════════ JOURNEY / BANDS ═════════ */
.a7h-journey{margin-top:var(--band)}.a7h-band{width:100%;margin-top:var(--band);content-visibility:auto;contain-intrinsic-size:auto 500px}.a7h-band:first-child{margin-top:0}.a7h-band:nth-of-type(even){background:color-mix(in oklch, hsl(var(--primary)) 3%, transparent);padding-block:var(--band);margin-top:0}.a7h-band:nth-of-type(even) + .a7h-band{margin-top:0}/* wide PILL header (the a7 signature) */
/* header row: the pill BAR (title only) + the action as a SEPARATE button beside it,
   on the far side (RTL → button sits to the LEFT of the bar). */
.a7h-band__row{display:flex;align-items:stretch;gap:.55rem;width:min(100% - 2*var(--pad),62rem);margin-inline:auto}.a7h-band__head{flex:1 1 auto;min-width:0;display:flex;align-items:center;justify-content:center;
  min-height:40px;padding:.3rem 1.4rem;
  border-radius:12px;background:var(--card);border:1px solid color-mix(in oklch, hsl(var(--base-content)) 6%, transparent);
  box-shadow:inset 0 1px 0 color-mix(in oklch, hsl(var(--base-content)) 4%, transparent),var(--sh1)}.a7h-band__title{text-align:center;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-weight:600;letter-spacing:-.01em;
  font-size:clamp(.9rem,.85rem + .3vw,1.1rem);color:color-mix(in oklch, hsl(var(--base-content)) 92%, transparent)}.a7h-band__action{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;gap:.4rem;white-space:nowrap;
  padding-inline:1.25rem;border-radius:12px;font-size:.85rem;font-weight:700;text-decoration:none;
  color:var(--pri);background:var(--tint);border:1px solid var(--tint-bd);
  transition:background .18s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease)}/* no vertical lift on hover — the button is edge-aligned with the bar beside it,
   so any translateY makes its top edge look like it shifts. Feedback = bg + shadow only. */
.a7h-band__action:hover{background:color-mix(in oklch, hsl(var(--primary)) 16%, transparent);
  box-shadow:0 4px 14px color-mix(in oklch, hsl(var(--primary)) 18%, transparent)}.a7h-band__action:active{transform:scale(.97)}.a7h-band__action{position:relative}.a7h-band__action::after{content:"";position:absolute;inset:-2px 0}.a7h-band__action svg{width:.9em;height:.9em}.a7h-band__rule{height:1px;width:min(100% - 2*var(--pad),62rem);margin:.9rem auto 0;background:linear-gradient(90deg,transparent,var(--line),transparent)}/* #243 admin knobs: optional band subtitle + per-device item counts.
   data-mob="N" (strip containers only) hides items N+1.. on phones. */
.a7h-band__dek{margin:.2rem 0 0;text-align:center;font-size:.78rem;font-weight:500;
  color:color-mix(in oklch, hsl(var(--base-content)) 55%, transparent);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media (max-width:640px){
  .a7h [data-mob="1"] > :nth-child(n+2),.a7h [data-mob="2"] > :nth-child(n+3),
  .a7h [data-mob="3"] > :nth-child(n+4),.a7h [data-mob="4"] > :nth-child(n+5),
  .a7h [data-mob="5"] > :nth-child(n+6),.a7h [data-mob="6"] > :nth-child(n+7),
  .a7h [data-mob="7"] > :nth-child(n+8),.a7h [data-mob="8"] > :nth-child(n+9),
  .a7h [data-mob="9"] > :nth-child(n+10),.a7h [data-mob="10"] > :nth-child(n+11){display:none}
}@media(max-width:480px){.a7h-band__row{gap:.4rem}.a7h-band__action{padding-inline:.9rem;font-size:.8rem}.a7h-band__head{padding-inline:.9rem}.a7h-band__title{font-size:.9rem}}/* ── BAND RHYTHM (page-wide standard) ── rule→content gap = 12px for EVERY
   band: the content root's margin-top + padding-top MUST sum to 12. Roots
   with no padding-top take the full 12 as margin; scroll strips keep a small
   padding-top as shadow/beam clip headroom and take only the remainder as
   margin. (.a7h-arc/.a7h-fan/.a7h-cf are RETIRED treatments — if revived,
   their padding-block:1rem must be re-budgeted to honor the sum.)
   New band → register its root here, don't invent per-band gaps. */.a7h-band > .a7h-rail,.a7h-band > .a7h-focus,.a7h-band > .a7h-empty,.a7h-band > .a7h-ko,.a7h-band > .a7h-go{
  margin-top:12px}/* + .5rem padding-top = 12 */

/* media + placeholder (shared) */
.a7h-card__media{display:block;overflow:hidden;border-radius:var(--r);aspect-ratio:1;background:var(--card);border:1px solid var(--card-bd);
  transition:transform .25s var(--ease),box-shadow .25s var(--ease),border-color .18s var(--ease),background .18s var(--ease)}.a7h-card__media[data-ratio="portrait"]{aspect-ratio:3/4}.a7h-card__media[data-ratio="watch"]{aspect-ratio:1;border-radius:50%}.a7h-card__media[data-ratio="crest"]{aspect-ratio:1}.a7h-card__media img{width:100%;height:100%;object-fit:cover;display:block}.a7h-fatile{display:grid;place-items:center;font-size:26px;color:#111;background:var(--c,#eee)!important}.a7h-ph{display:grid;place-items:center;color:var(--pri);
  background:radial-gradient(120% 120% at 30% 20%, color-mix(in oklch, hsl(var(--primary)) 14%, transparent), color-mix(in oklch, hsl(var(--base-content)) 4%, transparent));
  box-shadow:inset 0 0 0 1px color-mix(in oklch, hsl(var(--base-content)) 10%, transparent)}.a7h-ph__g{width:38%;height:38%;opacity:.6}/* RAIL (calm base) */
.a7h-rail{display:flex;gap:var(--gap);list-style:none;overflow-x:auto;scroll-snap-type:x proximity;
  padding:.5rem var(--pad) 1rem;margin:0;scrollbar-width:none;width:min(100%,72rem);margin-inline:auto}.a7h-rail::-webkit-scrollbar{display:none}.a7h-card{flex:0 0 clamp(9rem,38vw,12.5rem);scroll-snap-align:start;position:relative}.a7h-card__link{display:block;text-decoration:none;color:inherit}.a7h-card__title{display:block;margin-top:.5rem;padding-inline:.15rem;font-weight:600;font-size:.9375rem;line-height:1.3;
  color:color-mix(in oklch, hsl(var(--base-content)) 90%, transparent);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.a7h-card:hover .a7h-card__media{transform:translateY(-3px);border-color:var(--tint-bd);
  background:color-mix(in oklch, hsl(var(--primary)) 7%, transparent);box-shadow:var(--sh3)}/* LEAGUES MARQUEE — infinite pure-CSS auto-scroll (owner's reveal-track spec).
   Track = 2 identical sets; keyframe slides 0 → -50%. One period = set width
   + its trailing 12px padding (padding on the SET, not gap on the track, so
   -50% lands exactly one period — no seam jump). Wrapper forced LTR so the
   -50% direction is deterministic under the RTL page; cards restore RTL
   internally. Hover/focus pauses; reduced-motion → plain scrollable strip. */@keyframes a7h-mq-scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}/* «صافرة البداية» — LEAGUES next-kickoff ticket: one frosted card for the
   soonest fixture (crest vs crest + live countdown + viewer-local time +
   «أضِف للتقويم») over a slim upcoming-pills rail. League accent arrives as
   --lg and is only ever a quiet wash/tint — never a glow or shadow. */
.a7h-ko{width:min(100% - 2*var(--pad),62rem);margin-inline:auto}.a7h-ko__hero{display:flex;align-items:center;justify-content:space-between;gap:clamp(.6rem,2.5vw,2rem);
  padding:clamp(1rem,3vw,1.5rem) clamp(.9rem,3.5vw,2rem);border-radius:22px;text-decoration:none;color:inherit;
  border:1px solid var(--card-bd);position:relative;overflow:hidden;
  background:radial-gradient(120% 160% at 50% -30%, color-mix(in oklch, var(--lg,#1473ff) 9%, transparent), transparent 60%),var(--card);
  box-shadow:inset 0 1px 0 color-mix(in oklch, #fff 14%, transparent);
  transition:border-color 1.6s var(--ease),transform 1.6s var(--ease)}.a7h-ko__hero:hover{border-color:color-mix(in oklch, var(--lg,#1473ff) 32%, var(--card-bd));transform:scale(1.01)}.a7h-ko__side{display:flex;flex-direction:column;align-items:center;gap:.55rem;min-width:0;flex:1}.a7h-ko__crest{width:clamp(2.9rem,8vw,4.5rem);height:clamp(2.9rem,8vw,4.5rem);object-fit:contain;display:block}.a7h-ko__crest--ph{border-radius:50%;background:color-mix(in oklch, hsl(var(--base-content)) 8%, transparent)}.a7h-ko__team{font-weight:700;font-size:clamp(.72rem,2vw,.95rem);max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.a7h-ko__mid{display:flex;flex-direction:column;align-items:center;gap:.4rem;flex:0 1 auto;min-width:0}.a7h-ko__lg{font-size:.8rem;font-weight:600;color:color-mix(in oklch, hsl(var(--base-content)) 62%, transparent)}.a7h-ko__cd{display:flex;gap:clamp(.45rem,1.6vw,.9rem)}.a7h-ko__seg{display:flex;flex-direction:column;align-items:center;gap:.15rem}.a7h-ko__seg b{font-weight:800;font-size:clamp(1.1rem,3.4vw,1.7rem);line-height:1;
  font-variant-numeric:tabular-nums;letter-spacing:.02em}.a7h-ko__seg i,.a7h-ko__seg .a7h-ic{font-style:normal;font-size:.62rem;
  color:color-mix(in oklch, hsl(var(--base-content)) 48%, transparent)}.a7h-ko__when{font-size:.8rem;color:color-mix(in oklch, hsl(var(--base-content)) 58%, transparent);
  font-variant-numeric:tabular-nums;min-height:1em}.a7h-ko__cta{display:inline-flex;align-items:center;gap:.4rem;font-size:.85rem;font-weight:700;
  color:var(--pri);margin-top:.15rem}.a7h-ko__cta svg{width:15px;height:15px;flex:0 0 auto}.a7h-ko__rail{display:flex;gap:10px;margin-top:12px;overflow-x:auto;scroll-snap-type:x proximity;
  padding:.15rem .15rem .35rem;scrollbar-width:none;
  -webkit-mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%)}.a7h-ko__rail::-webkit-scrollbar{display:none}.a7h-ko__pill{flex:0 0 auto;scroll-snap-align:start;display:inline-flex;align-items:center;gap:.45rem;
  padding:.45rem .8rem;border-radius:999px;border:1px solid var(--card-bd);background:var(--card);
  text-decoration:none;color:inherit;font-size:.75rem;
  transition:border-color 1.6s var(--ease),background 1.6s var(--ease)}.a7h-ko__pill:hover{border-color:var(--tint-bd);background:color-mix(in oklch, hsl(var(--primary)) 6%, var(--card))}.a7h-ko__pc{width:18px;height:18px;object-fit:contain;display:block}.a7h-ko__pc.a7h-ko__crest--ph{border-radius:50%}.a7h-ko__pvs{font-size:.62rem;opacity:.5}.a7h-ko__pt{color:color-mix(in oklch, hsl(var(--base-content)) 55%, transparent);
  font-variant-numeric:tabular-nums;white-space:nowrap}@media (prefers-reduced-motion:reduce){
  .a7h-ko__hero,.a7h-ko__pill{transition:none}.a7h-ko__hero:hover{transform:none}
}/* ═══ «باسمك» — GREETING CARDS ═══ one card, the visitor's name landing in the
   design's own measured plate, two blurred cards behind for depth. All of this
   is scoped to .a7h-nc; deleting this block reverts the band to the arc fan. */
.a7h-nc{width:min(100% - 2*var(--pad),62rem);margin-inline:auto;display:flex;flex-direction:column;align-items:center;gap:.7rem}.a7h-nc__stage{position:relative;display:grid;place-items:center;
  width:clamp(11rem,34vw,14rem);aspect-ratio:9/16}.a7h-nc__card{position:relative;display:block;width:100%;height:100%;border-radius:16px;overflow:hidden;
  border:1px solid var(--card-bd);background:var(--card);box-shadow:var(--sh2)}/* the artwork zooms, the frame never moves — so the card keeps its place in
   the page while the name becomes readable */
.a7h-nc__zoom{position:absolute;inset:0;transform-origin:var(--zx,50%) var(--zy,88%);
  transition:transform 1.6s var(--ease)}.a7h-nc__card img{width:100%;height:100%;object-fit:cover;display:block}.a7h-nc__card:hover .a7h-nc__zoom{transform:scale(1.02)}/* typing pulls the card in toward the name plate (set as --zx/--zy from the
   measured rect) so a 6px name becomes ~16px and the point actually lands */
.a7h-nc.is-typing .a7h-nc__zoom{transform:scale(var(--zs,1.3))}.a7h-nc.is-typing .a7h-nc__card:hover .a7h-nc__zoom{transform:scale(var(--zs,1.3))}.a7h-nc__ghost{position:absolute;top:0;width:100%;height:100%;object-fit:cover;border-radius:16px;
  filter:blur(3px) saturate(.85);opacity:.45;pointer-events:none;
  transform:translateX(calc(var(--g) * 14%)) scale(.94) rotate(calc(var(--g) * 2deg));
  transform-origin:50% 100%;transition:opacity 1.6s var(--ease)}.a7h-nc__ghost:nth-of-type(2){transform:translateX(calc(var(--g) * -14%)) scale(.94) rotate(calc(var(--g) * -2deg))}/* while zoomed in, the ghosts step back so nothing competes with the name */
.a7h-nc.is-typing .a7h-nc__ghost{opacity:.3}/* the name sits INSIDE the artwork's own plate — measured per design */
.a7h-nc__slot{position:absolute;display:grid;place-items:center;overflow:hidden;pointer-events:none;
  container-type:inline-size}.a7h-nc__name{font-weight:800;color:#141414;line-height:1;white-space:nowrap;
  font-size:min(9cqw,80cqh);max-width:96%;overflow:hidden;text-overflow:clip;
  transition:opacity 1.6s var(--ease)}.a7h-nc__pill{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .3rem .3rem .9rem;
  border-radius:999px;border:1px solid var(--card-bd);background:var(--card);
  backdrop-filter:blur(14px) saturate(1.2);-webkit-backdrop-filter:blur(14px) saturate(1.2);
  box-shadow:inset 0 1px 0 color-mix(in oklch,#fff 12%,transparent);
  transition:border-color 1.6s var(--ease)}.a7h-nc__pill:focus-within{border-color:color-mix(in oklch,hsl(var(--primary)) 40%,var(--card-bd));
  box-shadow:inset 0 1px 0 color-mix(in oklch,#fff 12%,transparent),
             0 0 0 3px color-mix(in oklch,hsl(var(--primary)) 14%,transparent)}/* no focus box on the field itself — the whole pill lights up instead, so
   typing never draws a hard blue rectangle inside the glass */
.a7h-nc__in{border:0;background:none;outline:none;box-shadow:none;-webkit-appearance:none;appearance:none;
  color:inherit;font:inherit;font-size:.9rem;font-weight:600;
  inline-size:min(42vw,11rem);padding-block:.35rem}.a7h-nc__in:focus,.a7h-nc__in:focus-visible{outline:none;box-shadow:none}.a7h-nc__in::placeholder{color:color-mix(in oklch,hsl(var(--base-content)) 42%,transparent);font-weight:500}.a7h-nc__go{display:inline-flex;align-items:center;gap:.25rem;border:0;cursor:pointer;
  padding:.45rem .85rem;border-radius:999px;font:inherit;font-size:.8rem;font-weight:700;
  background:hsl(var(--primary));color:hsl(var(--primary-content,0 0% 100%));
  transition:filter 1.6s var(--ease)}.a7h-nc__go:hover{filter:brightness(1.06)}.a7h-nc__go svg{width:13px;height:13px}.a7h-nc__hint{margin:0;font-size:.75rem;text-align:center;
  color:color-mix(in oklch,hsl(var(--base-content)) 52%,transparent)}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media (prefers-reduced-motion:reduce){
  .a7h-nc__zoom,.a7h-nc__name,.a7h-nc__pill,.a7h-nc__go,.a7h-nc__ghost{transition:none}.a7h-nc__card:hover .a7h-nc__zoom{transform:none}
}/* «الرابط الحيّ» — SMART LINKS: one frosted pill holding a FINISHED link, and a
   strip of apps that rewrites it live. The pill is a link, never a form: no
   caret, no input chrome, no placeholder grey — that reading is what makes the
   band feel like a result instead of a field dumped on the homepage. */
.a7h-go{width:min(100% - 2*var(--pad),62rem);margin-inline:auto;display:flex;flex-direction:column;align-items:center;gap:.55rem}.a7h-go__pill{display:inline-flex;align-items:center;gap:.6rem;max-width:100%;
  padding:.7rem clamp(.85rem,3vw,1.15rem);border-radius:999px;text-decoration:none;color:inherit;
  border:1px solid color-mix(in oklch, var(--tint,#1473ff) 26%, var(--card-bd));
  background:color-mix(in oklch, var(--tint,#1473ff) 7%, var(--card));
  backdrop-filter:blur(14px) saturate(1.2);-webkit-backdrop-filter:blur(14px) saturate(1.2);
  box-shadow:inset 0 1px 0 color-mix(in oklch, #fff 12%, transparent);
  transition:border-color 1.6s var(--ease),background 1.6s var(--ease),transform 1.6s var(--ease);
  caret-color:transparent;cursor:pointer}.a7h-go__pill:hover{transform:scale(1.012);border-color:color-mix(in oklch, var(--tint,#1473ff) 45%, var(--card-bd))}.a7h-go__mark{width:26px;height:26px;object-fit:contain;flex:0 0 auto;border-radius:7px;
  transition:opacity 1.6s var(--ease)}.a7h-go__url{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:clamp(.72rem,2.5vw,.92rem);
  font-weight:600;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  unicode-bidi:isolate;min-width:0}.a7h-go__pre{color:color-mix(in oklch, hsl(var(--base-content)) 45%, transparent)}.a7h-go__slug,.a7h-go__val{color:hsl(var(--base-content));transition:opacity 1.6s var(--ease)}.a7h-go__go{width:15px;height:15px;flex:0 0 auto;color:var(--pri);opacity:.85}.a7h-go__hint{margin:0;font-size:.75rem;text-align:center;
  color:color-mix(in oklch, hsl(var(--base-content)) 52%, transparent)}.a7h-go__strip{display:flex;gap:10px;max-width:100%;overflow-x:auto;scroll-snap-type:x proximity;
  padding:.35rem .15rem .5rem;scrollbar-width:none;
  -webkit-mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(10px,2.4vw,28px),#000 clamp(26px,6vw,64px),#000 calc(100% - clamp(26px,6vw,64px)),rgba(0,0,0,.18) calc(100% - clamp(10px,2.4vw,28px)),transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(10px,2.4vw,28px),#000 clamp(26px,6vw,64px),#000 calc(100% - clamp(26px,6vw,64px)),rgba(0,0,0,.18) calc(100% - clamp(10px,2.4vw,28px)),transparent 100%)}.a7h-go__strip::-webkit-scrollbar{display:none}/* one shared plate behind every mark so black/white logos (X, TikTok) stay
   readable in BOTH themes without per-brand exceptions */
.a7h-go__chip{flex:0 0 auto;scroll-snap-align:center;display:flex;flex-direction:column;align-items:center;gap:.3rem;
  padding:.4rem .5rem;border-radius:14px;border:1px solid transparent;background:none;cursor:pointer;
  color:inherit;font:inherit;min-width:56px;
  transition:border-color 1.6s var(--ease),background 1.6s var(--ease)}.a7h-go__ci{width:30px;height:30px;object-fit:contain;border-radius:8px;padding:2px;
  background:color-mix(in oklch, hsl(var(--base-content)) 7%, transparent);
  filter:saturate(.25) opacity(.6);transition:filter 1.6s var(--ease),transform 1.6s var(--ease)}.a7h-go__cn{font-size:.66rem;font-weight:600;white-space:nowrap;
  color:color-mix(in oklch, hsl(var(--base-content)) 55%, transparent);transition:color 1.6s var(--ease)}.a7h-go__chip:hover .a7h-go__ci,.a7h-go__chip:focus-visible .a7h-go__ci{filter:none;transform:scale(1.06)}.a7h-go__chip.is-on .a7h-go__ci{filter:none}.a7h-go__chip.is-on{border-color:color-mix(in oklch, var(--tint,#1473ff) 34%, transparent);
  background:color-mix(in oklch, var(--tint,#1473ff) 8%, transparent)}.a7h-go__chip.is-on .a7h-go__cn{color:hsl(var(--base-content))}@media (prefers-reduced-motion:reduce){
  .a7h-go__pill,.a7h-go__mark,.a7h-go__slug,.a7h-go__val,.a7h-go__ci,.a7h-go__cn,.a7h-go__chip{transition:none}.a7h-go__pill:hover{transform:none}.a7h-go__chip:hover .a7h-go__ci{transform:none}
}/* APP DISCOVERY — compact icon cards + flush «تنزيل» footer (prompt-button family) */
.a7h-ap{display:flex;gap:var(--gap);overflow-x:auto;scroll-snap-type:x proximity;
  padding:.5rem var(--pad) 1rem;margin:0;scrollbar-width:none;
  width:min(100% - 2*var(--pad),62rem);margin-inline:auto;scroll-padding-inline:var(--pad);
  -webkit-mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%)}.a7h-ap::-webkit-scrollbar{display:none}.a7h-ap__card{flex:0 0 clamp(8rem,33vw,9rem);scroll-snap-align:start;display:flex;flex-direction:column;
  position:relative;background:var(--card);border:1px solid var(--card-bd);border-radius:18px;
  box-shadow:var(--sh1);transition:box-shadow .25s var(--ease),border-color .2s var(--ease)}.a7h-ap__card:hover{border-color:var(--line2);box-shadow:var(--sh2)}/* App-Store style: the icon floats INSIDE the card (own squircle rounding)
   instead of a full-bleed square — kills the oversized feel on desktop */
.a7h-ap__media{display:block;padding:.85rem .85rem 0}.a7h-ap__media img{width:100%;aspect-ratio:1;object-fit:cover;display:block;
  /* matched to prompts/shortcuts: 1.6s on the theme ease-out curve */
  border-radius:22%;transition:transform 1.6s var(--ease)}/* same zoom-on-hover as the prompt cards */
.a7h-ap__card:hover .a7h-ap__media img{transform:scale(1.03)}@media (prefers-reduced-motion: reduce){
  .a7h-ap__media img{transition:none}.a7h-ap__card:hover .a7h-ap__media img{transform:none}
}.a7h-ap__n{display:block;margin:.75rem .6rem .375rem;font-weight:600;font-size:.85rem;line-height:1.3;
  color:color-mix(in oklch, hsl(var(--base-content)) 90%, transparent);text-decoration:none}/* plaintext bidi = ellipsis always at the name's LOGICAL end, so English names
   show their FIRST words (not a chopped tail) even inside the RTL page */
.a7h-ap__n .t-ar,.a7h-ap__n .t-en{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  unicode-bidi:plaintext;text-align:center}
body:not(.font-english) .a7h-ap__n .t-en{display:none}
body.font-english .a7h-ap__n .t-ar{display:none}
body.font-english .a7h-ap__n .t-en{display:block}.a7h-ap__d{margin:0 .65rem 1.125rem;font-size:.72rem;line-height:1.6;font-weight:500;color:var(--muted)}/* owner spec: Arabic description right-aligned, English left-aligned */
.a7h-ap__d .t-ar{text-align:right;direction:rtl}.a7h-ap__d .t-en{text-align:left;direction:ltr}/* 2-line clamp needs -webkit-box display — restate the global .t-ar/.t-en
   visibility swap at higher specificity so the box display never leaks the
   hidden language back in */
.a7h-ap__d .t-ar,.a7h-ap__d .t-en{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
body:not(.font-english) .a7h-ap__d .t-en{display:none}
body.font-english .a7h-ap__d .t-ar{display:none}
body.font-english .a7h-ap__d .t-en{display:-webkit-box}.a7h-ap__dl{margin-top:auto;display:inline-flex;align-items:center;justify-content:center;gap:.4rem;
  border-top:1px solid var(--tint-bd);background:var(--tint);color:var(--pri);text-decoration:none;
  font-weight:700;font-size:.8rem;padding:.75rem .5rem;border-radius:0 0 17px 17px;
  transition:background .2s var(--ease)}.a7h-ap__dl:hover{background:color-mix(in oklch, hsl(var(--primary)) 14%, transparent)}.a7h-ap__dl svg{width:16px;height:16px}/* SHORTCUT TILES — iOS-style small rects: icon top-start, name on-card,
   bottom scrim melting upward */
.a7h-st{display:flex;gap:var(--gap);overflow-x:auto;scroll-snap-type:x proximity;
  padding:.5rem var(--pad) 1rem;margin:0;scrollbar-width:none;
  width:min(100% - 2*var(--pad),62rem);margin-inline:auto;scroll-padding-inline:var(--pad);
  -webkit-mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%)}.a7h-st::-webkit-scrollbar{display:none}.a7h-st__tile{position:relative;flex:0 0 clamp(9.5rem,40vw,12rem);aspect-ratio:1.76;scroll-snap-align:start;
  border-radius:18px;text-decoration:none;
  /* iOS-Shortcuts gradient: clearly lighter airy top melting into the full color */
  background:linear-gradient(172deg,color-mix(in oklch,var(--c) 68%,white) 0%,var(--c) 72%);
  box-shadow:var(--sh1);transition:transform .25s var(--ease),box-shadow .25s var(--ease)}/* fixed RIGHT (owner spec «يمين فوق») — the strip's scroll context is LTR,
   so logical inset-inline-start would land LEFT; pin physically instead */
/* --on is computed per tile by render.py::_tile_ink from the ADMIN's colour;
   a hardcoded #fff hit 1.08:1 on the pale «موقف السيارة» tile (2026-07-29).
   The icon sits at the TOP, over the gradient's lightest stop (68% --c + white)
   and outside the bottom scrim, so a white icon keeps its dark drop-shadow —
   a dark icon on a pale tile needs none and a dark shadow would only smudge it. */
.a7h-st__tile i,.a7h-st__tile .a7h-ic{position:absolute;top:.7rem;right:.75rem;z-index:2;font-size:1.3rem;
  color:var(--on,#fff)}.a7h-st__tile[style*="--on:#ffffff"] i,.a7h-st__tile[style*="--on:#ffffff"] .a7h-ic{filter:drop-shadow(0 1px 2px rgb(0 0 0/.35))}.a7h-st__n{position:absolute;bottom:.55rem;left:.75rem;right:.75rem;z-index:2;color:var(--on,#fff);font-weight:700;
  font-size:.875rem;line-height:1.3;text-align:right;direction:rtl;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}/* the name was pinned to rtl/right for the Arabic strip; in English that reverses
   the reading order of a Latin name and pushes it away from the icon */
.font-english .a7h-st__n{direction:ltr;text-align:left}/* --sc is the scrim render.py::_tile_ink computed for THIS tile: strong enough,
   and in the direction away from --on, that the composited background under the
   name clears WCAG AA. The rgb(0 0 0/.34) fallback only applies to HTML cached
   before this shipped. */
.a7h-st__tile::after{content:"";position:absolute;inset-inline:0;bottom:0;height:52%;
  border-radius:0 0 18px 18px;pointer-events:none;z-index:1;
  /* ⛔ render.py::_tile_ink solves AA against a FLAT --sc. A pure fade makes the
     real composite under the name lighter than the model, which is why tiles
     still failed AA after the first attempt (2026-07-30). Hold --sc at full
     strength across the bottom 58%, then melt. 58% is not arbitrary: the glyph
     cap-top sits ~23.2px above the tile bottom and does NOT scale (font-size is a
     fixed 14px), while the narrowest tile (9.5rem → 86.4px tall) has only a
     44.9px scrim — so the plateau must reach 23.2/44.9 = 51.6% or the top of the
     letters lands in the ramp and _tile_ink's flat model over-certifies. */
  background:linear-gradient(to top,var(--sc,rgb(0 0 0/.34)) 0,var(--sc,rgb(0 0 0/.34)) 58%,transparent 100%)}/* the tile IS the reveal element — initReveal() stamps is-in on the TILES
   themselves (never on the group), so gate on the tile's own is-in to retake
   transform + transition from the reveal rules. Hover = grow only, NO shadow. */
.a7h .a7h-st__tile.reveal.is-in{transform:none;
  /* owner-tuned: extra slow — 1.6s on the theme ease-out curve */
  transition:transform 1.6s var(--ease),opacity .8s cubic-bezier(0,0,.5,1)}.a7h .a7h-st__tile.reveal.is-in:hover{transform:scale(1.1)}@media (prefers-reduced-motion: reduce){
  .a7h-st__tile{transition:none}.a7h .a7h-st__tile.reveal.is-in{transition:none}.a7h .a7h-st__tile.reveal.is-in:hover{transform:none}
}/* FOCUS (featured) */
.a7h-focus{display:grid;grid-template-columns:1fr;border-radius:var(--r);overflow:hidden;text-decoration:none;color:var(--ink);
  width:min(100% - 2*var(--pad),62rem);margin-inline:auto;background:var(--card);border:1px solid var(--card-bd);
  transition:transform .35s var(--ease),box-shadow .35s var(--ease)}.a7h-focus:hover{transform:translateY(-3px);box-shadow:var(--sh3)}@media(min-width:720px){.a7h-focus{grid-template-columns:1.5fr 1fr}}.a7h-focus__m{aspect-ratio:16/9;overflow:hidden}.a7h-focus__m .a7h-card__media{border:0;border-radius:0;height:100%;aspect-ratio:auto}.a7h-focus__b{padding:24px 26px;display:flex;flex-direction:column;justify-content:center;gap:14px}.a7h-focus__t{font-weight:800;font-size:clamp(1.15rem,3vw,1.6rem);line-height:1.25}.a7h-focus__go{align-self:flex-start;display:inline-flex;align-items:center;gap:5px;font-size:13px;font-weight:800;color:#fff;
  background:var(--pri);padding:9px 18px;border-radius:999px}/* FAN (cards signature) *//* ARC (my_apps closer) *//* COVERFLOW (wallpapers) */.a7h-empty{color:var(--faint);font-size:14px;text-align:center;width:min(100% - 2*var(--pad),62rem);margin-inline:auto}/* CLOSING */
.a7h-closing{text-align:center;padding:clamp(46px,8vw,92px) var(--pad)}.a7h-closing__in{display:flex;flex-direction:column;align-items:center}.a7h-closing__h{font-weight:800;font-size:clamp(1.6rem,4.2vw,2.4rem);margin:0 0 12px}.a7h-closing__p{color:var(--muted);max-width:44ch;margin:0 auto 24px}.a7h-cta{display:inline-flex;align-items:center;gap:8px;background:var(--pri);color:#fff;font-weight:700;padding:13px 26px;border-radius:999px;text-decoration:none;box-shadow:var(--sh2);transition:transform .2s var(--ease)}.a7h-cta:hover{transform:translateY(-2px)}.a7h-maint{padding:100px 20px;text-align:center;font-size:18px;font-weight:700}/* ===== NEWS «TIME MACHINE» — 3D deck scrubbed by a vertical time axis =====
   axis is FLUSH with the band bar's start edge (same 62rem container, no pad):
   RTL → right, English (forced ltr below) → left. Deck flexes + centers. */
.a7h-band--tm{content-visibility:visible;contain-intrinsic-size:none}.a7h-band > .a7h-tm{width:min(100% - 2*var(--pad),62rem);margin-inline:auto;margin-top:12px;position:relative}.font-english .a7h-tm__stage{direction:ltr}.a7h-tm__stage{display:flex;align-items:center;gap:clamp(.5rem,2vw,1.25rem)}/* deck hugs the card: height = card height (width/1.6) + 6px bottom slack; the
   active card top sits exactly at the deck top (top:50% − 3px = half the slack)
   → rule→card gap = the root's 12px margin. JS lift is capped at 7px/step so no
   PROJECTED behind-card top (translateZ −62·o under perspective 1100) rises
   above the deck. align-self:flex-start pins the deck to the stage top whenever
   the axis column is the taller flex child (≤~440px and 561-789px with 6 items)
   — align-items:center would re-sink it and reopen the gap. */
.a7h-tm__deck{position:relative;flex:1 1 auto;min-width:0;align-self:flex-start;
  height:calc(clamp(16rem,60vw,31rem) / 1.6 + 6px);
  perspective:1100px;transform-style:preserve-3d}.a7h-tm__card{position:absolute;left:50%;top:calc(50% - 3px);
  width:clamp(16rem,60vw,31rem);aspect-ratio:1.6;border-radius:clamp(16px,2.4vw,28px);
  transform:translate(-50%,-50%);
  transition:transform .62s var(--ease),opacity .55s var(--ease),box-shadow .3s var(--ease);
  will-change:transform,opacity;backface-visibility:hidden}/* physically-correct exit: departing card ACCELERATES past the camera (ease-in
   mirror of the entry curve) and fades before it travels far */
.a7h-tm__card.is-past{transition:transform .5s cubic-bezier(.5,0,1,1),opacity .3s cubic-bezier(.55,0,1,.45)}/* instant reset on auto-advance wrap — no reverse card-shower */
.a7h-tm--noanim .a7h-tm__card{transition:none!important}.a7h-tm__card{z-index:1;overflow:hidden;text-decoration:none;color:inherit;
  background:var(--card);border:1px solid var(--card-bd);box-shadow:var(--sh3);outline:none}.a7h-tm__card:not(.is-active){pointer-events:none}.a7h-tm__card:focus-visible{box-shadow:0 0 0 3px var(--ring),var(--sh3)}/* the deck's only link responds to hover like every other clickable on the page:
   neutral-ink deeper shadow + image-only zoom (frame stays put) */
.a7h-tm__card.is-active:hover{box-shadow:0 18px 52px color-mix(in oklch,hsl(var(--base-content)) 16%,transparent),var(--sh3)}.a7h-tm__media{position:absolute;inset:0;overflow:hidden}.a7h-tm__media img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .5s var(--ease)}.a7h-tm__card.is-active:hover .a7h-tm__media img{transform:scale(1.04)}.a7h-tm__phg{width:34%;height:34%;position:absolute;inset:0;margin:auto;display:block;color:var(--pri);opacity:.5}.a7h-tm__scrim{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,color-mix(in oklch,#000 64%,transparent) 0%,color-mix(in oklch,#000 14%,transparent) 44%,transparent 72%)}.a7h-tm__cap{position:absolute;inset-inline:0;inset-block-end:0;padding:.9rem 1.1rem 1rem;
  display:flex;flex-direction:column;gap:.3rem;color:#fff;
  opacity:0;transform:translateY(6px);transition:opacity .4s var(--ease) .05s,transform .4s var(--ease) .05s}.a7h-tm__card.is-active .a7h-tm__cap{opacity:1;transform:none}.a7h-tm__t{font-weight:700;font-size:clamp(.92rem,.64rem + .85vw,1.06rem);line-height:1.42;
  /* ⛔ was display:block;white-space:nowrap — 5 of 6 live headlines were cut
     (scrollWidth 649-890px into a 459px box, measured 2026-07-30). Two lines
     is the honest fit; the -webkit-box clamp needs overflow:hidden and must
     NOT be followed by display:block or white-space:nowrap, which override it. */
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;
  text-shadow:0 1px 8px rgba(0,0,0,.45)}/* fading hairline between the one-line title and the publish time */
.a7h-tm__hr{display:block;height:1px;width:100%;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.55),transparent)}.a7h-tm__ago{font-size:.7rem;font-weight:500;opacity:.72;letter-spacing:0;font-variant-numeric:tabular-nums}.font-english .a7h-tm__t{letter-spacing:-.01em}.font-english .a7h-tm__ago{letter-spacing:.04em}/* axis — hairline time ruler pinned at the container's start edge (bar-aligned).
   Node hit-boxes are 24px tall (WCAG 2.5.8); the visible dash stays a 2px line. */
.a7h-tm__axis{position:relative;flex:0 0 auto;display:flex;flex-direction:column;align-items:flex-start;
  gap:3px;padding-block:.4rem;outline:none;border-radius:10px}.a7h-tm__axis:focus-visible{box-shadow:0 0 0 3px var(--ring)}.a7h-tm__node{position:relative;display:flex;align-items:center;justify-content:flex-start;
  width:5.5rem;height:24px;padding:0;margin:0;border:0;background:none;cursor:pointer;outline:none}.a7h-tm__dash{height:2px;width:28px;border-radius:1px;background:var(--hair);opacity:.5;
  transform-origin:right center;
  transition:transform .3s var(--spring),background .2s var(--ease),opacity .2s var(--ease)}.font-english .a7h-tm__dash{transform-origin:left center}.a7h-tm__node:hover .a7h-tm__dash{opacity:.85;transform:scaleX(1.15)}.a7h-tm__node[aria-selected="true"] .a7h-tm__dash{background:var(--pri);opacity:1;transform:scaleX(1.5)}.a7h-tm__sub{position:relative;display:block;width:5.5rem;height:10px;cursor:pointer}.a7h-tm__sub::after{content:"";position:absolute;inset-inline-start:0;top:50%;transform:translateY(-50%);
  height:2px;width:19px;border-radius:1px;background:var(--hair);opacity:.22;transition:opacity .2s var(--ease),transform .2s var(--ease)}.a7h-tm__sub:hover::after{opacity:.4;transform:translateY(-50%) scaleX(1.15)}@media(hover:none){.a7h-tm__sub{display:none}}/* touch: subs are sub-24px decorative scrub aids */
.a7h-tm__date{position:absolute;inset-inline-start:3.2rem;top:50%;transform:translateY(-50%) translateX(-3px);
  white-space:nowrap;font-size:.7rem;font-weight:500;color:var(--muted);pointer-events:none;
  opacity:0;transition:opacity .18s var(--ease),transform .18s var(--ease)}.font-english .a7h-tm__date{transform:translateY(-50%) translateX(3px)}.a7h-tm__node:hover .a7h-tm__date,.a7h-tm__node[aria-selected="true"] .a7h-tm__date{opacity:1;transform:translateY(-50%)}.a7h-tm__node[aria-selected="true"] .a7h-tm__date{color:var(--pri);font-weight:600}@media(max-width:560px){
  .a7h-tm__stage{gap:.5rem}.a7h-tm__sub{display:none}.a7h-tm__node[aria-selected="true"] .a7h-tm__date{background:hsl(var(--base-100));padding-inline:4px;border-radius:6px}.a7h-tm__node,.a7h-tm__sub{width:4.2rem}.a7h-tm__dash{width:22px}.a7h-tm__date{inset-inline-start:2.45rem;font-size:.66rem}.a7h-tm__cap{padding:.7rem .85rem .8rem;gap:.25rem}
}/* ===== PRESETS «BEFORE/AFTER» — 6 draggable قبل/بعد cards in a scroll strip.
   Theme-colored edge fades (mask → page bg shows through) hint that more cards
   hide beyond both sides (owner 2026-07-27). ===== */
.a7h-band > .a7h-pb{width:min(100% - 2*var(--pad),62rem);margin-inline:auto;margin-top:8px;  /* + .25rem padding-top = 12 */
  display:flex;gap:clamp(.7rem,1.6vw,1rem);overflow-x:auto;scroll-snap-type:x proximity;
  padding:.25rem var(--pad) .6rem;scroll-padding-inline:var(--pad);scrollbar-width:none;
  -webkit-mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%)}.a7h-band > .a7h-pb::-webkit-scrollbar{display:none}/* smaller compare handle + hairline divider on the homepage strip only
   (shared a7-ba.js untouched) */
.a7h-pb__ba .a7ba__handle{transform:translate(-50%,-50%) scale(.68)}/* out-ranks A7BA's injected drag rule (scale 1.1) — grow stays gentle */
.a7h .a7h-pb__ba.is-drag .a7ba__handle{transform:translate(-50%,-50%) scale(.74)}.a7h-pb__ba .a7ba__line{width:1px}.a7h-pb__card{flex:0 0 clamp(15rem,44vw,19rem);scroll-snap-align:start;position:relative;
  background:var(--card);border:1px solid var(--card-bd);border-radius:18px;
  padding:0;box-shadow:var(--sh1);transition:box-shadow .25s var(--ease),border-color .2s var(--ease)}.a7h-pb__card:hover{border-color:var(--line2);box-shadow:var(--sh2)}/* A7BA mounts by ADDING .a7ba to this same element, and its runtime-injected
   sheet lands after this file — so the override must out-rank .a7ba (14px all
   corners) by specificity, not source order: top corners from the frame,
   bottom dead straight against the download button. */
.a7h .a7h-pb__ba,.a7h .a7h-pb__ba.a7ba{border-radius:17px 17px 0 0;overflow:hidden;
  background:var(--card);aspect-ratio:4/3;touch-action:pan-y}.a7h-pb__body{display:flex;align-items:center;gap:.5rem;padding:.6rem .65rem .2rem}.a7h-pb__dl{width:100%;display:flex;align-items:center;justify-content:center;gap:.45rem;
  border:0;border-top:1px solid var(--tint-bd);
  background:var(--tint);color:var(--pri);font:inherit;font-weight:700;font-size:.84rem;
  padding:.65rem .95rem;border-radius:0 0 17px 17px;cursor:pointer;
  transition:background .2s var(--ease),box-shadow .2s var(--ease),transform .15s var(--ease)}.a7h-pb__dl:hover{background:color-mix(in oklch,hsl(var(--primary)) 13%,transparent);box-shadow:var(--sh1)}.a7h-pb__dl:active{transform:scale(.97)}.a7h-pb__dl svg{width:15px;height:15px}.a7h-pb__dl[data-busy] svg{display:none}.a7h-pb__spin{display:none;width:13px;height:13px;border:2px solid var(--tint-bd);border-top-color:var(--pri);
  border-radius:50%;animation:a7hSpin .7s linear infinite}.a7h-pb__dl[data-busy] .a7h-pb__spin{display:inline-block}@keyframes a7hSpin{to{transform:rotate(360deg)}}.a7h-pb__text{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:.4rem;overflow:hidden}.a7h-pb__name{font-weight:700;font-size:.88rem;color:var(--ink);text-decoration:none;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.a7h-pb__name:hover{color:var(--pri)}.a7h-pb__dash{color:var(--faint)}.a7h-pb__dash,.a7h-pb__fmt{flex:0 0 auto}.a7h-pb__fmt{font-size:.72rem;font-weight:700;letter-spacing:.04em;color:var(--muted)}.a7h-pb__share{flex:0 0 auto;width:34px;height:34px;border-radius:50%;display:grid;place-items:center;cursor:pointer;
  border:1px solid var(--card-bd);background:var(--card);color:var(--muted);
  transition:color .2s var(--ease),border-color .2s var(--ease)}.a7h-pb__share:hover{color:var(--pri);border-color:var(--tint-bd)}.a7h-pb__share svg{width:15px;height:15px}.a7h-pb__dl[data-err]{border-color:color-mix(in oklch,crimson 55%,transparent);
  color:color-mix(in oklch,crimson 75%,hsl(var(--base-content)))}/* download success — same treatment as the prompt copy button */
.a7h-pb__ok{display:none;align-items:center;gap:.45rem}.a7h-pb__dl[data-done] .a7h-pb__cl{display:none}.a7h-pb__dl[data-done] > svg{display:none}.a7h-pb__dl[data-done] .a7h-pb__spin{display:none}.a7h-pb__dl[data-done] .a7h-pb__ok{display:inline-flex}.a7h-pb__dl[data-done]{background:color-mix(in oklch,#16a34a 12%,transparent);
  border-top-color:color-mix(in oklch,#16a34a 45%,transparent);
  color:color-mix(in oklch,#16a34a 80%,hsl(var(--base-content)));
  animation:a7hCopyPop .5s var(--spring)}.a7h-pb__dl[data-done] .a7h-pr__chk path{animation:a7hChkDraw .35s .08s var(--ease) forwards}.a7h-vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}/* ===== WATCH FACES «COVERFLOW» — rotated side cards + frosted pill control ===== */
.a7h-band > .a7h-wf{width:min(100% - 2*var(--pad),62rem);margin-inline:auto;margin-top:12px;
  display:flex;flex-direction:column;align-items:center;gap:1.6rem}/* stage height = 2·(.9rem lift · 1000/950) + 2·0.70603·cardW → the PROJECTED
   top of the active card (scale 1.1 · translateZ 50 · perspective 1000, aspect
   .82) sits exactly at the stage top; rule→card gap = the root's 12px margin.
   Retune constants if the lift/scale/translateZ/perspective ever change. */
.a7h-wf__stage{position:relative;width:100%;height:calc(30.5px + 1.412*clamp(7.5rem,20vw,10rem));overflow-x:clip;
  perspective:1000px;transform-style:preserve-3d}/* watch faces keep their NATIVE screen shape: tall rounded-rect (Apple-Watch
   ~0.82 ratio, big soft corners) — NOT circles (owner 2026-07-27) */
.a7h-wf__card{position:absolute;left:50%;top:calc(50% - .9rem);width:clamp(7.5rem,20vw,10rem);aspect-ratio:.82;
  transform:translate(-50%,-50%);transition:transform .55s var(--spring),opacity .4s var(--ease);
  will-change:transform,opacity;text-decoration:none;color:inherit;outline:none;cursor:pointer;
  backface-visibility:hidden}.a7h-wf__card img{width:100%;height:100%;object-fit:cover;display:block;border-radius:24% / 20%;
  border:1px solid var(--card-bd);box-shadow:var(--sh2);background:var(--card)}.a7h-wf__card:focus-visible img{box-shadow:0 0 0 3px var(--ring),var(--sh2)}.a7h-wf__t{position:absolute;top:calc(100% + .45rem);left:50%;transform:translateX(-50%) translateY(-4px);
  white-space:nowrap;max-width:13rem;overflow:hidden;text-overflow:ellipsis;
  font-size:.8rem;font-weight:600;color:color-mix(in oklch,hsl(var(--base-content)) 85%,transparent);
  opacity:0;transition:opacity .3s var(--ease),transform .3s var(--ease)}.a7h-wf__card.is-on .a7h-wf__t{opacity:1;transform:translateX(-50%)}/* pill pinned LTR so chevrons never flex-reverse into inward-pointing ▶|◀ under
   RTL (same trap a7-ba.js documents on its handle); dots follow the DECK's
   direction so dot 0 sits on the same side as card 0 */
.a7h-wf__ctl{display:flex;align-items:center;gap:.4rem;padding:.28rem .5rem;border-radius:999px;direction:ltr;
  background:color-mix(in oklch,hsl(var(--base-content)) 5%,transparent);border:1px solid var(--card-bd);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);box-shadow:var(--sh1)}.a7h-wf__dots{direction:rtl}.font-english .a7h-wf__dots{direction:ltr}.a7h-wf__nav{width:26px;height:26px;border:0;background:none;border-radius:50%;display:grid;place-items:center;
  cursor:pointer;color:var(--muted);transition:background .2s var(--ease),color .2s var(--ease)}.a7h-wf__nav:hover{background:color-mix(in oklch,hsl(var(--base-content)) 8%,transparent);color:var(--ink)}.a7h-wf__nav:active{transform:scale(.94)}.a7h-wf__nav{position:relative}.a7h-wf__nav::after{content:"";position:absolute;inset:-9px;border-radius:50%}@media(hover:none){.a7h-wf__dot{width:22px;height:36px}.a7h-wf__dot[aria-current="true"]{width:28px}}.a7h-wf__nav svg{width:14px;height:14px}.a7h-wf__dots{display:flex;align-items:center}.a7h-wf__dot{position:relative;width:15px;height:24px;padding:0;border:0;background:none;cursor:pointer;
  transition:width .3s var(--ease)}.a7h-wf__dot::after{content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:5px;height:5px;border-radius:999px;
  background:color-mix(in oklch,hsl(var(--base-content)) 28%,transparent);
  transition:width .3s var(--ease),background .3s var(--ease)}.a7h-wf__dot:hover::after{background:color-mix(in oklch,hsl(var(--base-content)) 45%,transparent)}.a7h-wf__dot[aria-current="true"]{width:24px}.a7h-wf__dot[aria-current="true"]::after{width:17px;background:var(--pri)}/* ===== GREETING CARDS «ARC5» — stacked deck fans into an arc on hover/focus ===== */
.a7h-band > .a7h-af{width:min(100% - 2*var(--pad),62rem);margin-inline:auto;margin-top:12px;
  /* height = rest-lift .257 + stack 16/9 + open-fan bottom-dip reserve;
     start-anchored — the stack's margin-top (below) is the real headroom */
  display:grid;place-items:start center;height:calc(clamp(8.5rem,21vw,10.5rem)*2.29)}/* cards keep their native STORY ratio (9:16), just miniaturized (owner 2026-07-27) */
/* margin-top = the JS pointer-REST front lift about origin bottom-center:
   (1.12−1)·16/9 + 0.08·rest(.55) = .257·cardW → resting first pixel lands at
   the stage top → rule→card gap = the root's 12px. Touch overrides below
   (ships pre-fanned). Retune with frontScale/rest/arc in home.js initArc5. */
.a7h-af__stack{position:relative;width:clamp(8.5rem,21vw,10.5rem);aspect-ratio:9/16;
  margin-top:calc(clamp(8.5rem,21vw,10.5rem)*.257)}.a7h-af__card{position:absolute;inset:0;display:block;outline:none;
  transform-origin:50% 100%;
  transition:transform .5s var(--spring),opacity .35s var(--ease),filter .45s var(--ease);
  will-change:transform,opacity}.a7h-af__card img{width:100%;height:100%;object-fit:cover;display:block;border-radius:16px;
  border:1px solid var(--card-bd);box-shadow:var(--sh2);background:var(--card)}.a7h-af__card:focus-visible img{box-shadow:0 0 0 3px var(--ring),var(--sh2)}/* touch ships pre-fanned (home.js open=touch): rest = the OPEN lift
   (1.176−1)·16/9 + 0.08·1 = .393·cardW; height adds the A=10 open bottom dip */
@media(hover:none){
  .a7h-band > .a7h-af{height:calc(clamp(8.5rem,21vw,10.5rem)*2.43)}.a7h-af__stack{margin-top:calc(clamp(8.5rem,21vw,10.5rem)*.393)}
}/* ===== MY APPS «CAROUSEL» — one-slot viewport, side icons spill rotated ===== *//* the strip lives in physical LTR coordinates (track shift math); labels stay bilingual *//* track is LTR → dot 0 leftmost matches */

/* ===== PROMPTS «SHOWCASE» — swipeable split cards: image start, copyable text end ===== */
.a7h-band > .a7h-pr{width:min(100% - 2*var(--pad),62rem);margin-inline:auto;margin-top:8px;  /* + .25rem padding-top = 12 */
  display:flex;gap:clamp(.8rem,1.8vw,1.2rem);overflow-x:auto;scroll-snap-type:x proximity;
  padding:.25rem var(--pad) .6rem;scroll-padding-inline:var(--pad);scrollbar-width:none;cursor:grab;
  -webkit-mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.18) clamp(14px,3.4vw,44px),rgba(0,0,0,.55) clamp(28px,6.6vw,84px),#000 clamp(44px,10.3vw,132px),#000 calc(100% - clamp(44px,10.3vw,132px)),rgba(0,0,0,.55) calc(100% - clamp(28px,6.6vw,84px)),rgba(0,0,0,.18) calc(100% - clamp(14px,3.4vw,44px)),transparent 100%)}.a7h-band > .a7h-pr::-webkit-scrollbar{display:none}.a7h-band > .a7h-pr.is-drag{cursor:grabbing;scroll-snap-type:none;user-select:none;-webkit-user-select:none}@property --a7beam{syntax:'<angle>';inherits:false;initial-value:0deg}.a7h-pr__card{flex:0 0 clamp(15rem,45vw,19rem);scroll-snap-align:start;position:relative;
  display:flex;flex-direction:column;gap:.55rem;
  background:var(--card);border:1px solid var(--card-bd);border-radius:18px;
  padding:0;box-shadow:var(--sh1);
  transition:box-shadow .25s var(--ease),border-color .2s var(--ease)}.a7h-pr__card:hover{border-color:var(--line2);box-shadow:var(--sh2)}/* light beam traveling around the card border (owner's BorderBeam, theme-adapted):
   a spinning conic arc masked to the 1.5px border ring only */
.a7h-pr__card::after,.a7h-pb__card::after,.a7h-ap__card::after{content:"";position:absolute;inset:-1px;border-radius:18px;padding:1.5px;
  pointer-events:none;z-index:2;
  background:conic-gradient(from var(--a7beam),
    transparent 0 72%,
    hsl(var(--primary)) 84%,
    color-mix(in oklch,hsl(var(--primary)) 35%,#fff) 90%,
    transparent 96%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
          mask-composite:exclude;
  opacity:0;transition:opacity .35s var(--ease);
  animation:a7hBeamSpin 3s linear infinite;animation-play-state:paused}/* the beam wakes only while the pointer (or keyboard focus) is on the card */
.a7h-pr__card:hover::after,.a7h-pr__card:focus-within::after,
.a7h-pb__card:hover::after,.a7h-pb__card:focus-within::after,
.a7h-ap__card:hover::after,.a7h-ap__card:focus-within::after{opacity:1;animation-play-state:running}@keyframes a7hBeamSpin{to{--a7beam:360deg}}.a7h-pr__media{display:block;border-radius:17px 17px 0 0;overflow:hidden;background:var(--card)}.a7h-pr__media img{width:100%;aspect-ratio:1;object-fit:cover;object-position:top;display:block;
  /* matched to the shortcuts tiles: 1.6s on the theme ease-out curve */
  transition:transform 1.6s var(--ease)}.a7h-pr__card:hover .a7h-pr__media img{transform:scale(1.03)}.a7h-pr__open{display:flex;flex-direction:column;gap:.55rem;text-decoration:none;color:inherit;outline:none}.a7h-pr__open:hover .a7h-pr__t,.a7h-pr__open:focus-visible .a7h-pr__t{color:var(--pri)}.a7h-pr__t{margin:0;padding-inline:.85rem;transition:color .2s var(--ease);font-weight:700;font-size:.95rem;line-height:1.35;text-align:center;
  color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.a7h-pr__text{margin:0 0 1.2rem;padding-inline:.85rem;color:var(--muted);font-size:.8rem;line-height:1.65;text-align:center;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.a7h-pr__copy{margin-top:auto;align-self:stretch;position:relative;display:inline-flex;align-items:center;justify-content:center;gap:.45rem;
  border:0;border-top:1px solid var(--tint-bd);background:var(--tint);color:var(--pri);font:inherit;font-weight:700;font-size:.84rem;
  padding:.65rem .95rem;border-radius:0 0 17px 17px;cursor:pointer;
  transition:background .2s var(--ease),box-shadow .2s var(--ease),transform .15s var(--ease)}.a7h-pr__copy:hover{background:color-mix(in oklch,hsl(var(--primary)) 13%,transparent);box-shadow:var(--sh1)}.a7h-pr__copy:active{transform:scale(.97)}.a7h-pr__copy svg{width:14px;height:14px}.a7h-pr__ok{display:none;align-items:center;gap:.45rem}.a7h-pr__copy[data-done] .a7h-pr__cl{display:none}.a7h-pr__copy[data-done] > svg{display:none}.a7h-pr__copy[data-done] .a7h-pr__ok{display:inline-flex}/* copy success: soft green wash + one spring pulse + a checkmark that DRAWS itself */
.a7h-pr__copy[data-done]{background:color-mix(in oklch,#16a34a 12%,transparent);
  border-top-color:color-mix(in oklch,#16a34a 45%,transparent);
  color:color-mix(in oklch,#16a34a 80%,hsl(var(--base-content)));
  animation:a7hCopyPop .5s var(--spring)}@keyframes a7hCopyPop{0%{transform:scale(1)}35%{transform:scale(1.03)}100%{transform:scale(1)}}.a7h-pr__chk{width:15px;height:15px}.a7h-pr__chk path{stroke-dasharray:24;stroke-dashoffset:24}.a7h-pr__copy[data-done] .a7h-pr__chk path{animation:a7hChkDraw .35s .08s var(--ease) forwards}@keyframes a7hChkDraw{to{stroke-dashoffset:0}}@media(max-width:640px){
  .a7h-pr__card{flex-basis:60%}
}/* ===== MY APPS «SHELF» — App-Store editorial row: floating icons + names ===== */
.a7h-band > .a7h-as{width:min(100% - 2*var(--pad),62rem);margin-inline:auto;margin-top:12px;
  display:flex;justify-content:center;align-items:flex-start;gap:clamp(1.2rem,5vw,3.5rem);
  padding-block:0 1.4rem;flex-wrap:wrap}/* top padding removed: margin-top 12 owns the full rule→content gap */
.a7h-as__app{display:flex;flex-direction:column;align-items:center;gap:.65rem;
  text-decoration:none;color:inherit;outline:none}.a7h-as__ic{display:block;border-radius:24%;
  animation:a7hFloat 4.6s ease-in-out infinite;animation-delay:calc(var(--i,0)*-1.15s);
  transition:transform .35s var(--spring)}.a7h-as__ic img{width:clamp(4.5rem,12vw,6.5rem);height:clamp(4.5rem,12vw,6.5rem);
  object-fit:cover;display:block;border-radius:24%;background:var(--card);
  border:1px solid var(--card-bd);
  box-shadow:0 0 0 1px color-mix(in oklch,hsl(var(--base-content)) 4%,transparent) inset,var(--sh2);
  transition:box-shadow .3s var(--ease),transform .35s var(--spring)}.a7h-as__app:hover .a7h-as__ic img,.a7h-as__app:focus-visible .a7h-as__ic img{
  transform:translateY(-6px) scale(1.06);
  box-shadow:0 0 0 1px var(--tint-bd) inset,0 18px 40px color-mix(in oklch,hsl(var(--base-content)) 18%,transparent)}.a7h-as__app:focus-visible .a7h-as__ic img{box-shadow:0 0 0 3px var(--ring),var(--sh2)}.a7h-as__n{font-weight:700;font-size:clamp(.82rem,.78rem + .2vw,.95rem);
  color:color-mix(in oklch,hsl(var(--base-content)) 88%,transparent);white-space:nowrap}@keyframes a7hFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-7px)}}/* ===== WALLPAPERS «LINEAR SPREAD» — stacked deck fans out on hover/focus ===== */
.a7h-band > .a7h-sp{width:min(100% - 2*var(--pad),62rem);margin-inline:auto;margin-top:12px;
  /* height = cardW · 16/9 · 1.176 (open frontScale 1.12·1.05) + spring slack —
     top-anchored deck's tallest state fits exactly (band is c-v:auto → clips) */
  position:relative;height:calc(clamp(9.5rem,24vw,12rem)*2.11)}/* wallpapers keep their native STORY ratio (9:16); front card bigger, back
   cards slightly smaller + blurred — mirrors the greeting-cards deck (owner) */
.a7h-sp__card{position:absolute;left:50%;top:0;width:clamp(9.5rem,24vw,12rem);aspect-ratio:9/16;
  transform:translate(-50%,0);transform-origin:50% 0;
  transition:transform .5s var(--spring),filter .45s var(--ease);
  will-change:transform;display:block;outline:none}.a7h-sp__card img{width:100%;height:100%;object-fit:cover;display:block;border-radius:16px;
  border:1px solid var(--card-bd);box-shadow:var(--sh2);background:var(--card)}.a7h-sp__card:focus-visible img{box-shadow:0 0 0 3px var(--ring),var(--sh2)}/* Latin-only negative tracking (Arabic is a connected script) */
.font-english .a7h-greet,.font-english .a7h-closing__h{letter-spacing:-.02em}/* long-EN tuning */
.font-english .a7h-band__title{font-size:clamp(.86rem,.82rem + .26vw,1rem)}.font-english .a7h-about__bio{line-height:1.7}@media(prefers-reduced-motion:reduce){
  .a7h *{animation:none!important;transition:none!important}.a7h .reveal{opacity:1!important;transform:none!important}.a7h-tm__deck{perspective:none}/* JS still inlines translateY(−7·o) lifts; without perspective the stepped
     stack would poke ~22px above the tightened deck (10px past the rule). Flatten
     to a single centered card; opacity:0 because flattening also flattens the
     preserve-3d paint order (DOM-later translucent cards would cover the active). */
  .a7h-tm__card{transform:translate(-50%,-50%)!important}.a7h-tm__card:not(.is-active){opacity:0!important}.a7h-pr__card::after,.a7h-pb__card::after,.a7h-ap__card::after{content:none}
}

/* ===== ADS — one banner, no heading row. Shape mirrors the canonical card ad
   (features/cards/public/injector.js) so a placement looks the same site-wide.
   Prefix is a7h-ad because .a7cad lives in the cards bundle, not here. ===== */
.a7h-ad{width:min(100% - 2*var(--pad),62rem);margin:clamp(1.4rem,4vw,2.4rem) auto 0;display:flex;justify-content:center}
.a7h-ad--tall{--ad-w:min(100%,20rem);--ad-ar:9 / 16}
/* ⛔ 16/3 EVERYWHERE, phone included — owner 2026-08-05 «خل العرض ١٦٠٠ بس الارتفاع ٣٠٠».
   This MUST equal the cropper's output ratio in home.fragment.html (1600x300). If the two
   ever drift, the site silently re-crops what he framed by hand and the whole promise of
   the cropper («what you see in the frame is what gets saved») becomes a lie. The old pair
   was 32/9 desktop + 16/9 phone, so a phone visitor saw a DIFFERENT crop than a desktop one. */
.a7h-ad--wide{--ad-w:100%;--ad-ar:16 / 3}
.a7h-ad__native{position:relative;display:block;width:var(--ad-w);aspect-ratio:var(--ad-ar);
  border-radius:20px;overflow:hidden;border:1px solid var(--card-bd);box-shadow:var(--sh1);
  background:var(--card);text-decoration:none;color:#fff;isolation:isolate;
  transition:transform .35s var(--ease),box-shadow .35s var(--ease)}
.a7h-ad__native img{width:100%;height:100%;object-fit:cover;display:block}
a.a7h-ad__native:hover{transform:translateY(-2px);box-shadow:var(--sh2)}
a.a7h-ad__native:focus-visible{outline:2px solid var(--pri);outline-offset:3px}
/* disclosure — a paid placement must say so, in both languages */
.a7h-ad__badge{position:absolute;inset-block-start:10px;inset-inline-start:10px;z-index:2;
  font-size:.66rem;font-weight:700;letter-spacing:.02em;padding:.2rem .5rem;border-radius:999px;
  color:#fff;background:rgb(0 0 0/.46);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.a7h-ad__cap{position:absolute;inset-inline:0;inset-block-end:0;z-index:2;padding:1.6rem .9rem .8rem;
  /* ⛔ centre, not flex-start — owner 2026-08-05 «خل الزر بالنص». On a 16:3 strip a
     corner-pinned CTA reads as a stray caption; centred it reads as the button it is. */
  display:flex;justify-content:center;pointer-events:none;
  background:linear-gradient(to top,rgb(0 0 0/.62) 0,rgb(0 0 0/.42) 46%,transparent 100%)}
.a7h-ad__t{display:inline-flex;align-items:center;gap:.4rem;font-size:.86rem;font-weight:700;color:#fff;
  text-shadow:0 1px 6px rgb(0 0 0/.5)}
.a7h-ad__ti{width:16px;height:16px;flex:none}
/* responsive AdSense: fill the column (capped so it never looks stretched on a
   wide desktop), let Google choose the height. NO aspect-ratio here — an
   auto-format unit resizes itself and a fixed ratio just crops or letterboxes. */
.a7h-ad--gg{--ad-w:min(100%,46rem)}
/* ⛔ --ad-w is consumed by .a7h-ad__native, which google units never get, so the
   46rem cap below was dead CSS and the unit painted the full 992px column. */
.a7h-ad--gg .adsbygoogle{display:block;width:100%;max-width:var(--ad-w);margin-inline:auto;height:auto;min-height:100px}
@media (max-width:640px){.a7h-ad--gg{--ad-w:100%}.a7h-ad--gg .adsbygoogle{min-height:100px}}
/* ⛔ The 100px min-height above is reserved BEFORE Google answers, so when it has
   nothing to sell the slot stays as a ~100px empty strip on the page (measured
   2026-08-03: a visible gap between «تطبيقاتي» and the closing line). AdSense
   stamps data-ad-status="unfilled" on the <ins> in exactly that case, which is
   the only reliable signal — an unfilled unit is otherwise indistinguishable
   from one still loading, and collapsing early would cost real impressions.
   :has() removes the wrapper's margin too; the second rule is the fallback for
   engines without :has(), which at least drops the 100px. */
.a7h-ad:has(.adsbygoogle[data-ad-status="unfilled"]){display:none}
.a7h-ad--gg .adsbygoogle[data-ad-status="unfilled"]{display:none}
@media (prefers-reduced-motion:reduce){.a7h-ad__native,a.a7h-ad__native:hover{transition:none;transform:none}}
/* ⛔ OWNER 2026-08-05, his option «ب» («ظاهر فجاه بشكل مب حلو … خط فوقه و تحته
   ضايبين من الاطراف»). The google unit used to float bare between two bands and
   read as something that had crashed into the page. Two hairlines that dissolve
   at both ends — the site's OWN `.a7h-band__rule` language, not a new invention —
   plus a small «إعلان» caption sitting ON the upper line, which is what turns the
   block from an intruder into a part of the page.
   ⛔ They are ::before/::after ON THE BLOCK ITSELF, so wherever the dashboard
   reorders the ad to, the frame travels with it — no markup and no per-position
   CSS. That was his explicit requirement («في حال نقلته اي مكان … الخطوط تكون وياه»).
   The wrapper already collapses itself on data-ad-status="unfilled" (rule above),
   so an unsold slot can never leave two orphan lines and a floating caption. */
.a7h-ad--gg{flex-direction:column;gap:1.15rem;position:relative;
  margin-block:clamp(1.6rem,4.4vw,2.6rem)}
.a7h-ad--gg::before,.a7h-ad--gg::after{content:"";display:block;height:1px;width:100%;
  background:linear-gradient(90deg,transparent,var(--line),transparent)}
/* ⛔ `left` + translateX, NEVER inset-inline-start: the caption must sit dead
   centre in BOTH directions, and a logical offset lands it on the wrong half the
   moment the visitor switches to English. */
/* ⛔ SAFETY NET, and the only !important in this block. AdSense writes its layout
   margins as an INLINE style on the <ins>, which beats any class we author — so if
   a future AdSense change starts injecting the negative full-width margins again
   (or the attribute above gets flipped back), this keeps the unit centred inside
   its rules instead of drifting off-axis. `auto` is what centres it; it is
   identical to what Google itself computes when the page is not RTL. */
.a7h-ad--gg .adsbygoogle{margin-inline:auto !important}
.a7h-ad__lbl{position:absolute;top:-.6rem;left:50%;transform:translateX(-50%);
  background:hsl(var(--base-100));padding:0 .7rem;font-size:.66rem;line-height:1.2;
  letter-spacing:.08em;color:var(--muted);text-transform:uppercase;white-space:nowrap}

/* ═══ «الموجة» — the page opener (owner's design, 2026-08-04) ═══════════════
   A smooth sine in ONE neutral stroke; four PRIMARY dots on its extrema.
   ⛔ INVARIANT 4 (his rule, recorded in about.css): the line stays NEUTRAL and
   only the dots are primary — «خط … و نقاط زرقا». Tint the line and it dies. */
.a7h-wv{padding:clamp(22px,5.5vw,34px) var(--pad) 0}
.a7h-wv__in{width:min(100%,42rem);margin-inline:auto}
.a7h-wv__t{margin:0;font-size:clamp(1.6rem,5.4vw,2.5rem);font-weight:800;line-height:1.22;
  color:var(--ink);letter-spacing:-.01em;text-wrap:balance}
.font-english .a7h-wv__t{letter-spacing:-.02em}
/* the stage is the dots' positioning context; the SVG is inset 30px from its top */
.a7h-wv__stage{position:relative;width:min(380px,100%);height:192px;margin-top:18px;
  overflow:visible;--wv-T:11s;
  /* ⛔ ONE source of truth for the curve's height. The svg's viewBox is 0 0 100 132
     with preserveAspectRatio="none", so changing this squashes the curve — and the
     pins, which are sized by the SAME variable, squash with it. Never set a height
     on `.a7h-wv__line` or `.a7h-wv__pins` directly; change this. */
  --wv-lineH:132px}
/* ⛔ 300% WIDE, CENTRED ON THE PIN BOX. Both insets at -100% make the svg three
   halves wider than the stage, and the viewBox grew by the same factor, so the middle third
   — the part carrying the dots — lands on exactly the pixels it did before.
   The tails run under the portrait and off the other edge, where the existing
   end-fade dissolves them. */
/* ⛔ AN EXPLICIT WIDTH — `inset-inline:-100%` + `width:auto` DOES NOT STRETCH an
   <svg>. It is a REPLACED element, so `auto` resolves to its intrinsic size and
   the box came out 300px wide instead of 1140. Anchor one edge and state the
   width; 300% of the pin box, pulled back 100%, centres it on the same middle
   third — measured, not assumed. */
/* ⛔ overflow visible: the portrait-side tail runs to y=138, below the 132-unit
   viewBox, so it can end UNDER him instead of stopping at the box edge. */
.a7h-wv__line{position:absolute;inset-inline-start:-25%;top:30px;width:150%;height:var(--wv-lineH);overflow:visible;
  /* ⛔ --line2 (22%) disappeared on the light ground in the live shot: four dots
     with no visible wave between them. 38% is the readable floor here. The line
     stays NEUTRAL — only the value changes, INVARIANT 4 is intact. */
  color:color-mix(in oklch,hsl(var(--base-content)) 38%,transparent)}
/* ⛔ THE CENTRING SHIFT IS DIRECTION-DEPENDENT. The stop is anchored by
   `inset-inline-start`, which is the RIGHT edge in RTL and the LEFT edge in LTR, so
   centring it needs +50% in Arabic and −50% in English. It was hardcoded to +50%,
   which pushed every English dot off the curve by its own width — and the width is
   the LABEL's, not the dot's, so «Wallpapers» drifted furthest. Arabic looked fine,
   which is why it survived: «شوف كيف بالانجليزي غلط». */
/* ⛔ THE PIN LAYER IS THE CURVE'S BOX — same top, same height, same variable.
   Transparent and click-through; only the dots themselves take pointer events. */
/* ⛔ WHERE AN ANCHORED BAND COMES TO REST. The sticky nav's BOX is 48px, but its
   `::before` frosted panel extends 16px below it — land at 48 and the band's title
   sits inside the blur. 72px clears the glass with an 8px breath, and one value
   covers desktop and phone because the nav has no responsive height override.
   Base rule, above every @media, per the section-polish playbook. */
.a7h-band[id]{scroll-margin-top:72px}
.a7h-wv__pins{position:absolute;inset-inline:0;top:30px;height:var(--wv-lineH);
  pointer-events:none}
/* ⛔ THE ANCHOR IS THE DOT, NEVER THE DOT-PLUS-LABEL. This box is a fixed 44px
   square, so `translate(±50%,-50%)` puts the DOT's centre exactly on the curve.
   When the label lived inside it the box's centre sat between dot and label —
   every dot was 11.6px off vertically, and horizontally off by half the LABEL's
   width, which is why «Wallpapers» drifted furthest. The label is now absolutely
   positioned, so its length can never move the dot again.
   The shift is still direction-dependent: `inset-inline-start` is the RIGHT edge
   in RTL and the LEFT edge in LTR — «شوف كيف بالانجليزي غلط». */
.a7h-wv__stop{position:absolute;inset-inline-start:var(--x);top:var(--y);
  transform:translate(50%,-50%);width:44px;height:44px;display:grid;place-items:center;
  text-decoration:none;pointer-events:auto}
.font-english .a7h-wv__stop{transform:translate(-50%,-50%)}
/* crest → label ABOVE the dot; trough → label BELOW. Outside the box, both times. */
.a7h-wv__stop--hi .a7h-wv__lbl{bottom:calc(100% - 2px)}
.a7h-wv__stop--lo .a7h-wv__lbl{top:calc(100% - 2px)}
.a7h-wv__dot{position:relative;width:40px;height:40px;border-radius:50%;display:grid;
  place-items:center;background:hsl(var(--primary));
  /* ⛔ THE GLYPH IS ALWAYS WHITE, NEVER base-100. The svg strokes inherit this
     `color`, and base-100 is the PAGE background — near-black in dark mode — so
     the icons came out black-on-blue at night: «الايقونات لونها اسود خلها ابيض».
     The primary blue is the same in both themes, so white is the one value that
     is correct in both. The halo below stays base-100 on purpose — that one IS
     meant to match the page so it masks the wave passing behind the dot. */
  color:#fff;
  /* ⛔ INVARIANT 3 — the base-100 halo is what masks the wave passing behind the
     dot. It only works because the opener has NO background of its own. */
  box-shadow:0 0 0 4px hsl(var(--base-100))}
.a7h-wv__dot svg{width:20px;height:20px}
/* ⛔ RTL FIX — verified on the live page, not assumed. The dots are placed with
   `inset-inline-start`, so they MIRROR in RTL; the SVG path does not. Because
   y(100−x) = 132 − y(x) for this sine, mirroring turns every crest into a trough:
   in Arabic — the default language here — all four dots floated OFF the curve.
   Mirroring the SVG realigns them, and it is also correct for RTL reading order.
   Scoped positively on `.font-english` so the RTL default needs no class to be right. */
/* ⛔ MIRROR THE <svg> ONLY. `.a7h-wv__run` is a <path> INSIDE `.a7h-wv__line`,
   so listing both applied scaleX(-1) TWICE to the spark — it cancelled out, the
   spark ran an unmirrored path while the wave was mirrored, and it travelled the
   wrong way. The owner caught it: «الخط الازرق يمشي عكس الاتجاه». */
.a7h-wv__line{transform:scaleX(-1)}
.font-english .a7h-wv__line{transform:none}
/* the travelling pulse — one short lit dash running the curve, looping forever
   («بعدها يعيد»). dasharray/offset are fractions because pathLength="1". */
/* the comet's colour lives on the GRADIENT STOPS, not on the path — see the
   note in render.py. Opacity is carried by each stop, so one colour is enough. */
.a7h-wv__grad stop{stop-color:hsl(var(--primary))}
/* ⛔ NO dash and NO dashoffset animation. The travelling gradient is the whole
   effect; adding a dash produced two out-of-sync motions and the light stalled. */
.a7h-wv__run{pointer-events:none}
/* ⛔ ONE CURVE VISIBLE AT A TIME — the svg ships BOTH, CSS picks. `--wide` carries
   the tail that arches over «بطاقات» and dives behind the portrait; on a phone the
   portrait is centred BELOW the wave, so that tail had nothing to hide behind and
   hung in empty air beside his head («شو صار مع متصفح المبوايل»). `--sm` is the
   same sine with a plain lead-in that dissolves into the end-fade instead.
   ⛔ Toggle by display, never by the CSS `d` property — `d` is uneven across
   browsers and a silent fallback here is an opener with no line at all. */
.a7h-wv__d--sm{display:none}
@media(max-width:640px){.a7h-wv__d--wide{display:none}.a7h-wv__d--sm{display:inline}}
.a7h-wv__lbl{position:absolute;left:50%;transform:translateX(-50%);
  font-size:clamp(11.5px,3.1vw,13px);font-weight:700;color:var(--ink);white-space:nowrap}
.a7h-wv__stop:focus-visible{outline:none}
.a7h-wv__stop:focus-visible .a7h-wv__dot{box-shadow:0 0 0 4px hsl(var(--base-100)),0 0 0 6px hsl(var(--primary))}
@media (hover:hover){.a7h-wv__stop:hover .a7h-wv__dot{transform:scale(1.06)}
  .a7h-wv__dot{transition:transform .2s var(--ease)}}
/* the pulse — a ring expanding out of the dot, staggered so it travels the wave.
   ⛔ base opacity 0 and fill-mode none: invisible before the delay AND after the
   third cycle. ⛔ FINITE (3), never infinite — permanent motion at the top of the
   page beside the title is exactly what about.css's own comment forbids. */
.a7h-wv__dot::after{content:"";position:absolute;inset:0;border-radius:50%;
  border:2px solid hsl(var(--primary));opacity:0;pointer-events:none;
  animation:a7hWvPulse var(--wv-T) cubic-bezier(.22,.61,.36,1) var(--pd) infinite}
/* fires in the first 12% of the shared cycle — i.e. exactly as the spark passes —
   then rests for the remaining 88%. */
@keyframes a7hWvPulse{0%{transform:scale(1);opacity:.6}12%{transform:scale(1.72);opacity:0}
  100%{transform:scale(1.72);opacity:0}}
/* ⛔ one variable, both boxes. Setting `.a7h-wv__line{height:120px}` here while
   the pins kept px offsets is exactly what slid every dot off the curve on
   phones — and Arabic is the default language, so most visitors saw it. */
@media(max-width:640px){.a7h-wv__stage{height:176px;--wv-lineH:120px}}
/* ⛔ home.css's `.a7h *{animation:none!important}` CANNOT match a pseudo-element,
   so the pulse survives it. This is its own cancel — and a REAL alternative, not
   a removal: every dot keeps a static resting ring. */
@media (prefers-reduced-motion:reduce){
  .a7h .a7h-wv__dot::after{animation:none!important;opacity:.32;transform:scale(1.24)}
  .a7h .a7h-wv__run{opacity:.22}
  .a7h .a7h-wv__stop:hover .a7h-wv__dot{transform:none}}

/* ⛔ THE GAP UNDER THE PORTRAIT WAS 146px, NOT 88 — «تقلص المساحه بين بطاقات التهنيه و صورتي».
   Two separate causes, and only measuring both explains the number:
   1. `.a7h-journey{margin-top:var(--band)}` = 88px at >=1440.
   2. the desktop portrait is raised with `translateY(-58px)`, and a TRANSFORM DOES NOT
      SHRINK THE BOX — its bottom 58px stays reserved as dead air under the photo.
   So the journey's own margin absorbs the transform here. Desktop only: on phones the
   portrait sits ABOVE the text, is not translated, and the 48px gap is already right.
   ⛔ Do NOT shrink `--band` to fix this — that token is the rhythm between EVERY band. */
@media(min-width:641px){.a7h-journey{margin-top:1rem}}
/* ⛔ DO NOT PUT `overflow-x:clip` ON <html> HERE. It was tried on 2026-08-05 to stop an
   Arabic-phone overflow (document 426px on a 390px screen, everything shifted 36px, the
   «بطاقات» label clipped) and IT BROKE THE STICKY NAV: `clip` is not in the set of
   overflow values that propagate from the root to the viewport, so <html> itself becomes
   the clip container and `position:sticky` stops sticking. Measured: nav top after a
   1200px scroll was -1200 with the rule and 0 without it; /cards (no rule) was 0.
   ⛔ AND THE BUG IS INTERMITTENT — it is a Google AUTO-PLACED ad landing in the shared
   footer outside the RTL start edge, and auto-placement is non-deterministic. A later
   run of the same page measured 390 with no rule at all. Do not "fix" it from a single
   reading. If it ever needs fixing, `footer.a7ft{overflow-x:clip;overflow-y:visible}`
   keeps the nav sticky (verified) but costs ~36px of the ad, so it is the owner's call. */

/* ⛔ PHONE INTRO: SMALL PORTRAIT BESIDE THE NAME, SENTENCE FULL-WIDTH BELOW.
   «اريد صورتي صغيره ع الجنب بدل ما تكون كبيره». It was a 250px portrait stacked on
   top of everything, which pushed the whole block past 640px tall and made the photo
   the loudest thing on a phone.
   ⛔ `.a7h-about__copy` is a bare wrapper with NO styles of its own (checked), so
   `display:contents` is safe here — it lets name / role / bio / link become grid items
   of `.a7h-about` directly, which is the only way the sentence can span BOTH columns
   while the portrait sits beside the name alone.
   ⛔ Desktop is untouched: this whole block is inside the phone media query, and the
   desktop `translateY(-58px)` lift lives in its own min-width rule. */
@media(max-width:640px){
  .a7h-about{grid-template-columns:auto minmax(0,1fr);
    align-items:center;justify-items:stretch;text-align:start;
    column-gap:.85rem;row-gap:0}
  .a7h-about .a7h-about__copy{display:contents}
  .a7h-about .a7h-about__portrait{grid-column:1;grid-row:1 / span 2;
    width:clamp(84px,25vw,104px);align-self:center}
  .a7h-about .a7h-about__name{grid-column:2;grid-row:1;align-self:end}
  .a7h-about .a7h-about__role{grid-column:2;grid-row:2;align-self:start}
  .a7h-about .a7h-about__role::before{margin-inline:0}
  .a7h-about .a7h-about__bio{grid-column:1 / -1;grid-row:3;margin-top:.85rem;max-width:none}
  .a7h-about .a7h-about__link{grid-column:1 / -1;grid-row:4;justify-self:start}
}
/* ⛔ SMALLER DOTS ON PHONES ONLY — «صغر الايقونات … في متصفح المبوايل فقط».
   40px next to a 98px portrait was the loudest thing on the screen.
   ⛔ SHRINK THE CIRCLE, NEVER `.a7h-wv__stop`. That box stays a 44px square for two
   independent reasons: it is the 44px minimum touch target, AND `translate(±50%,-50%)`
   on it is what puts the dot's centre exactly on the curve — the geometry the owner
   caught twice («الخط مب ضابط ع الايقونات»). Changing its size moves every dot.
   Desktop is untouched: 40px there. */
@media(max-width:640px){
  .a7h-wv__dot{width:32px;height:32px;box-shadow:0 0 0 3px hsl(var(--base-100))}
  .a7h-wv__dot svg{width:16px;height:16px}
}
/* ⛔ THE RAISED TROUGH DOTS — pairs with _WAVE_D_SM's trough at 96 (was 110).
   96/132 = 72.7273%. The inline style sets --y, and an inline custom property beats any
   stylesheet, so this overrides `top` DIRECTLY rather than re-declaring --y.
   ⛔ Phones only: the desktop curve still troughs at 110 and its dots must not move. */
@media(max-width:640px){.a7h-wv__stop--lo{top:72.7273%}}
/* ⛔ NO FOCUS RING ON THE LANDING SECTION. Tapping a wave dot navigates to the band's
   fragment, which makes the BAND the activeElement — and the browser paints its blue
   focus ring around the whole section: «يحدد القسم باللون الازرق … ما اريد يحدد».
   The band is a scroll destination, never an interactive control, so it has nothing to
   announce; the DOT keeps its own :focus-visible ring, so keyboard users lose nothing. */
.a7h-band:focus{outline:none}
.a7h-wv__stop{-webkit-tap-highlight-color:transparent}
/* ⛔ «تطبيقاتي» ON ONE ROW ON PHONES — «خلهم بصف واحد». It wrapped 3+1 and the cause
   is NOT the icons: at 390px four 72px icons plus their gaps fit in 358px with room to
   spare. The item is as wide as its NAME, and «Shadow Studio» / «Velura Studio» run
   ~100px on one line, so 4 items needed ~458px and flex-wrap broke the row.
   Fix all three at once: no wrapping, equal shares, and a name that may wrap inside
   its own share instead of widening it. Icons shrink only as much as that needs.
   ⛔ Phones only — the desktop shelf is roomy and unchanged. */
@media(max-width:640px){
  .a7h-band > .a7h-as{flex-wrap:nowrap;justify-content:space-between;
    gap:.45rem;align-items:flex-start}
  .a7h-as__app{flex:1 1 0;min-width:0;gap:.45rem}
  .a7h-as__ic img{width:min(4rem,17vw);height:min(4rem,17vw)}
  .a7h-as__n{font-size:.68rem;line-height:1.25;text-align:center;
    max-width:100%;overflow-wrap:anywhere}
}
/* ⛔ THE iPAD DEAD LINK. Between 641 and 959 the «خلفيات» dot's CENTRE sits inside the
   portrait's box — `elementFromPoint` returns the IMG, so the dot is unclickable and its
   label is unreadable over his face. Cause: the wave stage is a FIXED 380px centred box,
   while `.a7h-about` is fluid — as the viewport narrows the portrait slides left, under
   the wave's left dots. It is NOT a vertical problem: the overlap measures 68–71px at
   EVERY width, 1440 included, where there is no collision at all.
   ⛔ The fix is NOT to raise the dots above the portrait — that puts the pulsing circle
   on his face, which was deliberately avoided before.
   Instead drop the portrait back down by exactly what was lifting it: the -58px lift plus
   the ~10px negative margin = 68px, which is the measured overlap. Desktop (>=960) keeps
   the lift he asked for twice. Measured, not guessed. */
@media(min-width:641px) and (max-width:959px){
  .a7h-about{margin-top:0}
  .a7h-about .a7h-about__portrait{transform:none}
}