/* Sabqi website — one stylesheet, no build step, no JavaScript, no external
 * request of any kind. Fonts are the reader's own system faces; images are
 * same-origin WebP. A page App Review opens once and judges immediately should
 * not have a way to fail to render.
 *
 * ─── Colour ──────────────────────────────────────────────────────────────
 *
 * Every value below is lifted from `Sabqi/Core/Theme/Theme.swift` so the site
 * and the app are the same object. Where that file quotes a measured contrast
 * ratio, the ratio is repeated here, because the pairing is the same pairing.
 *
 * The one thing that surprises people: **the card is near-white in BOTH
 * themes.** DESIGN.md §2 row 9 is a white card either way, so `Theme.dark`
 * and `Theme.light` differ in their *background*, not their card. That is why
 * `--card-text`, `--card-accent` and the highlight pill are theme-independent
 * here — Theme.swift already resolved them to one value each that clears AA on
 * a near-white surface in both themes, and re-deriving them per theme is how
 * the app's `accentFill` comment describes getting it backwards.
 *
 * ─── Type ────────────────────────────────────────────────────────────────
 *
 * There is no display face and that is the choice, not the default. The page's
 * one piece of display typography is the Qur'anic line in the hero, set in
 * whatever Arabic face the reader's device carries — which on an iPhone, the
 * only device this app runs on, is the same SF Arabic the app draws with. The
 * Uthmani font the app bundles is deliberately NOT served here: its EULA
 * forbids modification, so it can be neither subset nor safely redistributed.
 * The Latin type stays the system UI face for the same reason the app does.
 *
 * ─── Motion ──────────────────────────────────────────────────────────────
 *
 * One animation on the whole site: the word-by-word highlight in the hero,
 * which is the product's single characteristic moment. Everything else is
 * still. `prefers-reduced-motion` settles the hero on its last word rather
 * than blanking it — see the block at the foot of this file. */

/* ── tokens ───────────────────────────────────────────────────────────── */

:root {
  /* ThemeGradient.dark — top darker, bottom lighter (DESIGN.md §1). */
  --grad-1: #052124;
  --grad-2: #0a3838;
  --grad-3: #12544d;

  /* Theme.dark */
  --text: #ffffff;
  --text-dim: rgba(255, 255, 255, 0.72);
  --accent: #5cd9b8;                 /* accent, 5.01–9.63 on the gradient */
  --card: #f7fafa;                   /* cardSurface */
  --card-dim: #597375;               /* cardSecondaryText, 4.85 on the card */
  --rule: rgba(242, 248, 248, 0.16);
  --rule-soft: rgba(242, 248, 248, 0.09);
  --bezel: linear-gradient(155deg, #1b4446, #04191b 52%, #10393b);
  --lift: 0 1px 2px rgba(0, 0, 0, 0.3), 0 16px 44px rgba(0, 0, 0, 0.28);
  --lift-sm: 0 1px 2px rgba(0, 0, 0, 0.26), 0 6px 18px rgba(0, 0, 0, 0.2);

  /* Theme-independent — the card is near-white in both themes. */
  --card-text: #0f2629;              /* cardText, 15.01 / 15.75 on the card */
  --card-accent: #0a6657;            /* Theme.cardAccentColor, 6.56 / 6.88 */
  /* A hairline *on the card*. `--rule` is white-on-dark for the page and is
   * invisible the moment it is drawn on a near-white surface. */
  --card-rule: rgba(15, 38, 41, 0.13);
  --pill: #0a6657;                   /* the highlight, as PlayerView draws it */
  --on-pill: #ffffff;                /* 6.88 on --pill */

  /* Hero timing. Four words; the cycle carries a deliberate rest at the end
   * so the loop reads as a phrase finishing rather than a spinner. */
  --step: 1.15s;
  --cycle: 6s;
}

@media (prefers-color-scheme: light) {
  :root {
    /* ThemeGradient.light — airy blue → green pastel. */
    --grad-1: #abdbe8;
    --grad-2: #bfe6e3;
    --grad-3: #d6f0db;

    /* Theme.light. textSecondary and accent are the deepened Phase 4 values;
     * the pale gradient failed AA against the originals. */
    --text: #0f2b30;
    --text-dim: #335c61;
    --accent: #0a6657;
    --card: #ffffff;
    --card-dim: #617a80;
    --rule: rgba(15, 43, 48, 0.16);
    --rule-soft: rgba(15, 43, 48, 0.08);
    --bezel: linear-gradient(155deg, #2c5c5e, #0b2426 52%, #204b4d);
    --lift: 0 1px 2px rgba(10, 56, 56, 0.1), 0 16px 44px rgba(10, 56, 56, 0.16);
    --lift-sm: 0 1px 2px rgba(10, 56, 56, 0.08), 0 6px 18px rgba(10, 56, 56, 0.12);
  }
}

/* ── base ─────────────────────────────────────────────────────────────── */

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  min-height: 100vh;
  background: linear-gradient(163deg, var(--grad-1), var(--grad-2) 46%, var(--grad-3));
  background-attachment: fixed;
  color: var(--text);
  font: 400 17px/1.68 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui,
        Roboto, "Helvetica Neue", sans-serif;
  padding: 0 22px 88px;
  overflow-x: hidden;
}

/* `margin-inline`, not the `margin: 0 auto` shorthand. `.wrap` is also on the
 * <footer>, and the shorthand's implicit `margin-top: 0` out-specifies
 * `footer { margin-top: … }` and welds the footer to the section above it. */
.wrap { max-width: 46rem; margin-inline: auto; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ── masthead ─────────────────────────────────────────────────────────── */

.masthead {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 20px;
  align-items: center;
  justify-content: space-between;
  padding: 34px 0 6px;
}

.wordmark {
  font-size: 1.32rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--text);
  text-decoration: none;
}

.wordmark span { color: var(--accent); }

/* ── language switcher (CSS only) ─────────────────────────────────────── */

.lang-input { position: absolute; opacity: 0; pointer-events: none; }

.lang-picker {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--rule);
  border-radius: 999px;
}

