/* ==========================================================================
   Naveed Mobiles — design system
   Light by default, dark via [data-theme="dark"]. Navy primary, one accent.
   Elevation is hairlines, not shadows.
   ========================================================================== */

/* --------------------------------------------------------------- fonts ---
   Design §3.1/§8: Cabinet Grotesk (display), Geist Sans (body), Geist Mono
   (data), Noto Nastaliq Urdu. Subset and SELF-HOSTED — no Google Fonts, no
   build step, one fewer third-party connection on a slow 4G handshake.

   The woff2 files are not in the repo yet. Until they are, the stacks below
   fall back to system faces that hold the design intent (the mono fallbacks
   all support tabular numerals, which is what §3.2 actually depends on).
   See docs/FONTS.md for exact sources and the @font-face block to paste here.
   -------------------------------------------------------------------------- */

:root {
  /* ---------- Brand (sampled from the logo) ---------- */
  --navy:       #252265;
  --navy-deep:  #1A1847;
  --navy-soft:  #4A4790;

  /* !! CONTRAST TRAP — READ BEFORE USING (design §2.1) !!
     --cyan is 3.22:1 on white. It FAILS WCAG AA for body text.
     Use it ONLY for: headings 24px+, icon fills, active-state backgrounds,
     decorative rules, the logo.
     For ANY cyan text at body size, and for ALL links, use --cyan-ink. */
  --cyan:       #049DD8;
  --cyan-ink:   #027AAB;   /* 4.80:1 on white — the one safe for text */
  --cyan-wash:  #E4F4FB;   /* active filter chips, selected state */

  /* ---------- Text ---------- */
  --ink:        #1A1A24;   /* never #000000 */
  --ink-soft:   #55596B;
  /* Darkened from the design's #8A8FA3, which measures 2.9:1 and so fails the
     4.5:1 floor §10 itself mandates. It carries captions and hints ("Choose an
     option to continue") — meaningful text, not decoration — so the floor wins
     over the swatch. Measured: 4.69:1 on --surface, 5.20:1 on white. */
  --ink-faint:  #686C7E;

  /* ---------- Surfaces ----------
     A cool neutral, NOT the logo's cream #F9F3E2. Cyan on that cream is
     2.90:1, failing even the large-text threshold — it would make half the
     brand palette unusable on the shop's own background. */
  --surface:        #F2F3F7;
  --surface-raised: #FFFFFF;
  --hairline:       #DDDFE7;

  /* ---------- Status: SEMANTIC ONLY, never decorative ----------
     The moment amber appears as decoration, the trust position collapses. */
  --status-ok:  #17705E;
  --status-low: #9C5A0C;
  --status-out: #96303A;

  /* ---------- Type ---------- */
  --font-display: "Cabinet Grotesk", "Geist Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body:    "Geist Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono:    "Geist Mono", ui-monospace, "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;
  --font-urdu:    "Noto Nastaliq Urdu", serif;

  /* ---------- Shape: one radius scale, everywhere ---------- */
  --r-sm: 6px;    /* inputs, chips, badges */
  --r-md: 10px;   /* cards, buttons */
  --r-lg: 16px;   /* sheets, modals, hero tiles */

  --container: 1280px;

  /* ---------- Motion: intensity 4 (design §7) ----------
     Feedback and hierarchy, never spectacle. Heavy motion janks on mid-range
     Android over 4G, and jank reads as cheap, which reads as fake. */
  --ease-out:  cubic-bezier(0.16, 1, 0.3, 1);
  --dur-fast:  150ms;   /* filter cross-fade */
  --dur-base:  200ms;   /* cart badge, card hover */
  --dur-slow:  320ms;   /* card hover elevation */
  --rise:      24px;    /* section entry */

  /* Real shadows are reserved for genuinely floating things: the mobile filter
     sheet, the cart drawer, dropdowns. Everything else separates by hairline. */
  --shadow-float: 0 12px 32px rgba(26, 24, 71, 0.16);

  /* ---------- Glass (design request) ----------
     Frosted surfaces, applied ONLY to things that genuinely float over content:
     the sticky header, the filter bar, dropdown panels, the mobile filter
     sheet. Deliberately NOT applied to product cards — a card sits on the page
     rather than over it, and blurring 24 of them on a category page is real
     GPU cost on the mid-range Android this design targets, for no depth cue.

     The tint is opaque enough that text contrast is carried by the tint itself,
     never by the blur. That matters: `backdrop-filter` is unsupported or
     disabled often enough (Firefox with the pref off, low-power modes, older
     WebViews) that anything relying on it for legibility fails silently. Check
     contrast against --glass-*-solid, which is what those browsers actually get. */
  --glass-bg:        rgba(255, 255, 255, 0.72);
  --glass-bg-solid:  #F7F8FB;              /* the no-backdrop-filter fallback */
  --glass-border:    rgba(255, 255, 255, 0.55);
  --glass-blur:      blur(14px) saturate(150%);
  /* On the navy header/filter bar the glass is a dark tint, not a light one. */
  --glass-navy:      rgba(26, 24, 71, 0.72);
  --glass-navy-solid:#1F1D52;

  /* ---------- Fixed light header (design request) ----------
     The top nav bar is white regardless of theme — deliberately NOT
     theme-variable like --navy/--surface/--ink, which all swap for dark
     theme. The logo art is navy-on-transparent and would go illegible
     against those tokens' dark-theme values (near-black), so this stays
     defined ONLY here in :root and is never overridden under
     [data-theme="dark"]. A dark-mode visitor gets a white top bar and a
     dark-themed page below it — intentional, not a bug. */
  --header-bg-solid: #FFFFFF;
  --header-bg:       rgba(255, 255, 255, 0.86);
  --header-border:   rgba(26, 24, 71, 0.12);
  --header-hover:    rgba(26, 24, 71, 0.06);
  --header-ink:      #1A1847;
  --header-ink-soft: rgba(26, 24, 71, 0.66);

  color-scheme: light;
}

