/* ═══════════════════════════════════════════════════════════
   Birkari – Shared Components
   Header, buttons, toggles, book
   ═══════════════════════════════════════════════════════════ */

/* ── Header bar (unified for all pages) ── */
.header,
.page-header {
  position: sticky; top: 0;
  z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 20px;
  background: var(--bg);
  transition: background .35s cubic-bezier(.22,1,.36,1),
              box-shadow .35s cubic-bezier(.22,1,.36,1),
              margin .35s cubic-bezier(.22,1,.36,1),
              border-radius .35s cubic-bezier(.22,1,.36,1),
              padding .35s cubic-bezier(.22,1,.36,1);
}
.header { position: fixed; left: 0; right: 0; background: transparent; }

/* Landing header only: layout locked to LTR (brand left, controls right)
   in BOTH languages. Secondary pages' .page-header deliberately follows
   the document direction, so the Back button sits — and points — the way
   the reading direction expects. */
.header { direction: ltr; }

/* Teal glow line */
.header::after,
.page-header::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 16px; right: 16px;
  height: 2px;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
  background: radial-gradient(ellipse 40% 100% at 50% 50%, var(--accent), transparent);
  opacity: 0;
  transition: opacity .4s cubic-bezier(.22,1,.36,1), left .35s, right .35s;
  pointer-events: none;
}

/* Scrolled state — visual card via ::before, header stays full-width */
.header.scrolled,
.page-header.scrolled {
  background: transparent;
}
.header::before,
.page-header::before {
  content: '';
  position: absolute;
  inset: 4px 10px 0;
  background: var(--surface);
  box-shadow: var(--shadow-raised-sm);
  border-radius: var(--radius-md);
  opacity: 0;
  transition: opacity .35s cubic-bezier(.22,1,.36,1);
  z-index: -1;
  pointer-events: none;
}
.header.scrolled::before,
.page-header.scrolled::before {
  opacity: 1;
}
.header.scrolled::after,
.page-header.scrolled::after {
  opacity: .6;
  left: 18px;
  right: 18px;
}

/* ── Birkari.com wordmark ──
   The leading "B" is the Birkari mark itself, so the logo and the name are one
   object instead of a badge parked next to a word. */
.brand-wordmark {
  /* Optical tuning hook: lifts the suffix period off the baseline. 0 keeps the
     whole lockup — mark, "irkari", ".com" — on one straight bottom line;
     .18em would centre the dot on the x-height as a middot. */
  --wm-dot-lift: 0em;
  display: inline-flex;
  /* baseline, not centre: the chip is a separate flex item, so centring floated
     "com" .16em above the letters it sits next to (and moved whenever the
     mark's height changed). Baseline puts every part on one line. */
  align-items: baseline;
  direction: ltr;
  unicode-bidi: isolate;
  font-family: 'IBM Plex Mono', 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
  font-weight: 700;
  letter-spacing: .02em;
  line-height: 1;
  color: var(--text-primary);
  white-space: nowrap; /* the mark and "irkari" are one word; without this a
                          line can break between the SVG and the letters */
}
/* The mark standing in for the "B" (same geometry as brand/birkari-mark.svg).
   It is deliberately larger than a cap — 1.1em against the mono's .698em cap
   height — so it reads as the logo carrying the name rather than as a letter,
   and all of that extra height goes upward: no bottom margin, so the replaced
   element's baseline (its bottom margin edge) is the text baseline and the
   mark's foot lands in one straight line with "irkari". The viewBox is the ink
   box including the round caps, so the drawn bottom is the box bottom.
   Stroke is opened from the standalone mark's 46 units to 52 — 46 renders
   washy below ~20px, and 52 sits between Plex Mono Bold's .145em stems and its
   .10em bars once scaled here. `width: auto` keeps the glyph's proportion. */
.brand-wordmark__mark {
  display: inline-block;
  height: 1.1em;
  width: auto;
  vertical-align: baseline;
  margin-inline-end: .04em; /* the "B"'s right side bearing in the mono face */
}
.brand-wordmark__dot {
  display: inline-block;
  transform: translateY(calc(var(--wm-dot-lift) * -1));
}
.brand-wordmark__suffix {
  display: inline-block;
  margin-inline-start: .08em;
  padding: .1em .22em .13em;
  border-radius: .38em;
  background: var(--surface);
  color: var(--accent);
  font-weight: 600;
  line-height: 1;
  box-shadow:
    inset 1px 1px 2px rgba(0,0,0,.05),
    inset -1px -1px 2px rgba(255,255,255,.5);
}
[data-theme="dark"] .brand-wordmark__suffix {
  box-shadow:
    inset 1px 1px 2px rgba(0,0,0,.3),
    inset -1px -1px 2px rgba(255,255,255,.04);
}

