/* ─────────────────────────────────────────────────────────────────────────────
   votivepatina / styles.css

   Two worlds, deliberately clashing:
   - the warm devotional image (reds, creams, gold) that rots like a forwarded jpeg
   - the cold machine-vision overlay (YOLO neon) that brackets devotion as objects

   No external requests. All fonts are bundled locally (assets/fonts/fonts.css) or
   system faces. Three type registers kept distinct: Arabic naskh / machine mono /
   intimate serif. Motion is subtle and gated by prefers-reduced-motion.
   ──────────────────────────────────────────────────────────────────────────── */

:root {
  /* base - oulipo brand (white page, black-opacity ink) */
  --bg: #ffffff;
  --ink: rgba(0, 0, 0, 0.85);
  --ink-strong: #000000;
  --ink-muted: rgba(0, 0, 0, 0.6);
  --ink-subtle: rgba(0, 0, 0, 0.4);
  --rule: rgba(0, 0, 0, 0.75);

  /* devotional warmth (for Arabic ink + accents) */
  --warm-ink: #2a140c;
  --warm-cream: #fff6ea;

  /* detection overlay - YOLO/COCO neon, deliberately clashing */
  --yolo-green: #39ff14;
  --yolo-magenta: #ff00ff;
  --yolo-cyan: #00ffff;
  --yolo-yellow: #ffd400;
  --yolo-red: #ff3b30;
  --yolo-label-ink: #000000;

  /* faux-console / terminal drawer - OLED dark */
  --term-bg: #0b0e14;
  --term-fg: #e6e6e6;
  --term-dim: #6b7280;
  --term-accent: #22c55e;
  --term-prayer: #f8fafc;

  /* type registers */
  --font-arabic:
    "Amiri", "Noto Naskh Arabic", "Geeza Pro", "Times New Roman", serif;
  --font-mono:
    ui-monospace, "SFMono-Regular", Menlo, "Cascadia Mono", Consolas,
    "Liberation Mono", monospace;
  --font-serif:
    "EB Garamond", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia,
    serif;
  --font-sans:
    system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* motion */
  --t-micro: 200ms;
  --t-decay: 400ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  /* z-index scale */
  --z-image: 1;
  --z-arabic: 15;
  --z-boxes: 20;
  --z-sweep: 25;
  --z-panel: 30;
  --z-drawer: 50;
  --z-lightbox: 70;
  --z-about: 80;

  /* v3 - radiance (the icon as a sun/spaceship) + satellite detection colors */
  --radiance: 0; /* 0..1, raised per decay step by main.js */
  --glow: #ffd34d; /* warm devotional yellow */
  --sat-pink: #ff3da6;
  --sat-green: #39ff14;
}

/* ── reset / base ─────────────────────────────────────────────────────────── */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  /* Clip at the root too (not just body) so no stray horizontal overflow can widen
     the layout and make a phone zoom out to fit - which would displace the fixed
     "?" toggle. Vertical scrolling is unaffected. */
  overflow-x: clip;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 1.05rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
a:hover {
  opacity: 0.7;
}

:focus-visible {
  outline: 2px solid var(--ink-strong);
  outline-offset: 2px;
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ── page shell ───────────────────────────────────────────────────────────── */
.page {
  max-width: 540px;
  margin: 0 auto;
  padding: 2rem 1.25rem 6rem;
}

.site-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--ink-muted);
  text-transform: lowercase;
  margin-bottom: 2.5rem;
}
.site-head a {
  text-decoration: none;
}
.site-head a:hover {
  text-decoration: underline;
}

.intro {
  margin-bottom: 1.75rem;
}
.intro h1 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(2.4rem, 12vw, 3.4rem);
  line-height: 1;
  letter-spacing: -0.01em;
  margin: 0 0 0.6rem;
  color: var(--ink-strong);
}
.intro .lede {
  font-family: var(--font-serif);
  font-size: 1.15rem;
  line-height: 1.45;
  color: var(--ink-muted);
  margin: 0;
}
.intro .dek {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-subtle);
  margin: 0.9rem 0 0;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.returning-note {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-subtle);
  margin: 0.75rem 0 0;
}