[data-theme="dark"] {
  --navy:       #3F3B93;
  --navy-deep:  #16142E;
  --navy-soft:  #6663B8;

  --cyan:       #03AFF6;
  --cyan-ink:   #4FC4FA;   /* 7.21:1 on --surface */
  --cyan-wash:  #12314A;

  --ink:        #ECEDF3;
  --ink-soft:   #A5A9BA;
  /* Lightened from the design's #6E7285, which measures 3.87:1 on the dark
     surface. This is 6.1:1. Same reasoning as the light theme above. */
  --ink-faint:  #969BB0;

  --surface:        #121320;
  --surface-raised: #1B1D2C;
  --hairline:       #2C2F42;

  --status-ok:  #3FA98F;
  --status-low: #D08A2E;
  --status-out: #D4646E;

  --shadow-float: 0 12px 32px rgba(0, 0, 0, 0.55);

  --glass-bg:        rgba(27, 29, 44, 0.72);
  --glass-bg-solid:  #1B1D2C;
  --glass-border:    rgba(255, 255, 255, 0.10);
  --glass-navy:      rgba(15, 14, 34, 0.76);
  --glass-navy-solid:#16142E;

  color-scheme: dark;
}

/* ---------------------------------------------------------------- glass --
   One utility, used by the header, filter bar, dropdown panels and the mobile
   sheet. Solid first, glass only where the browser actually supports it — so
   a browser without backdrop-filter gets a perfectly legible opaque surface
   rather than transparent text over whatever happens to scroll underneath. */
.glass {
  background: var(--glass-bg-solid);
  border: 1px solid var(--glass-border);
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass {
    background: var(--glass-bg);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
  }
}

/* The navy variant, for surfaces sitting on the brand colour. */
.glass--navy { background: var(--glass-navy-solid); }
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass--navy {
    background: var(--glass-navy);
    -webkit-backdrop-filter: var(--glass-blur);
    backdrop-filter: var(--glass-blur);
  }
}

/* ---------------------------------------------------------------- reset -- */

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

html {
  /* 360px is the design width, not 375 — budget Androids are narrower. */
  -webkit-text-size-adjust: 100%;
  /* The flat colour lives on the ROOT, not on body. body stays transparent so
     the background texture below can sit between the two on a negative
     z-index without the classic trap: a z-index:-1 pseudo-element on an
     element that itself paints an opaque background ends up hidden behind
     that element's own background layer, not above it. */
  background: var(--surface);
}

body {
  position: relative;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;   /* the page body must never scroll horizontally */
}