.lang-picker label {
  padding: 5px 14px;
  border-radius: 999px;
  font-size: 0.84rem;
  font-weight: 500;
  color: var(--text-dim);
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease;
}

.lang-picker label:hover { color: var(--text); }

/* The radios are visually hidden, so the focus ring has to be borrowed by the
 * label the keyboard is actually on. */
.lang-input:focus-visible + .lang-picker label,
.lang-picker label:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* `.t` and not a bare `[lang]`: <html lang="nl"> carries the attribute too, and
 * a bare attribute selector hides the whole document. */
/* `.t.t` and not `.t`: the elements this hides include a flex row and a grid,
 * and `.absences { display: flex }` further down the file is the same one-class
 * specificity — so a plain `.t` loses on source order and every language shows
 * at once. Doubling the class wins without dragging !important in, and without
 * making the file order-dependent for whoever edits it next. */
.t.t { display: none; }

/* The reveal is `var(--t-display, block)` rather than a flat `block` because
 * this selector carries an id and would otherwise out-specify every layout
 * rule it lands on — a translated `.absences` (flex) or `.grid` (grid) would
 * silently collapse to a block. Each such element names its own display below
 * and the default covers everything else. */
#lang-nl:checked ~ .t[lang="nl"],
#lang-en:checked ~ .t[lang="en"],
#lang-tr:checked ~ .t[lang="tr"],
#lang-nl:checked ~ * .t[lang="nl"],
#lang-en:checked ~ * .t[lang="en"],
#lang-tr:checked ~ * .t[lang="tr"] { display: var(--t-display, block); }

/* `~ *` and not `~ .masthead`: the header is wrapped for width, so the picker is
 * a descendant of a sibling rather than a sibling itself. */
#lang-nl:checked ~ * label[for="lang-nl"],
#lang-en:checked ~ * label[for="lang-en"],
#lang-tr:checked ~ * label[for="lang-tr"] {
  background: var(--accent);
  color: var(--grad-1);
}