/* Obelus flourish — the suffix period occasionally evolves into a divide
   sign (Birkari ÷ com) and settles back. This default state renders as a
   plain period, so pages without app.js (or with reduced motion) just show
   the classic mark. Opt-in via markup; motion driven from app.js. */
.brand-obelus {
  position: relative;
  display: inline-block;
  width: .6em;
  height: .62em;
  /* The resting dot is flush with the box floor, so this offset is what puts it
     on the baseline. -.011em, not 0: that is how far Plex Mono's own period
     overshoots below the baseline, so the animated dot lands exactly where the
     literal ".com" period does on every other page. */
  vertical-align: -.011em;
}
.brand-obelus__dot,
.brand-obelus__echo {
  position: absolute;
  left: 50%;
  top: 0;
  width: .15em;
  height: .15em;
  border-radius: 50%;
  background: currentColor;
  transform: translate(-50%, .47em);
}
/* The resting period tracks --wm-dot-lift so it lands wherever the literal
   ".com" period lands on every other page. The echo keeps the .47em floor: it
   is the divide sign's lower dot, which stays centred on the box with the bar
   however the period is tuned. */
.brand-obelus__dot {
  transform: translate(-50%, calc(.47em - var(--wm-dot-lift)));
}
.brand-obelus__echo {
  opacity: 0;
  transform: translate(-50%, .47em) scale(0);
}
.brand-obelus__line {
  position: absolute;
  top: 50%;
  left: .03em;
  right: .03em;
  height: .09em;
  transform: translateY(-50%) scaleX(0);
  background: var(--text-primary);
  border-radius: 99px;
}
.brand-obelus__sym {
  position: absolute;
  left: 0;
  right: 0;
  bottom: .02em;
  text-align: center;
  font-size: .68em;
  color: currentColor;
  opacity: 0;
}
.brand-obelus__com {
  display: inline-block;
  white-space: nowrap;
}
.brand-obelus__com i { font-style: normal; }



/* Back button (inner pages) */
.page-header__back {
  width: 40px; height: 40px;
  border-radius: 14px; border: none;
  background: var(--surface);
  box-shadow: var(--shadow-raised-sm);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--text-secondary);
  transition: all .2s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.page-header__back:active {
  box-shadow: var(--shadow-inset); transform: scale(.94);
}
[dir="ltr"] .page-header__back svg { transform: scaleX(-1); }

/* Compact, lighter glyphs inside the 40px header buttons — the icon sits
   small in the tile (like the demo app-bar) instead of filling it */
.page-header__back svg {
  width: 14px; height: 14px;
  stroke-width: 2;
}
.hamburger-btn svg {
  width: 15px; height: 15px;
  stroke-width: 2;
}


/* ── Toggle pill (shared for lang + theme) ──
   A true segmented toggle: equal-width segments locked to LTR order, so
   the labels never swap sides on language change — only the raised thumb
   slides to the active side. Font stack is pinned (not inherited) so
   segment widths don't shift when the body font swaps per language. */
.toggle-pill {
  position: relative;
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  direction: ltr;
  border-radius: var(--radius-pill);
  background: var(--surface);
  box-shadow: var(--shadow-inset);
  padding: 4px; gap: 2px; overflow: hidden;
}
.toggle-pill__btn {
  position: relative; z-index: 1;
  padding: 5px 14px; border: none; border-radius: var(--radius-pill);
  background: transparent; color: var(--text-muted);
  font-family: 'Outfit', 'Noto Sans Arabic', sans-serif;
  font-size: .7rem; font-weight: 700;
  cursor: pointer;
  transition: all .25s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
  white-space: nowrap;
}
.toggle-pill__btn.active {
  background: var(--surface);
  box-shadow: var(--shadow-raised-sm);
  color: var(--text-primary);
}
.toggle-pill__btn:not(.active):hover { color: var(--text-secondary); }

/* Sliding thumb — browsers without :has() keep the raised state above.
   Geometry: pill padding 4px + 2px gap → each segment = 50% − 5px. */
@supports selector(:has(*)) {
  .toggle-pill::before {
    content: '';
    position: absolute;
    top: 4px; bottom: 4px; left: 4px;
    width: calc(50% - 5px);
    border-radius: var(--radius-pill);
    background: var(--surface);
    box-shadow: var(--shadow-raised-sm);
    opacity: 0;
    transition: transform .35s cubic-bezier(.22,1,.36,1), opacity .2s;
  }
  .toggle-pill:has(.toggle-pill__btn.active)::before { opacity: 1; }
  .toggle-pill:has(.toggle-pill__btn:last-child.active)::before {
    transform: translateX(calc(100% + 2px));
  }
  .toggle-pill__btn.active { background: transparent; box-shadow: none; }
}

