/* ============================================================================
   Mereketoi.kz — Design Tokens : Colors + Type
   Той / ивент қызметтері маркетплейсі. Қазақша (default) + Орысша.
   Source of truth for the platform palette (front / app / admin / mobile).
   Branding is code-controlled — never editable from the admin panel.
   ============================================================================ */

/* ---- Fonts ------------------------------------------------------------------
   ONEST, self-hosted (owner 2026-09-05: «қазір аппта басқа шрифт, соны қолдан»).

   This REOPENS the 2026-08-01 "no webfont" request — deliberately, and in the shape
   the 2026-09-04 changelog pre-described: "matching it is a separate, reviewable
   change to public/assets/css/tokens.css". Why it was reopened: --font-system draws
   SF Pro on iOS, Roboto on Android and Segoe UI on Windows, so the site was three
   products in three screenshots. The mobile app moved to Onest on 2026-09-04; this
   is the web catching up, and the two surfaces match again.

   Onest is the only face vetted for this product. Quicksand (dropped 2026-07-17),
   Nunito (2026-08-01) and Manrope (2026-09-04 — the face the reference screens use,
   and what was asked for) were all refused for losing Kazakh letters mid-word.
   Verified against the cmap of the actual .ttf, never against a subset list on a web
   page, which is exactly what Manrope gets wrong about itself:
     Ә ә Ғ ғ Қ қ Ң ң Ө ө Ұ ұ Ү ү Һ һ І і · ₸ № « » — …   all present.

   These are Google own woff2 subsets of the VARIABLE face (wght 400..800), fetched
   once at authoring time and served from OUR origin — so the
   <link rel="stylesheet" ...googleapis> tags deleted on 2026-08-01 stay deleted and
   nothing is requested from Google at page load. 88 KB on disk, 60 KB preloaded
   (partials/font_preload.php), the rest fetched on demand.

   The `v11` in each filename is the cache-bust: asset() only appends ?v= to .css and
   .js, and nginx sets `expires 30d` on woff2 — replacing a file under the same name
   would serve the stale one for a month. Bump the version, never overwrite.

   Which subset carries what:
     cyrillic-ext  U+0460-052F  -> Ә Ғ Қ Ң Ү Ө Һ
     cyrillic      U+0400-045F  -> І і, plus U+04B0-04B1 (Ұ ұ) and U+2116 (№)
     latin-ext     U+20AD-20C0  -> ₸ (U+20B8), the ONLY subset that carries it
     latin         U+0000-00FF  -> digits, latin, basic punctuation

   font-display: swap, not optional. The 2026-07 FOUT fix chose `optional` for a
   THIRD-PARTY, non-preloaded font behind two round trips, which routinely lost the
   100ms race. This one is same-origin and preloaded, so it normally lands before
   first paint; and `optional` would render the system font for the WHOLE session on
   a slow first load, hiding the new face from exactly the first-time visitor the
   landing page exists for. CLS risk is small: app.css pins a unitless line-height on
   body, so almost nothing here derives its line box from font metrics.

   Licence: OFL 1.1 — public/assets/fonts/Onest-OFL.txt (must travel with the font).
   ---------------------------------------------------------------------------- */
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400 800;          /* one variable file spans the whole --weight-* scale */
  font-display: swap;
  src: url('../fonts/onest-v11-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/onest-v11-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/onest-v11-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/onest-v11-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* ============= BRAND PALETTE (navy — 2026-06; gold accent removed 2026-06-25) ===
     Logo-driven: deep navy as the lead. The former warm-gold accent was removed
     (owner request) and replaced by a deep navy so the brand reads as one cohesive
     blue/navy. Token NAMES are kept (secondary/accent/gold) so no call-site breaks —
     only the values changed from gold to navy. */
  --color-primary:          #000099;  /* Mereketoi blue — main CTA, active tabs, links, primary text */
  --color-on-primary:       #FFFFFF;  /* foreground on a filled primary control */
  --color-primary-hover:    #1A1AAD;  /* blue pressed/hover (slightly lighter) */
  --color-primary-soft:     #E5E5F5;  /* blue tint — chips, highlight backgrounds */
  --color-primary-soft2:    #EDEDF7;  /* soft blue — hero gradient, active card bg, chip hover */
  --color-violet-soft:      #E6E6F2;  /* soft blue — icon bubbles, image placeholders */
  --color-navy:             #000099;  /* deep blue — footer, hero overlay, dark sections */
  --color-secondary:        #0B1F4D;  /* deep navy — secondary/accent: VIP, badges, highlights (was gold) */
  --color-secondary-hover:  #08183A;  /* deep navy pressed (darker) */
  --color-secondary-soft:   #E8EAF3;  /* soft navy tint — chips, accent backgrounds */
  --color-accent:           #0B1F4D;  /* deep navy — small highlights, selected filters, special chips (was gold) */
  --color-accent-soft:      #E8EAF3;
  --color-gold:             #0B1F4D;  /* legacy alias — now deep navy (no longer gold), kept for back-compat */
  --color-gold-soft:        #E8EAF3;

  /* ====================== SURFACES & TEXT ================================== */
  --color-background:       #FFFFFF;  /* page background — white (cards differ by border) */
  --color-surface:          #FFFFFF;  /* cards, modals, forms, dropdowns */
  --color-surface-muted:    #F4F5F6;  /* filter panels, secondary sections, skeleton base */
  --color-text:             #0F172A;  /* primary readable text — near-black (owner 2026-08-01:
                                         body copy is BLACK in light mode, not brand blue;
                                         blue stays on links/CTAs via --color-primary) */
  --color-text-strong:      #0F172A;  /* near-black headings/values (was hardcoded slate-900) */
  --color-text-body:        #334155;  /* neutral body text (was hardcoded slate-700) */
  --color-text-muted:       #5B6573;  /* helper text, labels, descriptions */
  --color-text-faint:       #8B93A1;  /* timestamps, disabled, meta */
  --color-border:           #D3D5D6;  /* inputs, cards, dividers (tuned to grey bg) */
  --color-border-strong:    #BDC0C2;  /* hover borders, emphasized dividers */

  /* ====================== SEMANTIC STATES ================================= */
  --color-success:          #10B981;  /* active / available */
  --color-success-soft:     #E7F8F1;
  --color-warning:          #F59E0B;  /* review / report attention */
  --color-warning-soft:     #FEF3E2;
  --color-error:            #EF4444;  /* hidden / blocked / destructive */
  --color-error-solid:      #B91C1C;  /* small badges with white text */
  --color-error-soft:       #FDECEC;
  --color-info:             #0EA5E9;  /* neutral informational */
  --color-info-soft:        #E5F6FD;

  /* ====================== TYPOGRAPHY ====================================== */
  /* Onest everywhere (2026-09-05) — the @font-face block at the top of this file
     carries the why and the glyph evidence. --font-system stays inside --font-onest
     as the fallback, so a blocked font request degrades to exactly what the site
     rendered before this change rather than to a browser default. */
  --font-system: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
                 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
  --font-onest:   'Onest', var(--font-system);
  --font-display: var(--font-onest);
  --font-body:    var(--font-onest);
  /* Onest ships no italic; font-style:italic synthesises an oblique. Nothing reads
     this token today (grep: tokens.css only) — kept so no call-site can break. */
  --font-display-italic: var(--font-onest);

  /* Type scale (px) — H1 24–32 / H2 20 / body 16 / small 14 per spec */
  --text-display:  40px;   /* hero headlines */
  --text-h1:       30px;
  --text-h2:       22px;
  --text-h3:       18px;
  --text-body-lg:  17px;
  --text-body:     16px;
  --text-sm:       14px;
  --text-xs:       12.5px;

  --weight-regular: 400;
  --weight-medium:  500;
  --weight-semibold:600;
  --weight-bold:    700;
  --weight-black:   800;

  /* Line-height ≥ 1.5 for body (Kazakh runs long) */
  --leading-tight:  1.18;  /* display / headings */
  --leading-snug:   1.32;
  --leading-normal: 1.55;  /* body copy */

  --tracking-tight: -0.02em;
  --tracking-wide:  0.01em;

  /* ---- Fluid editorial steps (2026-09-05) — marketing surfaces only ---------
     ADDED, never changed: the fixed --text-* scale above is untouched because ~40
     views plus the whole admin panel consume it. Nothing that exists today reads
     the tokens below, so the ripple of adding them is exactly zero. Onest is a
     variable face, so --weight-black here is a real instance, not a synthetic bold.
     html{font-size:16px} is pinned in app.css, so the rem maths is stable.       */
  --text-display-xl: clamp(2.5rem,    1.30rem + 6.00vw, 4.75rem);  /*  40 -> 76 */
  --text-display-lg: clamp(1.875rem,  1.10rem + 3.90vw, 3.25rem);  /*  30 -> 52 */
  --text-display-md: clamp(1.5rem,    1.10rem + 2.00vw, 2.25rem);  /*  24 -> 36 */
  --text-lead:       clamp(1.0625rem, 0.98rem + 0.42vw, 1.25rem);  /*  17 -> 20 */

  --leading-display:  1.04;      /* only for --text-display-xl */
  --tracking-display: -0.035em;  /* -2.7px at 76px; Onest counters carry it */
  --tracking-tighter: -0.03em;
  --tracking-eyebrow: 0.16em;
  /* No negative tracking below --text-h3 — Kazakh stacked diacritics (Ә Ө Ү) muddy
     up fast once the sidebearings are pulled in at small sizes. */

  /* ====================== RADII / ELEVATION / SPACING ===================== */
  --radius-xs:  6px;
  --radius-sm:  10px;
  --radius-md:  14px;   /* default card radius */
  --radius-lg:  20px;
  --radius-xl:  28px;
  --radius-pill: 999px;

  --shadow-xs:  0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-sm:  0 1px 3px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
  --shadow-md:  0 4px 12px rgba(15, 23, 42, 0.07), 0 2px 4px rgba(15, 23, 42, 0.04);
  --shadow-lg:  0 12px 28px rgba(15, 23, 42, 0.10), 0 4px 10px rgba(15, 23, 42, 0.05);
  --shadow-primary: 0 6px 18px rgba(0, 0, 153, 0.28);
  --ring-focus: 0 0 0 3px color-mix(in srgb, var(--color-primary) 38%, transparent);
  --ring-focus-blue: 0 0 0 3px color-mix(in srgb, var(--color-secondary) 30%, transparent);

  /* 4px spacing grid */
  --space-1: 4px;  --space-2: 8px;  --space-3: 12px; --space-4: 16px;
  --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px;
  --space-12: 48px; --space-16: 64px; --space-20: 80px;

  --container: 1200px;
  --transition: 160ms cubic-bezier(0.4, 0, 0.2, 1);

  color-scheme: light;
}