/* ── the interactive prayer card (phone-proportioned) ─────────────────────── */
.prayer-card {
  position: relative;
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
  aspect-ratio: 2 / 3;
  background: var(--warm-cream);
  container-type: inline-size;
  overflow: hidden;
  isolation: isolate; /* contain the z-index scale to the card */
  user-select: none;
}

/* the decaying photo - the only layer that rots */
#mary-source {
  display: none;
}
#mary-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: var(--z-image);
  display: block;
}

/* scrim over the lower image: hides the photo's OWN burned-in Arabic and gives the
   live prayer lines a legible dark surface, while the face + halo stay bright.
   Sits above the decaying canvas (z 1) and below the live text (z 15) + boxes. */
.card-scrim {
  position: absolute;
  inset: 0;
  z-index: 10;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    transparent 33%,
    rgba(8, 5, 3, 0.5) 50%,
    rgba(8, 5, 3, 0.88) 78%,
    rgba(8, 5, 3, 0.92) 100%
  );
}

/* live Arabic text - crisp, RTL, never decays */
.arabic-layer {
  position: absolute;
  inset: 0;
  z-index: var(--z-arabic);
  pointer-events: none;
}
.ar-line {
  position: absolute;
  display: flex;
  justify-content: flex-end; /* RTL right-align within the band */
  align-items: center;
}
.ar-glyphs {
  font-family: var(--font-arabic);
  font-weight: 700;
  font-size: 6.4cqw;
  line-height: 1.3;
  white-space: nowrap;
  /* light type over the scrimmed photo: the words stay crisp and legible while the
     image rots beneath them, then migrate into the console */
  color: var(--warm-cream);
  text-shadow:
    0 1px 3px rgba(0, 0, 0, 0.95),
    0 0 10px rgba(0, 0, 0, 0.7),
    0 0 2px rgba(0, 0, 0, 0.9);
}