/* ── Theme toggle (icon button) ── */
.theme-toggle {
  position: relative;
  overflow: hidden; /* clips the theme fill to the rounded corners */
  width: 40px; height: 40px;
  border-radius: 14px;
  border: none;
  background: var(--surface);
  box-shadow: var(--shadow-raised-sm);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--text-secondary);
  font-size: 1rem;
  transition: all .2s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.theme-toggle:active {
  box-shadow: var(--shadow-inset);
  transform: scale(.93);
}
.theme-toggle svg { position: relative; z-index: 1; }

/* Theme-switch flourish: a "glass" of the incoming theme's background
   fills the button from the bottom, then the page follows (app.js injects
   the span and drives the timing). Transform/opacity only — cheap on
   mobile. Colors mirror tokens.css --bg (:root / [data-theme="dark"]). */
.theme-toggle__fill {
  position: absolute; inset: 0; z-index: 0;
  border-radius: inherit;
  transform: translateY(101%);
  pointer-events: none;
}
.theme-toggle__fill[data-fill="light"] { background: #e5eaee; }
.theme-toggle__fill[data-fill="dark"]  { background: #2b2822; }
.theme-toggle__fill.is-rising {
  transform: translateY(0);
  transition: transform .3s cubic-bezier(.22,1,.36,1);
}
.theme-toggle__fill.is-fading {
  transform: translateY(0);
  opacity: 0;
  transition: opacity .28s ease;
}

/* ── CTA button ── */
.btn-cta {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  padding: 16px 36px;
  border: none; border-radius: var(--radius-md);
  background: var(--accent);
  color: var(--accent-text);
  font-family: inherit; font-size: .95rem; font-weight: 700;
  cursor: pointer;
  box-shadow: var(--shadow-raised);
  transition: transform .2s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
  position: relative;
  isolation: isolate;
}
/* Ambient glow lives on a pseudo-element so the pulse animates opacity
   (compositor-only) instead of box-shadow (which repaints every frame). */
.btn-cta::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  box-shadow: 0 0 22px 2px var(--accent-glow), 0 0 46px 8px var(--accent-glow);
  opacity: .5;
  animation: btn-glow-fade 2.5s ease-in-out infinite;
  pointer-events: none;
}
@keyframes btn-glow-fade {
  0%, 100% { opacity: .4; }
  50% { opacity: .95; }
}
@media (prefers-reduced-motion: reduce) {
  .btn-cta::before { animation: none; }
}
.btn-cta:hover {
  background: var(--accent-hover);
  transform: translateY(-2px) scale(1.03);
}
.btn-cta:active {
  transform: scale(.97);
  box-shadow: var(--shadow-inset);
}
/* .btn-cta ambient glow now lives on .btn-cta::before (opacity-animated);
   --shadow-raised is already theme-aware, so no dark-mode box-shadow override
   is needed. */

/* ── Book float animation ── */
.book-float {
  animation: book-hover 4s ease-in-out infinite;
  filter: drop-shadow(4px 8px 16px rgba(0,0,0,.15));
  transition: filter .3s;
}
.book-float:hover {
  filter: drop-shadow(6px 12px 24px rgba(0,0,0,.2));
}
@keyframes book-hover {
  0%, 100% { transform: translateY(0) rotate(-1deg); }
  50%      { transform: translateY(-12px) rotate(1deg); }
}

/* ── Inset stage (clay well) ── */
.clay-well {
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-inset-deep);
  padding: 32px 24px;
}

/* ── Live content state surfaces ── */
.live-state-card,
.question-state-card,
.question-loading,
.question-unavailable {
  width: min(100%, 420px);
  margin: 18px auto;
  padding: 22px 20px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-raised-sm), inset 0 1px 0 rgba(255,255,255,.22);
  color: var(--text-secondary);
  text-align: center;
}

.live-state-card__icon,
.question-state-card__icon,
.question-loading__icon {
  width: 42px;
  height: 42px;
  margin: 0 auto 12px;
  border-radius: 14px;
  background: var(--surface);
  box-shadow: var(--shadow-inset);
  display: grid;
  place-items: center;
  color: var(--accent);
}

.live-state-card__title,
.question-state-card__title,
.question-loading__title {
  color: var(--text-primary);
  font-size: .86rem;
  font-weight: 800;
  margin-bottom: 6px;
}

.live-state-card__body,
.question-state-card__body,
.question-loading__body {
  max-width: 320px;
  margin: 0 auto;
  color: var(--text-muted);
  font-size: .68rem;
  font-weight: 500;
  line-height: 1.8;
}