/* ============================================================================
   DARK THEME (owner request 2026-07-17) — variable overrides only.
   `data-theme` is stamped on <html> by partials/theme_boot.php BEFORE first
   paint on EVERY page: stored preference 'light'|'dark', or the OS scheme when
   the preference is 'system' (the default — «По умолчанию»).
   ============================================================================ */
html[data-theme='dark'] {
  color-scheme: dark;

  /* Brand — the deep blues flip to lighter indigos so CTAs/links stay readable */
  --color-primary:          #6C6CFF;
  --color-on-primary:       #0B0F1A;
  --color-primary-hover:    #8585FF;
  --color-primary-soft:     #1B1B3A;
  --color-primary-soft2:    #16162E;
  --color-violet-soft:      #1B1B33;
  --color-navy:             #05051F;
  --color-secondary:        #9DB1E8;
  --color-secondary-hover:  #B6C5F0;
  --color-secondary-soft:   #17203A;
  --color-accent:           #9DB1E8;
  --color-accent-soft:      #17203A;
  --color-gold:             #9DB1E8;
  --color-gold-soft:        #17203A;

  /* Surfaces & text */
  --color-background:       #0B0F1A;
  --color-surface:          #121828;
  --color-surface-muted:    #1A2133;
  /* Owner request 2026-07-17: ALL text is WHITE in dark mode (muted/faint stay
     near-white so hierarchy survives without going grey). */
  --color-text:             #FFFFFF;
  --color-text-strong:      #FFFFFF;
  --color-text-body:        #FFFFFF;
  --color-text-muted:       #E3E7EF;
  --color-text-faint:       #C6CDD9;
  --color-border:           #28324A;
  --color-border-strong:    #394562;

  /* Semantic softs — dark-tinted so text keeps contrast */
  --color-success-soft:     #0E2B22;
  --color-warning-soft:     #33250C;
  --color-error-soft:       #331414;
  --color-info-soft:        #0C2836;

  /* Shadows read as depth on dark via stronger black */
  --shadow-xs:  0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-sm:  0 1px 3px rgba(0, 0, 0, 0.40), 0 1px 2px rgba(0, 0, 0, 0.30);
  --shadow-md:  0 4px 12px rgba(0, 0, 0, 0.45), 0 2px 4px rgba(0, 0, 0, 0.30);
  --shadow-lg:  0 12px 28px rgba(0, 0, 0, 0.55), 0 4px 10px rgba(0, 0, 0, 0.35);
  --shadow-primary: 0 6px 18px rgba(108, 108, 255, 0.30);
}