/* ── the machine-vision overlay (boxes as real buttons) ───────────────────── */
.boxes-overlay {
  position: absolute;
  inset: 0;
  z-index: var(--z-boxes);
  pointer-events: none; /* the container ignores clicks; the buttons opt back in */
}
.det-box {
  position: absolute;
  margin: 0;
  padding: 0;
  background: transparent;
  border: 2px solid var(--box-color, var(--yolo-green));
  cursor: pointer;
  pointer-events: auto;
  /* Un-revealed boxes are visibility:hidden (not just opacity:0) so they are
     genuinely gone: not painted, not focusable, not clickable, and correctly
     reported as not-visible. You cannot pray before pressing "Pray for us". */
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--t-micro) var(--ease-out),
    visibility var(--t-micro) var(--ease-out);
  /* a faint neon presence - the cold eye */
  box-shadow: 0 0 6px
    color-mix(in srgb, var(--box-color, #39ff14) 55%, transparent);
}
/* guarantee a 44x44 tap target even on tiny mislabels, without changing visuals */
.det-box::before {
  content: "";
  position: absolute;
  inset: -8px;
  min-width: 44px;
  min-height: 44px;
}
.det-box.is-revealed {
  opacity: 1;
  visibility: visible;
  transition-delay: calc(var(--reveal-index, 0) * 110ms);
}
.det-box:hover {
  box-shadow: 0 0 12px
    color-mix(in srgb, var(--box-color, #39ff14) 80%, transparent);
}
.det-box:focus-visible {
  outline: 2px solid var(--box-color, var(--yolo-cyan));
  outline-offset: 2px;
}
.det-box[data-opened="true"] {
  border-style: double;
}
/* box-type is NEVER signalled by color alone: stroke style differs too */
.det-box[data-box-type="virgin"] {
  border-width: 3px;
}
.det-box[data-box-type="mislabel"] {
  border-style: dashed;
  border-width: 1.5px;
  opacity: 0;
  visibility: hidden;
}
.det-box[data-box-type="mislabel"].is-revealed {
  opacity: 0.62;
  visibility: visible;
}

.det-label {
  position: absolute;
  left: -1.5px;
  top: 0;
  transform: translateY(-100%);
  background: var(--box-color, var(--yolo-green));
  color: var(--yolo-label-ink);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  line-height: 1.25;
  font-weight: 700;
  padding: 1px 5px;
  white-space: nowrap;
  letter-spacing: 0.01em;
  /* decorative (aria-hidden): a label tab sits above its box and can overlap the
     box above it - never let it swallow that box's clicks. The box body handles
     the gesture. */
  pointer-events: none;
}

/* the detection sweep - a neon scan line traveling top to bottom */
.sweep {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  z-index: var(--z-sweep);
  background: var(--yolo-cyan);
  box-shadow:
    0 0 10px var(--yolo-cyan),
    0 0 24px var(--yolo-cyan);
  opacity: 0;
  pointer-events: none;
}
body[data-state="detecting"] .sweep {
  animation: sweep-travel 1100ms var(--ease-out) forwards;
}
@keyframes sweep-travel {
  0% {
    top: 0;
    opacity: 0;
  }
  8% {
    opacity: 1;
  }
  92% {
    opacity: 1;
  }
  100% {
    top: 100%;
    opacity: 0;
  }
}
/* a faint scanline texture while the machine "looks" */
body[data-state="detecting"] .prayer-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: var(--z-sweep);
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 3px,
    rgba(0, 255, 255, 0.05) 3px,
    rgba(0, 255, 255, 0.05) 4px
  );
}

/* ── the pray gate + the counter pill ─────────────────────────────────────── */
.card-controls {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 1rem;
  z-index: var(--z-panel);
  display: flex;
  justify-content: center;
  pointer-events: none;
}
.card-controls > * {
  pointer-events: auto;
}

.pill {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  border: none;
  border-radius: 999px;
  padding: 0.7rem 1.4rem;
  cursor: pointer;
  min-height: 44px;
}
.pray-pill {
  background: var(--warm-ink);
  color: var(--warm-cream);
  text-transform: lowercase;
  letter-spacing: 0.04em;
}
.pray-pill:hover {
  opacity: 0.85;
}
.counter-pill {
  background: #ff7a18; /* the orange of the storyboard */
  color: #000;
  max-width: 92%;
  text-align: center;
  line-height: 1.2;
}
.counter-pill.is-complete {
  background: #000;
  color: var(--term-accent);
  font-size: 0.72rem;
  cursor: pointer;
}

/* the closing couplet, spoken softly on the card at 5 of 5 */
.closing-couplet {
  position: absolute;
  inset: 0;
  z-index: var(--z-panel);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 0.15rem;
  padding: 2rem;
  text-align: center;
  background: radial-gradient(
    ellipse at center,
    rgba(255, 246, 234, 0.82),
    rgba(255, 246, 234, 0.5)
  );
  opacity: 0;
  transition: opacity 1.2s var(--ease-out);
  pointer-events: none;
}
body[data-state="complete"] .closing-couplet,
body[data-state="resting"] .closing-couplet {
  opacity: 1;
}
.cc-line {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.05rem;
  line-height: 1.35;
  color: var(--warm-ink);
}

/* in the resting state the boxes fade; the prayer has migrated elsewhere */
body[data-state="resting"] .boxes-overlay {
  opacity: 0.18;
  transition: opacity 1.5s var(--ease-out);
}

/* ── translation panel + the "+" buried expansion ─────────────────────────── */
.translation-panel {
  max-width: 420px;
  margin: 1.25rem auto 0;
  border-top: 1px solid var(--rule);
  padding-top: 1rem;
  min-height: 2rem;
}
.tp-literal {
  font-family: var(--font-mono);
  font-size: 0.92rem;
  line-height: 1.4;
  color: var(--ink);
  margin: 0;
  letter-spacing: -0.01em;
}
.tp-aside {
  font-family: var(--font-serif);
  font-size: 1.08rem;
  font-style: italic;
  line-height: 1.5;
  color: var(--ink-muted);
  margin: 0.75rem 0 0;
}
.tp-expand {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.85rem;
  padding: 0.35rem 0.1rem;
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-subtle);
}
.tp-expand:hover {
  color: var(--ink);
}
.tp-plus {
  font-size: 1.1rem;
  line-height: 1;
}
.tp-expand[aria-expanded="true"] .tp-plus {
  transform: rotate(45deg);
  display: inline-block;
}
.tp-expansion {
  overflow: hidden;
  margin-top: 0.5rem;
  border-left: 2px solid var(--warm-ink);
  padding-left: 1rem;
  animation: uncover var(--t-micro) var(--ease-out);
}
.tp-expansion p {
  font-family: var(--font-serif);
  font-size: 1.18rem;
  line-height: 1.55;
  color: var(--warm-ink);
  margin: 0;
}
@keyframes uncover {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ── the longitudinal litany (a forwarded thread, worn by scroll depth) ───── */
.litany {
  max-width: 420px;
  margin: 4rem auto 0;
}
.litany-head {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-subtle);
  border-top: 1px solid var(--rule);
  padding-top: 1rem;
  margin-bottom: 1.5rem;
}
.litany-item {
  margin: 0 0 1.25rem;
}
.litany-jpeg {
  display: block;
  width: 100%;
  height: auto;
  /* generational loss deepens with scroll depth (--wear set by main.js) */
  filter: contrast(calc(1 + var(--wear, 0) * 0.7))
    saturate(calc(1 - var(--wear, 0) * 0.55))
    brightness(calc(1 - var(--wear, 0) * 0.06))
    blur(calc(var(--wear, 0) * 0.7px));
  transition: filter 600ms var(--ease-out);
}