.retry-btn,
.question-retry-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 38px;
  margin-top: 16px;
  padding: 9px 18px;
  border: 0;
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-raised-sm);
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: .72rem;
  font-weight: 800;
  transition: transform .2s var(--ease-out), box-shadow .2s var(--ease-out), color .2s var(--ease-out);
  -webkit-tap-highlight-color: transparent;
}
.retry-btn:hover,
.question-retry-btn:hover {
  color: var(--accent-hover);
  box-shadow: var(--shadow-raised), 0 0 16px var(--accent-glow);
  transform: translateY(-1px);
}
.retry-btn:active,
.question-retry-btn:active {
  box-shadow: var(--shadow-inset);
  transform: scale(.97);
}

.skeleton-line,
.question-skeleton-line {
  display: block;
  height: 12px;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--surface-alt) 0%, var(--surface) 42%, var(--surface-alt) 78%);
  background-size: 220% 100%;
  box-shadow: var(--shadow-inset);
  animation: birkari-skeleton 1.35s ease-in-out infinite;
}
.skeleton-line + .skeleton-line,
.question-skeleton-line + .question-skeleton-line { margin-top: 10px; }

@keyframes birkari-skeleton {
  0% { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

/* ── Infinity loading widget ──
   Lean and stateless: one inline SVG (~0.4KB), a single dash-orbit
   animation, no filters. Continuous motion with no start or end, so
   split-second loads read as deliberate rather than cut off.
   Full size for page-level states; --mini fits the 42px icon tile. */
.bk-loader {
  display: block;
  margin-inline: auto;
  width: 108px;
  height: 81px;
}
.bk-loader .track {
  fill: none;
  stroke: var(--surface-alt);
  stroke-width: 7;
  stroke-linecap: round;
}
.bk-loader .comet,
.bk-loader .core {
  fill: none;
  stroke: var(--accent);
  stroke-linecap: round;
  stroke-dasharray: 22 78;
  stroke-dashoffset: 100;
  animation: bk-loader-trace 1.6s linear infinite;
}
.bk-loader .comet { stroke-width: 7; opacity: .35; }
.bk-loader .core { stroke-width: 5.5; stroke-dasharray: 13 87; }
.bk-loader--mini { width: 38px; height: 28px; }
.bk-loader--mini .track,
.bk-loader--mini .comet { stroke-width: 11; }
.bk-loader--mini .core { stroke-width: 8.5; }
@keyframes bk-loader-trace {
  to { stroke-dashoffset: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .bk-loader .comet,
  .bk-loader .core {
    animation-play-state: paused;
    animation-delay: -.4s; /* rest with the comet visible on the track */
  }
}

.term-highlight,
mark.term-highlight {
  border-radius: 7px;
  padding: 0 .18em;
  background: color-mix(in srgb, var(--accent) 17%, transparent);
  color: var(--text-primary);
  box-shadow: inset 0 -0.14em 0 color-mix(in srgb, var(--accent) 36%, transparent);
}

.graph-asset,
.graph-asset-frame {
  display: grid;
  place-items: center;
  width: min(100%, 460px);
  margin: 16px auto;
  padding: 10px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-inset);
}
.graph-asset img,
.graph-asset svg,
.graph-asset-frame img,
.graph-asset-frame svg {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-md);
  filter: drop-shadow(0 8px 14px rgba(0,0,0,.08));
}

@media (prefers-reduced-motion: reduce) {
  .skeleton-line,
  .question-skeleton-line {
    animation: none;
  }
}

/* ══════════════════════════════════════════════════════════════
   Mobile / touch performance guard
   Phones read at 2–3× pixel density on weaker GPUs, and users sit
   on the explanation pages for long stretches. Neutralize the
   effects that force *continuous* repaint / re-raster while idle,
   keeping the visual intent. Desktop (wide + fine pointer) keeps
   the full glass treatment.
     • backdrop-filter re-samples & re-blurs the page behind every
       sticky bar / modal on each scroll frame → drop it and make
       the glass surfaces opaque so they stay legible.
   ══════════════════════════════════════════════════════════════ */
@media (max-width: 768px), (hover: none) and (pointer: coarse) {
  /* Opaque glass — same hue as the translucent value, no bleed-through. */
  :root { --surface-glass: #e5eaee; }
  [data-theme="dark"] { --surface-glass: #302d27; }

  *, *::before, *::after {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }

  /* Sticky desktop-workspace stepper uses a translucent color-mix bg;
     make it solid too on the off chance it renders on a large touch screen. */
  .dk-stepper-wrap { background: var(--bg) !important; }
}