@media (prefers-color-scheme: light) {
  #lang-nl:checked ~ * label[for="lang-nl"],
  #lang-en:checked ~ * label[for="lang-en"],
  #lang-tr:checked ~ * label[for="lang-tr"] { color: #ffffff; }
}

/* ── type ─────────────────────────────────────────────────────────────── */

h1 {
  font-size: clamp(2.35rem, 6.6vw, 3.9rem);
  line-height: 1.06;
  letter-spacing: -0.032em;
  font-weight: 600;
  margin: 30px 0 16px;
  max-width: 15ch;
}

/* Prose spacing. The landing page drives its rhythm from `.band` instead, so
 * every container that owns its own spacing resets these — see `.band-head`,
 * `.card` and `.grid` below. Getting this backwards (no top margin here, top
 * margin added per container) leaves the privacy and support prose with its
 * headings welded to the paragraph above. */
h2 {
  font-size: clamp(1.3rem, 2.6vw, 1.55rem);
  font-weight: 600;
  letter-spacing: -0.018em;
  margin: 42px 0 12px;
}

h3 {
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.008em;
  margin: 26px 0 6px;
}

p { margin: 0 0 15px; }

/* Scoped, not a global `p:last-child`. A global one out-specifies `.lede` and
 * silently ate the whole gap between the lede and the hero card, because the
 * lede is the last child of its language wrapper. */
.card p:last-child,
.grid > div > p:last-child,
.answer p:last-child { margin-bottom: 0; }

.lede {
  font-size: clamp(1.1rem, 2.3vw, 1.32rem);
  line-height: 1.55;
  color: var(--text-dim);
  max-width: 33rem;
  margin-bottom: 34px;
}

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }

ul { margin: 0 0 15px; padding-left: 1.15em; }
li { margin-bottom: 7px; }

strong { font-weight: 600; }

.meta { font-size: 0.9rem; color: var(--text-dim); }

.eyebrow {
  font-size: 0.71rem;
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--card-dim);
  margin: 0;
}

/* ── sections ─────────────────────────────────────────────────────────── */

.band { margin-top: clamp(56px, 9vw, 88px); }
.band > :first-child { margin-top: 0; }

.band-head {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin-bottom: 20px;
}

.band-head::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--rule);
}

.band-head h2 { margin: 0; }

/* ── the hero's scripture card — the one signature element ────────────── */

.scripture {
  background: var(--card);
  color: var(--card-text);
  border-radius: 26px;
  padding: clamp(22px, 4vw, 32px) clamp(20px, 4vw, 34px) clamp(24px, 4vw, 30px);
  box-shadow: var(--lift);
}

/* Qur'anic lines are flush right, always — never centred per line. RTL flex
 * puts flex-start at the right edge, and wrapping keeps every line there. */
.ayah {
  display: flex;
  flex-wrap: wrap;
  direction: rtl;
  gap: 0.1em 0.34em;
  margin: 0.22em 0 0;
  font-family: "SF Arabic", "Geeza Pro", "Al Bayan", "Noto Naskh Arabic",
               "Traditional Arabic", "Amiri", "Scheherazade New", serif;
  font-size: clamp(2rem, 7.2vw, 3.7rem);
  line-height: 1.78;
  font-weight: 400;
}

.w {
  padding: 0.02em 0.19em 0.09em;
  border-radius: 0.19em;
  animation: lit var(--cycle) linear infinite;
  animation-delay: calc(var(--i) * var(--step));
}

/* On for one --step of the cycle, with a short fade at each end. The cycle is
 * longer than 4 × --step, so the phrase finishes and rests before repeating. */
@keyframes lit {
  0%    { background-color: transparent; color: var(--card-text); }
  2.5%  { background-color: var(--pill); color: var(--on-pill); }
  16%   { background-color: var(--pill); color: var(--on-pill); }
  19%   { background-color: transparent; color: var(--card-text); }
  100%  { background-color: transparent; color: var(--card-text); }
}

/* The gloss under the line follows the same phase, so what you read is what is
 * lit. Absolutely positioned in a fixed box: a swapping line that reflows the
 * card underneath it is the opposite of calm. */