/* ── interactive litany cards ─────────────────────────────────────────────── */
/* Each found prayer is a <article class="litany-card"> containing a positioned
   frame (canvas + overlay) followed by an inline panel. The same det-box and
   tp-* classes from the top card apply here, so visual language is consistent. */

.litany-card {
  position: relative;
  margin-bottom: 2.5rem;
  /* container-type allows Arabic inside to use cqw if ever needed */
  container-type: inline-size;
}

/* The frame holds the canvas and the absolute detection overlay so the overlay
   aligns perfectly to the image regardless of card width. */
.litany-frame {
  position: relative;
}

/* The hidden source image - never displayed, only drawn to the canvas */
.litany-source {
  display: none;
}

/* The decaying canvas: fills the frame, scales responsively */
.litany-card .litany-canvas {
  display: block;
  width: 100%;
  height: auto;
}

/* The boxes overlay: sits above the canvas (z-boxes), covers exactly the frame */
.litany-boxes {
  position: absolute;
  inset: 0;
  z-index: var(--z-boxes);
  pointer-events: none; /* buttons inside opt back in */
}

/* The inline panel below each card's image */
.litany-panel {
  border-top: 1px solid var(--rule);
  padding-top: 1rem;
  margin-top: 0.75rem;
}

/* The Arabic text from the image, rendered as live RTL type.
   Uses the same Arabic naskh face as the top card's overlay, but larger and
   ink-strong because here it sits on a white surface, not a dark scrim. */
.lp-arabic {
  font-family: var(--font-arabic);
  font-size: 1.5rem;
  line-height: 1.6;
  color: var(--ink-strong);
  text-align: right;
  margin: 0 0 0.6rem;
  direction: rtl;
}