/* ============================================================================
   SEMANTIC ELEMENT STYLES — opt-in via .ds-scope so kits can apply selectively
   ============================================================================ */
.ds-scope {
  font-family: var(--font-body);
  color: var(--color-text);
  background: var(--color-background);
  font-size: var(--text-body);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.ds-display, h1.ds, .ds-h1, .ds-h2, .ds-h3 { font-family: var(--font-display); }

.ds-display { font-size: var(--text-display); font-weight: var(--weight-black);
  line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); }
.ds-h1 { font-size: var(--text-h1); font-weight: var(--weight-bold);
  line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); }
.ds-h2 { font-size: var(--text-h2); font-weight: var(--weight-bold); line-height: var(--leading-snug); }
.ds-h3 { font-size: var(--text-h3); font-weight: var(--weight-semibold); line-height: var(--leading-snug); }
.ds-body-lg { font-size: var(--text-body-lg); line-height: var(--leading-normal); }
.ds-body { font-size: var(--text-body); line-height: var(--leading-normal); }
.ds-sm { font-size: var(--text-sm); line-height: var(--leading-normal); }
.ds-xs { font-size: var(--text-xs); line-height: var(--leading-snug); }
.ds-muted { color: var(--color-text-muted); }
.ds-eyebrow { font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-text-muted); }