/* The foot carries the reciter on the left and the gloss on the right. It is
 * one positioned box for both so the gloss can be taken out of flow — a line
 * that swaps every 1.15s and reflows the card under it is the opposite of the
 * calm the product asks for. */
.scripture-foot {
  position: relative;
  min-height: 2.2em;
  margin-top: 0.5em;
  border-top: 1px solid var(--card-rule);
  padding-top: 0.85em;
}

.reciter {
  margin: 0;
  font-size: 0.9rem;
  color: var(--card-dim);
}

.glosses { position: static; }

.gloss {
  position: absolute;
  right: 0;
  left: 40%;
  top: 0.85em;
  margin: 0;
  text-align: right;
  font-size: 1.04rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--card-text);
  opacity: 0;
  animation: gloss var(--cycle) linear infinite;
  animation-delay: calc(var(--i) * var(--step));
}

.gloss b { font-weight: 600; color: var(--card-text); }

@keyframes gloss {
  0%    { opacity: 0; transform: translateY(4px); }
  2.5%  { opacity: 1; transform: none; }
  16%   { opacity: 1; transform: none; }
  19%   { opacity: 0; transform: translateY(-4px); }
  100%  { opacity: 0; transform: translateY(-4px); }
}

/* Two short strings on one line have room to collide on a small phone. The
 * gloss is the one carrying meaning, so the reciter is what goes. */
@media (max-width: 27rem) {
  .reciter { display: none; }
  .gloss { left: 0; }
}

.scripture-caption {
  margin: 16px 2px 0;
  font-size: 0.94rem;
  color: var(--text-dim);
  max-width: 34rem;
}

/* ── the absences, which are the product ──────────────────────────────── */

/* Two columns by default, dividers only once all four fit on one line. A
 * wrapped flex row cannot know which item starts a line, so `li:first-child`
 * kills exactly one divider and the second row opens with a stray rule. */
.absences {
  --t-display: grid;
  display: grid;
  grid-template-columns: repeat(2, auto);
  justify-content: start;
  gap: 9px 30px;
  margin: 30px 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.95rem;
  color: var(--text-dim);
}

.absences li { margin: 0; }

@media (min-width: 40rem) {
  .absences { --t-display: flex; display: flex; gap: 0; }
  .absences li { padding: 0 18px; border-left: 1px solid var(--rule); }
  .absences li:first-child { padding-left: 0; border-left: 0; }
}

/* ── the screenshot rail ──────────────────────────────────────────────── */

/* Full-bleed: the rail has to reach the viewport edges or it does not read as
 * something you can push sideways. */
.bleed {
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding-left: max(22px, calc(50vw - 23rem));
  padding-right: max(22px, calc(50vw - 23rem));
}

.rail {
  display: flex;
  gap: clamp(14px, 2.4vw, 22px);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding: 6px 0 26px;
  margin: 0;
  list-style: none;
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}

.rail::-webkit-scrollbar { height: 8px; }
.rail::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 999px; }

.shot {
  flex: 0 0 auto;
  width: clamp(178px, 46vw, 224px);
  scroll-snap-align: center;
  margin: 0;
}

.shot-frame {
  padding: 5px;
  border-radius: 30px;
  background: var(--bezel);
  box-shadow: var(--lift-sm), inset 0 1px 0 rgba(255, 255, 255, 0.2);
}

.shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 25px;
}

.shot figcaption {
  margin-top: 12px;
  font-size: 0.86rem;
  line-height: 1.4;
  color: var(--text-dim);
}

.shot figcaption b {
  display: block;
  font-weight: 600;
  color: var(--text);
}

/* ── the things a screenshot cannot show ──────────────────────────────── */

/* One grid serves the three-up and the two-up: auto-fit collapses to a single
 * column on a phone without a second breakpoint to keep in sync. */
.grid {
  --t-display: grid;
  display: grid;
  gap: 30px 34px;
  /* 12.5rem, not 15: three tracks plus two gaps have to fit inside `.wrap`'s
   * 46rem or the three-up silently becomes a 2 + 1. */
  grid-template-columns: repeat(auto-fit, minmax(12.5rem, 1fr));
}