/* ── the mobile "look beneath" faux-console drawer (mirror of the console) ── */
.console-handle {
  position: fixed;
  right: 0.8rem;
  bottom: 0.8rem;
  z-index: var(--z-drawer);
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  background: var(--term-bg);
  color: var(--term-fg);
  border: 1px solid #1d2430;
  border-radius: 999px;
  padding: 0.5rem 1rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  cursor: pointer;
  min-height: 44px;
}
.console-handle .chev {
  transition: transform var(--t-micro) var(--ease-out);
}
.console-handle[aria-expanded="true"] .chev {
  transform: rotate(180deg);
}

.console-drawer {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-drawer);
  height: min(60vh, 420px);
  background: var(--term-bg);
  color: var(--term-fg);
  border-top: 1px solid #1d2430;
  transform: translateY(100%);
  transition: transform 320ms var(--ease-out);
  display: flex;
  flex-direction: column;
}
.console-drawer[data-open="true"] {
  transform: translateY(0);
}
.console-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.55rem 0.9rem;
  border-bottom: 1px solid #1d2430;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--term-dim);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.console-close {
  background: none;
  border: 1px solid #1d2430;
  color: var(--term-fg);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  padding: 0.25rem 0.6rem;
  cursor: pointer;
  min-height: 32px;
}
.console-body {
  flex: 1;
  overflow-y: auto;
  padding: 0.85rem 0.95rem 1.5rem;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  line-height: 1.55;
}
.console-line {
  white-space: pre-wrap;
  color: var(--term-prayer);
}
.console-line[data-kind="line"] {
  color: var(--term-fg);
}
.console-line[data-kind="couplet"] {
  color: var(--term-dim);
}
.console-line.is-invite {
  color: var(--term-accent);
  font-style: italic;
  padding: 0.4rem 0;
}
.console-line.will-print {
  opacity: 0;
  transform: translateY(3px);
}
.console-line.is-printed {
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity 200ms var(--ease-out) calc(var(--print-index, 0) * 60ms),
    transform 200ms var(--ease-out) calc(var(--print-index, 0) * 60ms);
}

/* ── footer ───────────────────────────────────────────────────────────────── */
.site-foot {
  max-width: 420px;
  margin: 4rem auto 0;
  border-top: 1px solid var(--rule);
  padding-top: 1.25rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-subtle);
  line-height: 1.6;
}
.site-foot a {
  color: var(--ink-muted);
}

/* ── responsive ───────────────────────────────────────────────────────────── */
@media (min-width: 768px) {
  .page {
    padding-top: 3.5rem;
  }
  /* desktop: keep the phone-like proportion; do NOT stretch the card full-width */
  .prayer-card {
    max-width: 380px;
  }
}

/* coarse pointer: the handle is offered; on fine pointers we rely on DevTools */
body[data-coarse-pointer="0"] .console-handle {
  display: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   v3 - the quiet landing, the About, the one radiant button, and the
   constellation: the icon as a sun/spaceship shooting rays that carry the
   forwarded prayers, each opening in a lightbox.
   ═══════════════════════════════════════════════════════════════════════════ */

body {
  overflow-x: clip; /* the constellation breaks out to viewport width */
}

/* ── the quiet intro (title + one line, centered above the icon) ──────────── */
.intro {
  text-align: center;
  margin: 0 auto 1.5rem;
  max-width: 30rem;
}
.intro h1 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1.3rem, 3.4vw, 1.6rem);
  line-height: 1.15;
  letter-spacing: 0.01em;
  margin: 0 0 0.35rem;
  color: var(--ink-muted);
}
.intro .lede {
  font-family: var(--font-serif);
  font-size: 1.12rem;
  line-height: 1.45;
  color: var(--ink-strong);
  margin: 0;
}

