/* =========================================================================
   BASE — reset, document defaults, primitives shared across components.
   ========================================================================= */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Sticky header must not cover the ayah we scroll to. */
  scroll-padding-top: calc(var(--header-h) + var(--space-6));
}

/* Overscrolling past either end rubber-bands the document, and iOS drags
   `position: fixed` chrome along with it — so a flick at the bottom lifts the
   tab bar off the screen edge. In a browser tab the toolbars mask it; once the
   app is installed there is nothing to mask it, so suppress the bounce there.
   Scoped to the installed app on purpose: browser tabs keep pull-to-refresh.
   `.is-installed` is set from JS because iOS Safari only reports the installed
   state through `navigator.standalone`, not the display-mode media query. */
@media (display-mode: standalone), (display-mode: fullscreen),
       (display-mode: minimal-ui) {
  html,
  body {
    overscroll-behavior-y: none;
  }
}
html.is-installed,
html.is-installed body {
  overscroll-behavior-y: none;
}

body {
  min-height: 100vh; /* fallback for engines without dynamic viewport units */
  min-height: 100dvh;
  font-family: var(--font-ui);
  font-size: var(--text-base);
  line-height: 1.6;
  word-spacing: var(--word-space-ui);
  color: var(--text);
  background-color: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  transition: background-color var(--dur-slow) var(--ease-out),
              color var(--dur-slow) var(--ease-out);
  overflow-wrap: break-word;
}

/* Author-level `display` declarations outrank the UA stylesheet's [hidden]
   rule, so components like .drawer (display:flex) and .modal (display:grid)
   would stay visible while hidden. This restores the attribute's meaning. */
[hidden] {
  display: none !important;
}

img,
svg,
video {
  display: block;
  max-width: 100%;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  /* `font: inherit` does not carry word-spacing, and the UA stylesheet pins it
     to normal on form controls — so control labels would keep the cramped
     space that --word-space-ui exists to widen. */
  word-spacing: inherit;
}

button {
  background: none;
  border: none;
  cursor: pointer;
}

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  list-style: none;
}

h1, h2, h3, h4 {
  font-weight: var(--weight-bold);
  line-height: 1.22;
  letter-spacing: var(--tracking-tight);
}

::selection {
  background: var(--accent-soft-hover);
  color: var(--text);
}

/* ---- Touch feedback ----
   The UA tap highlight is a fixed wash — translucent black on iOS, pale blue
   on Android — that belongs to none of the three themes. On Parchment it
   reads as a smudge, and on Midnight it is a dark rectangle over an already
   dark surface, so the tap barely registers. Suppressing it is inherited, so
   this one declaration covers the document.

   Suppressing it *alone* is the trap: hover does not exist on a finger, so
   every tappable surface would lose its only feedback and the app would feel
   broken rather than clean. Each one carries an explicit `:active` drawn from
   the current theme's palette instead — see the press states in
   components.css, which are what this rule hands over to. */
:root {
  -webkit-tap-highlight-color: transparent;
}

/* ---- No double-tap zoom ----
   Double-tap-to-zoom exists for desktop pages viewed on a phone: tap twice and
   the browser picks a column and zooms to fit it. This layout is already built
   for the viewport, so the gesture has nothing useful to do — it only ever
   fires by accident, and it fires most on the controls that invite repeat
   taps: the size steppers, the Hijri offset, stepping ayah to ayah.

   `manipulation` drops the double-tap gesture and keeps panning and pinch, so
   deliberate zoom still works. That is why this lives here rather than as
   `user-scalable=no` on the viewport tag, which would take pinch away too and
   fail WCAG 1.4.4.

   Allowed behaviours are the intersection of an element's own value with its
   ancestors', so the root declaration is what actually covers the document —
   `touch-action` itself does not inherit, and body still computes to `auto`.
   The second rule is belt and braces for the surfaces a finger actually lands
   on: the intersection is spec'd and confirmed here in Blink, but not in
   WebKit, where it could not be driven from the test harness. */
html {
  touch-action: manipulation;
}
a,
button,
input,
label,
select,
summary,
textarea,
[role='button'],
[tabindex] {
  touch-action: manipulation;
}

/* ---- Focus: visible only for keyboard users ----
   No border-radius here: the outline already follows the element's own
   corners, and setting a radius would reshape pills and cards on focus. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
:focus:not(:focus-visible) {
  outline: none;
}

/* ---- Scrollbars ---- */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: var(--radius-full);
  border: 3px solid var(--bg);
}
::-webkit-scrollbar-thumb:hover {
  background: var(--text-faint);
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* =========================================================================
   Utilities
   ========================================================================= */

.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;
}

.shell {
  width: 100%;
  max-width: var(--shell-max);
  margin-inline: auto;
  padding-inline: var(--space-5);
}

@media (min-width: 768px) {
  .shell {
    padding-inline: var(--space-8);
  }
}

.stack {
  display: flex;
  flex-direction: column;
}

.row {
  display: flex;
  align-items: center;
}

.hidden {
  display: none !important;
}

.arabic {
  font-family: var(--font-arabic);
  direction: rtl;
  text-align: right;
  font-feature-settings: 'liga' 1, 'calt' 1;
}

/* =========================================================================
   Islamic geometric pattern — an 8-point star tessellation, drawn once as a
   data URI and tinted per theme via --pattern-ink. Purely decorative.
   ========================================================================= */

:root {
  /* The tile is authored once here; both the flat and faded variants mask
     against it, so the geometry lives in exactly one place. */
  --pattern-tile: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90' viewBox='0 0 90 90'%3E%3Cg fill='none' stroke='%23000' stroke-width='1.15'%3E%3Cpath d='M45 4 L52.5 22.5 L71 15 L63.5 33.5 L82 41 L63.5 48.5 L71 67 L52.5 59.5 L45 78 L37.5 59.5 L19 67 L26.5 48.5 L8 41 L26.5 33.5 L19 15 L37.5 22.5 Z'/%3E%3Cpath d='M45 20 L57 32 L45 44 L33 32 Z'/%3E%3Ccircle cx='45' cy='41' r='27'/%3E%3Cpath d='M0 41 L8 41 M82 41 L90 41 M45 78 L45 90'/%3E%3C/g%3E%3C/svg%3E");
}

/* The tile's strokes are opaque black, so masking a themed background colour
   through it recolours the pattern per theme with no re-encoding. */
.pattern-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--pattern-opacity);
  background-color: rgb(var(--pattern-ink));
  -webkit-mask-image: var(--pattern-tile);
  mask-image: var(--pattern-tile);
  -webkit-mask-size: 90px 90px;
  mask-size: 90px 90px;
  -webkit-mask-repeat: repeat;
  mask-repeat: repeat;
}

/* Faded variant: intersect the tile with a vertical gradient so the pattern
   dissolves downward behind hero content. */
.pattern-overlay--fade {
  -webkit-mask-image: var(--pattern-tile),
                      linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.4) 55%, transparent 100%);
  mask-image: var(--pattern-tile),
              linear-gradient(180deg, #000 0%, rgba(0, 0, 0, 0.4) 55%, transparent 100%);
  -webkit-mask-size: 90px 90px, 100% 100%;
  mask-size: 90px 90px, 100% 100%;
  -webkit-mask-repeat: repeat, no-repeat;
  mask-repeat: repeat, no-repeat;
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}