.grid > div > :first-child { margin-top: 0; }
.grid > div > p { color: var(--text-dim); }

.grid .count {
  display: block;
  font-size: 2.1rem;
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1;
  color: var(--accent);
  margin-bottom: 9px;
  font-variant-numeric: tabular-nums;
}

/* ── the countdown ────────────────────────────────────────────────────── */

/* The numbers are the content here, not a decorative index: memorisation in
 * this app really does run 114 → 1, and the ramp is the direction of travel. */
.countdown {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 6px clamp(12px, 3.4vw, 30px);
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
  font-variant-numeric: tabular-nums;
}

.countdown li { margin: 0; }

.countdown .n {
  display: block;
  font-size: clamp(1.4rem, 4.2vw, 2.15rem);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.1;
  color: var(--text);
}

.countdown .sn {
  display: block;
  margin-top: 5px;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  color: var(--text-dim);
}

.countdown li:nth-child(1) .n { color: var(--accent); }
.countdown li:nth-child(4) { opacity: 0.66; }
.countdown li:nth-child(5) { opacity: 0.52; }
.countdown li:nth-child(6) { opacity: 0.42; }
.countdown li:nth-child(7) { opacity: 0.34; }
.countdown li:nth-child(8) { opacity: 0.55; }

/* ── cards ────────────────────────────────────────────────────────────── */

.card {
  background: var(--card);
  color: var(--card-text);
  border-radius: 22px;
  padding: 25px 27px;
  margin: 22px 0;
  box-shadow: var(--lift);
}

.card h2, .card h3 { margin-top: 0; }
.card a { color: var(--card-accent); }
.card .meta { color: var(--card-dim); }

.mail {
  display: inline-block;
  margin-top: 2px;
  font-size: 1.12rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* ── FAQ (native disclosure, no script) ───────────────────────────────── */

.faq { margin: 0; }

.faq details {
  border-bottom: 1px solid var(--rule);
}

.faq details:first-of-type { border-top: 1px solid var(--rule); }

.faq summary {
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 17px 2px;
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.008em;
  cursor: pointer;
  list-style: none;
}

.faq summary::-webkit-details-marker { display: none; }

/* A plus that becomes a minus. Drawn from two rules so it needs no glyph and
 * no icon font. */
.faq summary::after {
  content: "";
  flex: 0 0 auto;
  margin-left: auto;
  width: 13px;
  height: 13px;
  align-self: center;
  background:
    linear-gradient(var(--accent), var(--accent)) center/13px 1.5px no-repeat,
    linear-gradient(var(--accent), var(--accent)) center/1.5px 13px no-repeat;
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.faq details[open] summary::after {
  background: linear-gradient(var(--accent), var(--accent)) center/13px 1.5px no-repeat;
  transform: rotate(180deg);
}

.faq summary:hover { color: var(--accent); }

.faq .answer {
  padding: 0 2px 20px;
  color: var(--text-dim);
  max-width: 40rem;
}

.faq .answer p:last-child { margin-bottom: 0; }

/* ── footer ───────────────────────────────────────────────────────────── */

footer {
  margin-top: clamp(56px, 9vw, 84px);
  padding-top: 22px;
  border-top: 1px solid var(--rule);
  font-size: 0.9rem;
  color: var(--text-dim);
}

footer a { color: var(--text-dim); }
footer nav { display: flex; flex-wrap: wrap; gap: 20px; margin-bottom: 12px; }

/* ── reduced motion ───────────────────────────────────────────────────── */

/* Not a blanket kill: switching the hero's animation off with nothing in its
 * place leaves every word unlit and every gloss at opacity 0, i.e. an empty
 * card. It settles on the last word instead — the state the App Store
 * screenshot shows. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .w, .gloss { animation: none !important; }
  .w:last-child {
    background-color: var(--pill);
    color: var(--on-pill);
  }
  .gloss:last-child {
    opacity: 1;
    transform: none;
  }
}