/* ── About: a quiet question mark, top-right ──────────────────────────────── */
.about-toggle {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 60;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(0, 0, 0, 0.35);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.7);
  color: var(--ink-muted);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.2rem;
  cursor: pointer;
  opacity: 0.55;
  transition:
    opacity var(--t-micro) var(--ease-out),
    border-color var(--t-micro) var(--ease-out);
}
.about-toggle:hover,
.about-toggle:focus-visible {
  opacity: 1;
  border-color: var(--ink-strong);
}

.about-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-about);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 4vh 1rem;
}
.about-overlay[hidden] {
  display: none;
}
.about-scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
}
body.about-open {
  overflow: hidden;
}
.about-panel {
  position: relative;
  max-width: 40rem;
  max-height: 92vh;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--rule);
  padding: 2.5rem 2rem 2rem;
  font-family: var(--font-serif);
  font-size: 1.08rem;
  line-height: 1.6;
  color: var(--ink);
}
.about-close {
  position: absolute;
  top: 0.8rem;
  right: 0.9rem;
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-subtle);
  padding: 0.4rem;
  min-height: 44px;
}
.about-close:hover {
  color: var(--ink);
}
.about-panel h2 {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: 2rem;
  margin: 0 0 1rem;
  color: var(--ink-strong);
}
.about-panel h3 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 1.45rem;
  margin: 0.5rem 0 0.2rem;
  color: var(--ink-strong);
}
.about-panel h4 {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-muted);
  margin: 1.6rem 0 0.4rem;
}
.about-panel p {
  margin: 0 0 1rem;
}
.about-frame {
  font-size: 1rem;
  color: var(--ink-muted);
}
.about-dek {
  font-style: italic;
  color: var(--ink-muted);
}
.about-byline {
  display: block;
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-subtle);
  margin-top: 0.3rem;
}
.about-panel blockquote {
  margin: 0 0 1rem;
  padding-left: 1rem;
  border-left: 2px solid var(--warm-ink);
  font-style: italic;
  color: var(--warm-ink);
}
.about-panel hr {
  border: 0;
  height: 1px;
  background: var(--rule);
  margin: 1.6rem 0;
}
.about-colophon {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-subtle);
  line-height: 1.6;
}

/* ── the constellation: a wide stage centered on the icon ─────────────────── */
.constellation {
  position: relative;
  width: min(100vw, 1100px);
  left: 50%;
  transform: translateX(-50%);
  margin: 1rem 0 2rem;
}
.card-stack {
  position: relative;
  z-index: 3;
  max-width: 420px;
  margin: 0 auto;
}

/* the rays (SVG): thin lines of light from the icon to each satellite */
.rays {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}
.rays line {
  stroke: var(--glow);
  stroke-width: 2;
  stroke-linecap: round;
  filter: drop-shadow(0 0 4px var(--glow));
  opacity: 0;
  transition:
    opacity 500ms var(--ease-out),
    stroke-dashoffset 700ms var(--ease-out);
}
.rays line.is-lit {
  opacity: 0.85;
}

/* the satellites (forwarded prayers), positioned by JS at the ray ends */
.satellites {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.satellite {
  position: absolute;
  width: 78px;
  height: 78px;
  margin: -39px 0 0 -39px; /* center on its anchor point */
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  pointer-events: auto;
  opacity: 0;
  transform: scale(0.6);
  transition:
    opacity 500ms var(--ease-out),
    transform 500ms var(--ease-out);
}
.satellite.is-revealed {
  opacity: 1;
  transform: scale(1);
}
.satellite img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  box-shadow: 0 0 10px rgba(255, 211, 77, 0.5);
}
.satellite:hover img,
.satellite:focus-visible img {
  box-shadow: 0 0 16px rgba(255, 211, 77, 0.85);
}
.satellite:focus-visible {
  outline: 2px solid var(--glow);
  outline-offset: 3px;
}
/* the two little colored squares that hint it can be read */
.sat-hint {
  position: absolute;
  bottom: 4px;
  left: 4px;
  display: flex;
  gap: 3px;
}
.sat-hint i {
  width: 7px;
  height: 7px;
  display: block;
}
.sat-hint .pink {
  background: var(--sat-pink);
}
.sat-hint .green {
  background: var(--sat-green);
}