/* ---------------------------------------------------- background texture --
   Faint accessory line-art (design request, not in the original spec): says
   what the shop sells without a word or a stock photo. Fixed, not scrolling,
   so it reads as paper texture rather than parallax — §7 bans parallax.
   pointer-events: none so it can never intercept a click or a tap. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* Two pre-coloured files, not one + currentColor: a background-image SVG is
     fetched as its own isolated document, so currentColor inside it would
     resolve against the SVG's own root, not this page — it would render as
     plain black in both themes and never respond to the toggle. See the
     comment in bg-accessories.svg for the full reasoning. */
  background-image: url("/assets/img/bg-accessories.svg");
  background-repeat: repeat;
  background-size: 440px 440px;
  opacity: 0.035;
}
[data-theme="dark"] body::before {
  background-image: url("/assets/img/bg-accessories-dark.svg");
  /* A dark surface eats more of a faint pattern than a light one, so dark
     gets a slightly higher opacity to read as equally present in both themes. */
  opacity: 0.05;
}
@media (prefers-reduced-motion: reduce) {
  /* Not itself animated, but fixed backgrounds seesaw with the page rather
     than pausing on some Android WebViews; reduced motion is a proxy for
     that class of device, so pin it to scroll with the page there instead. */
  body::before { position: absolute; }
}

/* Kill the 300ms tap delay and pick the tap flash deliberately. */
a, button, input, select, textarea, summary, label { touch-action: manipulation; }
a, button { -webkit-tap-highlight-color: rgba(4, 157, 216, 0.20); }

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

a { color: var(--cyan-ink); text-decoration-thickness: 1px; text-underline-offset: 2px; }

button, input, select, textarea { font: inherit; color: inherit; }

/* Visible keyboard focus everywhere. Never outline: none. */
:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
  border-radius: 2px;
}

/* --------------------------------------------------------------- type --- */

h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 700; line-height: 1.1; }

h1 { font-size: clamp(1.75rem, 1.2rem + 2.4vw, 3.5rem); letter-spacing: -0.02em; }
h2 { font-size: clamp(1.5rem, 1.15rem + 1.5vw, 2.25rem); letter-spacing: -0.015em; }
h3 { font-size: clamp(1.15rem, 1rem + 0.6vw, 1.5rem);   letter-spacing: -0.01em; }

p { max-width: 65ch; }

/* THE SIGNATURE (design §3.2): every number on this site is mono with tabular
   figures, so a column of twenty prices aligns and can be scanned at a glance.
   That alignment is the usability win; it is also what makes the shop read as
   a spec sheet rather than a shop window. */
.num, .price, .spec-strip, .mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.spec-strip {
  font-size: 0.8125rem;
  color: var(--ink-soft);
  letter-spacing: 0.01em;
}

/* Urdu descends heavily and needs the room. Loaded only on routes that use it. */
.ur {
  font-family: var(--font-urdu);
  direction: rtl;
  line-height: 2;
}

.u-muted  { color: var(--ink-soft); }
.u-faint  { color: var(--ink-faint); }

/* ------------------------------------------------------------- layout --- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 1rem;
}
@media (min-width: 768px) { .container { padding-inline: 2rem; } }

.section { padding-block: clamp(2.5rem, 1.5rem + 4vw, 5rem); }

/* Wide content scrolls inside its own container, never the page. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* -------------------------------------------------------------- pieces -- */

.card {
  background: var(--surface-raised);
  border: 1px solid var(--hairline);
  border-radius: var(--r-md);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  /* 44px minimum tap target, including chips and variant selectors. */
  min-height: 44px;
  padding: 0.625rem 1.25rem;
  border: 1px solid transparent;
  border-radius: var(--r-md);
  background: var(--navy);
  color: #FFFFFF;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-out);
}
.btn:hover  { background: var(--navy-soft); }
.btn:active { transform: scale(0.98); }

.btn--quiet {
  background: transparent;
  color: var(--ink);
  border-color: var(--hairline);
}
.btn--quiet:hover { background: var(--cyan-wash); }

.chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.375rem 0.875rem;
  border: 1px solid var(--hairline);
  border-radius: var(--r-sm);
  background: var(--surface-raised);
  cursor: pointer;
}
.chip[aria-pressed="true"], .chip.is-active {
  background: var(--cyan-wash);
  border-color: var(--cyan);
}

/* Stock line. Colour is semantic here and nowhere else. */
.stock       { font-size: 0.875rem; font-weight: 600; }
.stock--ok   { color: var(--status-ok); }
.stock--low  { color: var(--status-low); }
.stock--out  { color: var(--status-out); }

/* -------------------------------------------------------------- motion -- */

.reveal {
  opacity: 0;
  transform: translateY(var(--rise));
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.reveal.is-in { opacity: 1; transform: none; }

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

/* ------------------------------------------------------------------ a11y */

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

.skip-link {
  position: absolute;
  left: 1rem;
  top: -3rem;
  z-index: 100;
  padding: 0.5rem 1rem;
  background: var(--navy);
  color: #FFFFFF;
  border-radius: var(--r-sm);
  transition: top var(--dur-base) var(--ease-out);
}
.skip-link:focus { top: 1rem; }