/* ============================================================================
   SIGNATURE LOADER — "Mereketoi Ribbon Loader" (token-driven, CSS only)
   ============================================================================ */
.mereketoi-loader {
  --loader-bg:   var(--color-surface-muted);
  --loader-line: var(--color-primary);
  --loader-dot:  var(--color-secondary);
  --loader-glow: color-mix(in srgb, var(--color-accent) 35%, transparent);
  position: relative; width: 168px; height: 10px; border-radius: var(--radius-pill);
  background: var(--loader-bg); overflow: hidden;
}
.mereketoi-loader::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(90deg, transparent, var(--loader-line), transparent);
  transform: translateX(-100%); animation: mrkt-sweep 1.25s ease-in-out infinite;
}
.mereketoi-loader::after {
  content: ""; position: absolute; top: 50%; left: 0; width: 12px; height: 12px;
  border-radius: 50%; background: var(--loader-dot);
  box-shadow: 0 0 12px 4px var(--loader-glow); transform: translate(-50%, -50%);
  animation: mrkt-dot 1.25s ease-in-out infinite;
}
@keyframes mrkt-sweep { 0% { transform: translateX(-100%);} 100% { transform: translateX(100%);} }
@keyframes mrkt-dot   { 0% { left: 4%;} 50% { left: 96%;} 100% { left: 4%;} }

@media (prefers-reduced-motion: reduce) {
  .mereketoi-loader::before, .mereketoi-loader::after { animation: none; }
}