/* ── the single bilingual prayer button, ABOVE the icon ───────────────────── */
.card-controls {
  position: static;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  margin: 0 auto 0.9rem;
}
.prayer-button {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  border: 1px solid var(--warm-ink);
  border-radius: 4px;
  background: var(--warm-cream);
  color: var(--warm-ink);
  padding: 0.55rem 1.5rem;
  cursor: pointer;
  min-height: 44px;
  text-align: center;
  transition:
    box-shadow var(--t-micro) var(--ease-out),
    background var(--t-micro) var(--ease-out),
    color var(--t-micro) var(--ease-out),
    border-color var(--t-micro) var(--ease-out);
  /* the radiance: a yellow glow that grows with --radiance */
  box-shadow: 0 0 calc(6px + var(--radiance) * 36px) calc(var(--radiance) * 6px)
    rgba(255, 211, 77, calc(var(--radiance) * 0.75));
}
.prayer-button .pb-en {
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.01em;
}
.prayer-button .pb-ar {
  font-family: var(--font-arabic);
  font-size: 1.05rem;
  line-height: 1.2;
}
.prayer-button[data-phase="instruct"] {
  background: #ececec;
  color: var(--ink-muted);
  border-color: rgba(0, 0, 0, 0.18);
  cursor: default;
}
.prayer-button[data-phase="answered"] {
  background: #fff7df;
  border-color: var(--glow);
  color: var(--warm-ink);
  cursor: pointer;
}
.copy-flash {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-muted);
  margin: 0;
  min-height: 1rem;
}
.copy-flash .cf-ar {
  font-family: var(--font-arabic);
}

/* the icon itself radiates as it wears (glow keyed to --radiance) */
.prayer-card {
  box-shadow: 0 0 calc(var(--radiance) * 55px) calc(var(--radiance) * 8px)
    rgba(255, 211, 77, calc(var(--radiance) * 0.4));
  transition: box-shadow var(--t-decay) var(--ease-out);
}

/* ── the lightbox: a forwarded prayer, enlarged ───────────────────────────── */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3vh 1rem;
}
.lightbox[hidden] {
  display: none;
}
.lightbox-scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.78);
}
body.lightbox-open {
  overflow: hidden;
}
.lightbox-stage {
  position: relative;
  width: min(92vw, 460px);
  max-height: 94vh;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--rule);
  padding: 2.4rem 1rem 1.2rem;
}
.lightbox-close {
  position: absolute;
  top: 0.7rem;
  right: 0.9rem;
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-subtle);
  padding: 0.4rem;
  min-height: 44px;
}
.lightbox-close:hover {
  color: var(--ink);
}
.lightbox-frame {
  position: relative;
  line-height: 0;
}
.lightbox-canvas {
  display: block;
  width: 100%;
  height: auto;
  max-height: 64vh;
  object-fit: contain;
}
.lightbox-boxes {
  position: absolute;
  inset: 0;
}
.lightbox-panel {
  line-height: 1.5;
  border-top: 1px solid var(--rule);
  margin-top: 1rem;
  padding-top: 1rem;
}

/* bilingual console drawer: Arabic lines (kinds ending in "-ar") render RTL in the
   naskh face; the English lines stay in the machine monospace */
.console-line[data-kind$="-ar"] {
  font-family: var(--font-arabic);
  direction: rtl;
  text-align: right;
  font-size: 1.02rem;
  color: var(--term-prayer);
}

/* ── reduced motion: keep the decay (content), drop the choreography ──────── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .sweep {
    display: none;
  }
  .det-box {
    transition: none;
  }
  .closing-couplet {
    transition: none;
  }
}
