/* ─────────────────────────────────────────────────────────────────────────────
 * production-overrides.css
 *
 * DO NOT DELETE THIS FILE. It is not leftover experiment CSS — without it every
 * page renders pinned at 1440px and the entire site is broken on mobile.
 *
 * WHY IT EXISTS
 * The design was authored inside the Claude Design canvas, where all eleven screens
 * were tiles in one scrolling document. Each screen is a `.vb-frame`, declared in
 * site.css as roughly:
 *
 *     .vb-frame { width: var(--vb-frame-width, 1440px); container-type: inline-size; }
 *
 * On the canvas, the Tweaks panel's "Viewport" control simulated responsiveness by
 * writing `--vb-frame-width` onto `document.documentElement` — that is what made all
 * eleven frames resize in lockstep so their descendants could pivot layout through
 * `@container` queries.
 *
 * The conversion deletes the Tweaks panel (brief §3.1), which orphans that variable.
 * Every `.vb-frame` would then fall back to the literal `1440px`, and — worse than the
 * fixed width alone — each frame's container-query context would measure 1440px
 * regardless of the real viewport. Every `@container` breakpoint in the design would
 * evaluate against the wrong box. The site would look correct on a desktop monitor and
 * be broken for the mobile-first Turkish market it is built for.
 *
 * Setting the variable here restores the intent: the frame fills its parent, so the
 * container-query context tracks the real viewport.
 *
 * WHY 100% AND NOT 100vw
 * `100vw` includes the scrollbar gutter, which produces horizontal overflow on every
 * desktop browser that reserves scrollbar space. `100%` resolves against the frame's
 * parent and does not.
 *
 * WHY A SEPARATE FILE
 * site.css, tokens.css and animations.css ship byte-identical from the design project
 * (brief §3.3, skills.md §4 — "inputs, not drafts"). Editing site.css to fix this would
 * put a conversion concern inside a design artefact and break the byte-identity check.
 * Aren authorised exactly one override file for this on 2026-08-17.
 *
 * This file must load AFTER site.css.
 * ───────────────────────────────────────────────────────────────────────────── */

:root {
  --vb-frame-width: 100%;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * DOCUMENT RESET — restores the one production-relevant line from the design's
 * own HTML template.
 *
 * The Claude Design template opened with:
 *
 *     html, body { margin: 0; padding: 0; height: 100%;
 *                  background: #2a261b; overflow: hidden; }
 *
 * That block was deliberately not carried over, because most of it is canvas
 * chrome: `overflow: hidden` would kill page scrolling, `#2a261b` is the dark
 * backdrop the frames floated on, and `height: 100%` belongs to the canvas app
 * shell. None of that is production.
 *
 * But `margin: 0` is, and dropping it with the rest left the browser default
 * `body { margin: 8px }` in place. Every full-bleed section — topbar, hero,
 * bands, footer — was inset 8px on all four sides, so sections the design
 * intends to run edge-to-edge stopped 8px short of the viewport. Subtle against
 * a cream background, wrong on every page, and it compounds at the bleed edges
 * where the hero video and band fills are supposed to meet the screen.
 *
 * Only the reset is restored here. The canvas-only declarations stay dropped.
 * ───────────────────────────────────────────────────────────────────────────── */

html,
body {
  margin: 0;
  padding: 0;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * MOBILE NAV DRAWER — restore the clip the canvas frame chrome used to provide
 *
 * SYMPTOM (measured, 375px viewport, every route)
 *   document.documentElement.clientWidth  375
 *   document.documentElement.scrollWidth  690
 *   .vb-drawer  x=375  width=315  right=690
 * On a real phone the layout viewport then has to fit 690px, so the browser
 * zooms out to ~54%. Three symptoms that look unrelated are all this one bug:
 * the drawer appears permanently parked open beside the page; tapping the
 * hamburger slides that SAME element in and reads as a second drawer; and the
 * topbar brand looks mis-sized and off-centre because it is correctly centred
 * in a 375px topbar being displayed at 690px.
 *
 * CAUSE
 * The drawer parks itself off-screen with `transform: translateX(100%)`
 * (site.css `.vb-drawer`). Transformed overflow still contributes to the
 * document's scrollable overflow area, so "off-screen" only works if something
 * clips it. On the canvas that something was `.vb-frame-shell { overflow: hidden }`
 * — part of the fake browser-window chrome — and the conversion correctly
 * dropped the shell along with the rest of the canvas furniture. Nothing
 * replaced the clip. Same root pattern as `--vb-frame-width`: a thing that was
 * positioned relative to "the frame" was fine when the frame was a tile on a
 * canvas, and is wrong now that the frame IS the page.
 *
 * WHY THE CLIP GOES HERE AND NOT ON .vb-frame
 * `.vb-drawer-backdrop` is `position: absolute; inset: 0` inside `.vb-frame`
 * (`position: relative`), so it is already exactly coincident with the frame box
 * AND it is already the drawer's containing block. Clipping here cannot change
 * which element establishes the drawer's containing block, which is what made
 * `.vb-frame { overflow-x: clip }` fail — that attempt stopped the drawer
 * opening at all, with its layout x stuck at 375 even under
 * `transform: translateX(0) !important`.
 *
 * It also keeps the clip away from every ancestor of page content, which is the
 * other constraint: an `overflow` value on an ancestor of a `position: sticky`
 * element breaks the sticking. `/hakkimizda/`'s sidebar is sticky, and it is
 * NOT inside the backdrop, so it is untouched. (`clip` is used rather than
 * `hidden` anyway — `clip` does not create a scroll container.)
 *
 * `overflow-x` rather than `overflow`, so the vertical axis stays `visible` and
 * the drawer's `-8px 0 24px` box-shadow is not boxed in. x is the only axis
 * that overflows: the drawer is `top: 0; bottom: 0`.
 *
 * WHAT THIS DELIBERATELY DOES NOT DO
 * The closed drawer stays laid out at x = viewport width. It is not
 * `display: none`d and not moved out of flow: the open/close transition is a
 * transform transition on a box that must already be in the right place, and
 * `prefers-reduced-motion` collapses that transition's duration (animations.css)
 * rather than removing it, so the box has to exist in both cases.
 *
 * No global `html { overflow-x: clip }` safety net either. That would hide the
 * next overflow bug instead of surfacing it, and this file exists because the
 * last three were found by measuring, not by masking.
 * ───────────────────────────────────────────────────────────────────────────── */

.vb-drawer-backdrop {
  overflow-x: clip;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * SSR INLINE-STYLE SERIALISATION — re-target the design's own mobile rules
 *
 * site.css collapses several desktop grids on mobile by matching the element's
 * inline style as a substring, e.g.
 *
 *     .vb-band.cream > div[style*="grid-template-columns: 1fr 1fr"] { … }
 *
 * On the canvas that matched, because the canvas rendered the JSX in the browser
 * and React set styles through the CSSOM — the style attribute then serialises
 * with a space after each colon: `grid-template-columns: 1fr 1fr`.
 *
 * Next's static export renders the same JSX on the server, where React writes
 * the style attribute as a compact string with NO space after the colon:
 *
 *     style="display:grid;grid-template-columns:1fr 1fr;gap:32px"
 *
 * Every space-bearing `[style*=…]` selector in site.css therefore matches zero
 * elements in production, and the mobile layouts they encode silently never
 * apply. Verified in the browser by walking document.styleSheets and running
 * each rule's own selectorText through querySelectorAll across all 11 routes.
 *
 * This is only true of server-rendered markup. The modals are client-rendered,
 * so their inline styles DO carry spaces and `.vb-modal [style*="…: …"]` in
 * site.css still matches — confirmed by opening the merchant modal at 375px.
 * That is why the rules below are additive: both spellings are listed, the
 * design's originals are left alone, and nothing here changes a value the
 * design did not already declare at this breakpoint.
 *
 * Only the two that produce horizontal overflow are restored. The remaining
 * dead rules are reported rather than fixed — see the note at the end of the
 * file.
 * ───────────────────────────────────────────────────────────────────────────── */

@container vbframe (max-width: 767px) {
  /* site.css:1047 "BAND B 2-col → stack; merchant flow below consumer flow".
     Measured before: the 1fr 1fr track sizing blew out to 255.9px + 32px + 222px
     inside a 335px content box, pushing the second card to right=530 at 375px. */
  .vb-band.cream > div[style*="grid-template-columns:1fr 1fr"],
  .vb-band.cream > div[style*="grid-template-columns: 1fr 1fr"] {
    grid-template-columns: 1fr !important;
    gap: 20px !important;
  }

  /* site.css:1234 "S7 Hakkımızda — 2-col editorial + sticky sidebar collapses to
     single column". Measured before: the fixed 320px second track started at
     x=395 on a 375px viewport, right=715.
     Scoped by the inline style rather than by
     `[data-screen-label="07 Hakkımızda"]` on purpose — that attribute now sits
     ON `.vb-frame` rather than on a child of it, so the design's descendant
     combinator `.vb-frame [data-screen-label=…]` matches nothing either. The
     `1fr 320px` track list is unique to this screen, and it is pure ASCII. */
  .vb-frame [style*="grid-template-columns:1fr 320px"],
  .vb-frame [style*="grid-template-columns: 1fr 320px"] {
    grid-template-columns: 1fr !important;
    gap: 32px !important;
  }
}

/* ─────────────────────────────────────────────────────────────────────────────
 * HERO ILLUSTRATION STAGE — re-target the design's own responsive sizes
 *
 * animations.css sizes the stage `480px × 480px`. site.css shrinks it for small
 * screens through `.vb-hero .hero-art .vb-hero-art-stage` — a selector that
 * matches nothing, because the component renders a single
 * `<div class="vb-hero-art">` and there is no `.hero-art` element anywhere.
 * (Confirmed against the immutable import baseline,
 * design/screens/wireframes/hero/_import_2026-08-17/src/anim.jsx:238 — the
 * class was already `vb-hero-art` there, so these rules were dead on the canvas
 * too. The whole `.vb-hero .hero-art` family is stale: `.logo-wrap`, `img`,
 * `img.vb-hero-star` and both stage sizes.)
 *
 * The one size that does land is `@container vbframe (max-width: 414px)`
 * `.vb-hero-art .vb-hero-art-stage { width: 200px !important }` — correct class,
 * so ≤414px was fine and nobody looked above it. Measured overflow before:
 *   415–480px : stage 480 wide, .vb-hero-art right=500 against a 415 viewport
 *   768–800px : stage 480 wide in a ~350px tablet grid column, right=868 at 768
 *
 * These restore the sizes site.css already declares for those two bands, under
 * a selector that matches. No `!important`: `.vb-hero-art .vb-hero-art-stage`
 * (0,2,0) already outranks animations.css `.vb-hero-art-stage` (0,1,0), and
 * staying non-important is what lets the design's ≤414px `!important` 200px keep
 * winning underneath the first rule.
 *
 * QUESTION FOR AREN: at 481–767px the stage does not currently overflow, so this
 * changes it from 480px to the 240px site.css intends without a rendering defect
 * forcing the change. Applying the design's own breakpoint whole is the
 * self-consistent reading — the alternative is a 240px stage at 480px jumping
 * back to 480px at 481px — but it is a visual change at widths that were not
 * broken, and Designer owns that call.
 * ───────────────────────────────────────────────────────────────────────────── */

@container vbframe (max-width: 767px) {
  /* site.css:1031 — was `.vb-hero .hero-art .vb-hero-art-stage` */
  .vb-hero-art .vb-hero-art-stage {
    width: 240px;
    height: 240px;
  }
}

@container vbframe (min-width: 768px) and (max-width: 1023px) {
  /* site.css:1273 — was `.vb-hero .hero-art .vb-hero-art-stage` */
  .vb-hero-art .vb-hero-art-stage {
    width: 360px;
    height: 360px;
  }
}

/* ─────────────────────────────────────────────────────────────────────────────
 * STILL DEAD, DELIBERATELY NOT FIXED HERE
 *
 * Same three causes, but none of these produces horizontal overflow, so fixing
 * them would be a layout change at widths that currently render without a
 * defect. They need Designer/Aren sign-off, not a CSS patch smuggled in behind
 * an overflow fix. Listed so the next session does not have to re-derive them:
 *
 *   site.css:1238  .vb-frame [data-screen-label="07 Hakkımızda"] aside[style*="sticky"]
 *                  { position: static !important }
 *                  Intended to drop the sidebar out of sticky on mobile. Dead
 *                  because of the `.vb-frame` descendant combinator. NOT restored:
 *                  it is not needed for the overflow fix, and restoring it would
 *                  make the sidebar compute `static` at 375px.
 *
 *   site.css:409,416,428,1032  .vb-hero .hero-art{,.logo-wrap,img,img.vb-hero-star}
 *                  Stale class name, as above. Harmless today.
 *
 *   site.css:1096  .vb-frame [data-screen-label="02 Nasıl çalışır"] section[…]
 *                  Empty declaration block; dead and also a no-op.
 *
 * Two sub-360px overflows are also outstanding and out of this change's
 * measured range (375 / 768 / 1440):
 *   /hakkimizda/    @320px  div[style*="max-width:720px"]  right=331
 *   /nasil-calisir/ @320px  div[style*="padding-top:6px"]  right=329
 *
 * The durable fix for the whole `[style*=…]` class of breakage is not more CSS —
 * it is a declared transform in scripts/conversion/transforms.mjs, or moving
 * these inline styles onto classes. That file is owned elsewhere.
 * ───────────────────────────────────────────────────────────────────────────── */

/* ─────────────────────────────────────────────────────────────────────────────
 * DRAWER HEIGHT — anchor it to the viewport, not the document.
 *
 * Same root cause as the modal backdrop. `.vb-drawer-backdrop` is
 * `position: absolute; inset: 0` inside `.vb-frame`, which on the canvas was one
 * fixed-height frame tile and in production is the ENTIRE PAGE — measured 3701px
 * tall on the homepage. So the drawer inherited that height, and because
 * site.css gives `.vb-drawer nav { flex: 1 }` the nav grew to fill all 3701px,
 * pushing the language pill and the "Giriş yap" button to the bottom of the
 * DOCUMENT. On a phone that means opening the menu and having to scroll several
 * screens to reach the login button.
 *
 * `fixed` makes `inset: 0` resolve against the viewport, so the drawer is exactly
 * one screen tall and its bottom-anchored controls sit where the design intends.
 * The parked (closed) drawer still translates outside that box and is still
 * clipped by the overflow-x rule above.
 * ───────────────────────────────────────────────────────────────────────────── */

.vb-drawer-backdrop {
  position: fixed;
}

/* ─────────────────────────────────────────────────────────────────────────────
 * DRAWER LOGIN BUTTON — restores centring lost when it stopped being a <button>.
 *
 * Aren's nav ruling turned every destination into a real link, so `.drawer-login`
 * is now an <a> rather than a <button>. Browsers centre button labels through the
 * UA stylesheet (`text-align: center`, plus a centred anonymous flex item); an
 * anchor gets `text-align: start` and no vertical centring. site.css never
 * declares either, because with a <button> it never had to — so the label landed
 * top-left inside the gold fill while the box itself stayed 100%/48px.
 *
 * Measured live: computed text-align `start` on the <a>, `center` on the
 * reference <button> beside it in the same drawer.
 *
 * Flex centring restores exactly the previous rendering. No design value changes;
 * this only puts back what the element type used to supply for free.
 * ───────────────────────────────────────────────────────────────────────────── */

.vb-drawer .drawer-login {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ── The lira bug: CLOSED 2026-08-25 ──────────────────────────────────────────────────────
 *
 * Prices used to render as blocky digits with a smooth currency sign, because no pixel face we
 * shipped carried U+20BA and the browser completed the string from Inter. The stopgap was
 * `--font-price`, which forced the whole price to Inter so at least it was ONE face.
 *
 * That stopgap is now gone, along with the two transforms that pointed the price tokens at it.
 * Prices are back on `--font-pixel` — Designer's ratified design — because the pixel family now
 * carries the lira via the additive subset declared at the end of this file.
 *
 * Removed only AFTER measuring the live host: `node scripts/verify-fonts.mjs
 * https://www.verbitir.com` reported ₺ painting from `Verbitir Pixel(1)`. Doing it in the other
 * order would have put tofu back on the pricing tiles if the subset had failed to load.
 *
 * DES-12 was logged for Designer to ratify pixel→Inter. It is closed by reversal rather than by
 * ratification: the change it described no longer exists. What Designer should look at now is the
 * lira GLYPH itself against the rest of the pixel face — that is a drawing question, not a
 * fallback question, and `verify-fonts.mjs` cannot answer it.
 */
/* ── Cyrillic for the pixel face (2026-08-24) ──────────────────────────────────────────────
 *
 * Stock Pixelify Sans ships NO Cyrillic subset at all, and the upstream face is additionally
 * missing capitals О (U+041E) and П (U+041F) — google/fonts#9392. Those two open a large share of
 * Russian nav and headings (О нас, Партнёрам, Помощь, Подробнее), so every one of them would have
 * rendered its first letter in a system font, inside a pixel face where the mismatch is
 * unmissable.
 *
 * Designer produced a patched derivative, `design/fonts/VerbitirPixel-Medium.ttf`, which never
 * reached `public/fonts/` — so nothing changed on the site. Subsetted here to the Google-standard
 * cyrillic range and verified after subsetting: 32/32 capitals present, О and П among them.
 *
 * The declared range below is DERIVED from this file's own cmap, not pasted from Google. It was
 * pasted originally, and that declared 102 codepoints against 95 present — Ѐ І Ѝ ѐ ѝ Ұ ұ were
 * promised and absent (they are absent from the source TTF too, so nothing was lost in subsetting;
 * the range was simply never checked against the file). Harmless today, since a declared-but-absent
 * codepoint falls through to the next family rather than painting tofu, and Russian is fully
 * covered — but it broke the rule the Cairo block states two faces down, in the same stylesheet.
 * A rule that the file carrying it does not follow is decoration.
 *
 * ADDITIVE BY DESIGN. This declares a NEW unicode-range on the existing family rather than
 * replacing the Latin faces, so Turkish and English rendering are byte-for-byte unchanged — the
 * browser only reaches for this file when it meets a Cyrillic codepoint, and today no route
 * serves one. It is in place for when /ru/ lands rather than being wired at the same time.
 *
 * `tokens.css` is byte-identity-protected, which is why this lives here.
 */
@font-face {
  font-family: 'Pixelify Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/verbitir-pixel-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0401-0405, U+0407-040C, U+040E-044F, U+0451-045C, U+045E-045F, U+0490-0491, U+2116;
}


/* ── The lira sign for the pixel face (2026-08-25) ─────────────────────────────────────────
 *
 * Closes the defect `--font-price` above is currently papering over. That override forces every
 * price to Inter because no pixel face we ship carries U+20BA — so `₺1.000` rendered as blocky
 * digits with a smooth currency sign, a mid-string face switch.
 *
 * Designer drew the glyph; `design/fonts/patch_lira_glyph.py` produces this 616-byte subset. It
 * contains exactly one glyph, verified with fontTools after subsetting rather than assumed from
 * the filename: `cmap` = {U+20BA}. The whole file is one character, which is why it costs less
 * than a favicon.
 *
 * ADDITIVE, exactly like the Cyrillic face above: a new unicode-range on the existing family, so
 * every Latin and Turkish glyph still comes from the stock subsets and nothing already on the page
 * changes. The browser reaches for this file only when it meets U+20BA.
 *
 * ORDER OF OPERATIONS — this face ships FIRST, `--font-price` is removed SECOND, in a later
 * commit, and only after the live host is measured with CDP `CSS.getPlatformFontsForNode`
 * confirming ₺ paints from the pixel family. Reversing that order would put tofu back on the
 * pricing tiles if the subset failed to load for any reason. The override is the safety net; a
 * safety net comes off after the proof, not before it.
 *
 * `tokens.css` is byte-identity-protected, which is why this lives here.
 */
@font-face {
  font-family: 'Pixelify Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/verbitir-pixel-lira.woff2') format('woff2');
  unicode-range: U+20BA;
}

/* ── Cairo for the Arabic locale (2026-08-25) ──────────────────────────────────────────────
 *
 * Declared ahead of /ar/ landing, same as the Cyrillic face above. Designer subsetted these and
 * verified Arabic SHAPING, not just codepoint counts — Arabic is a joining script, so stripping
 * GSUB renders disconnected isolated letters that a cmap count reports as a success.
 *
 * BOTH families are declared, and that is the point. Cairo's Arabic subset contains **no Western
 * digits at all** (0/10, audited with fontTools). Declaring Arabic alone means every price on an
 * Arabic page draws its numbers from a fallback face — the lira defect again, in a different
 * script. The Latin subset carries 10/10, so the browser takes digits from it and Arabic letters
 * from the other.
 *
 * D-22 — CLOSED 2026-08-25. The first cut of cairo-latin was Google's `latin`, not `latin-ext`, so
 * it carried none of `ğ ı ş ç ö ü İ Ğ Ş` and `Beyoğlu` painted its `ğ` from Inter mid-word.
 * Designer re-cut both weights from `latin-ext` (8.9→17.9 KB, 9.0→18.1 KB).
 *
 * THE RE-CUT ALONE FIXED NOTHING. The glyphs were in the file and unreachable, because this
 * declaration still carried the old ASCII range — so the browser never requested Cairo for them.
 * Same shape as the plugin patch that sat dormant nineteen days: work completed, work inert, and
 * nothing red anywhere to say so. The lesson is that a `unicode-range` is not documentation of a
 * file, it is the gate on it.
 *
 * The range below is GENERATED from the shipped file's own cmap
 * (`design/fonts/cairo-latin.unicode-range.txt`) and pasted verbatim — 359 codepoints declared
 * against 359 in the file, verified with fontTools in both directions: nothing declared that is
 * absent (which would be tofu), nothing present that is undeclared (which would be unreachable).
 * Do not hand-edit or widen it; regenerate it.
 */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/cairo-arabic-400.woff2') format('woff2');
  unicode-range: U+0020, U+060C-060D, U+0615, U+061B, U+061F, U+0621-063A, U+0640-0656, U+0658, U+0660-0671, U+0679, U+067E, U+0686, U+0688, U+0691, U+0698, U+06A1, U+06A4, U+06A9, U+06AF, U+06BA, U+06BE, U+06C1-06C3, U+06CC, U+06D2-06D4, U+06F0-06F9, U+FB51, U+FB57-FB59, U+FB67-FB69, U+FB6B-FB6D, U+FB7B-FB7D, U+FB89, U+FB8B, U+FB8D, U+FB8F-FB91, U+FB93-FB95, U+FB9F, U+FBA7-FBA9, U+FBAB-FBAD, U+FBAF, U+FBB1-FBB9, U+FBBD-FBBE, U+FBE8-FBE9, U+FBFD-FBFF, U+FC43-FC44, U+FC64-FC65, U+FC67-FC6B, U+FC6D-FC71, U+FC73-FC77, U+FC79-FC7B, U+FC86-FC87, U+FC8A-FC8B, U+FC8D-FC8F, U+FC91-FC92, U+FC94, U+FC96, U+FCFB-FCFE, U+FD05-FD08, U+FD0D-FD10, U+FD17-FD1A, U+FD21-FD24, U+FD29-FD2C, U+FD3E-FD3F, U+FDF2, U+FE82, U+FE84, U+FE86, U+FE88, U+FE8A-FE8C, U+FE8E, U+FE90-FE92, U+FE94, U+FE96-FE98, U+FE9A-FE9C, U+FE9E-FEA0, U+FEA2-FEA4, U+FEA6-FEA8, U+FEAA, U+FEAC, U+FEAE, U+FEB0, U+FEB2-FEB4, U+FEB6-FEB8, U+FEBA-FEBC, U+FEBE-FEC0, U+FEC2-FEC4, U+FEC6-FEC8, U+FECA-FECC, U+FECE-FED0, U+FED2-FED4, U+FED6-FED8, U+FEDA-FEDC, U+FEDE-FEE0, U+FEE2-FEE4, U+FEE6-FEE8, U+FEEA-FEEC, U+FEEE, U+FEF0, U+FEF2-FEFC;
}
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/cairo-arabic-700.woff2') format('woff2');
  unicode-range: U+0020, U+060C-060D, U+0615, U+061B, U+061F, U+0621-063A, U+0640-0656, U+0658, U+0660-0671, U+0679, U+067E, U+0686, U+0688, U+0691, U+0698, U+06A1, U+06A4, U+06A9, U+06AF, U+06BA, U+06BE, U+06C1-06C3, U+06CC, U+06D2-06D4, U+06F0-06F9, U+FB51, U+FB57-FB59, U+FB67-FB69, U+FB6B-FB6D, U+FB7B-FB7D, U+FB89, U+FB8B, U+FB8D, U+FB8F-FB91, U+FB93-FB95, U+FB9F, U+FBA7-FBA9, U+FBAB-FBAD, U+FBAF, U+FBB1-FBB9, U+FBBD-FBBE, U+FBE8-FBE9, U+FBFD-FBFF, U+FC43-FC44, U+FC64-FC65, U+FC67-FC6B, U+FC6D-FC71, U+FC73-FC77, U+FC79-FC7B, U+FC86-FC87, U+FC8A-FC8B, U+FC8D-FC8F, U+FC91-FC92, U+FC94, U+FC96, U+FCFB-FCFE, U+FD05-FD08, U+FD0D-FD10, U+FD17-FD1A, U+FD21-FD24, U+FD29-FD2C, U+FD3E-FD3F, U+FDF2, U+FE82, U+FE84, U+FE86, U+FE88, U+FE8A-FE8C, U+FE8E, U+FE90-FE92, U+FE94, U+FE96-FE98, U+FE9A-FE9C, U+FE9E-FEA0, U+FEA2-FEA4, U+FEA6-FEA8, U+FEAA, U+FEAC, U+FEAE, U+FEB0, U+FEB2-FEB4, U+FEB6-FEB8, U+FEBA-FEBC, U+FEBE-FEC0, U+FEC2-FEC4, U+FEC6-FEC8, U+FECA-FECC, U+FECE-FED0, U+FED2-FED4, U+FED6-FED8, U+FEDA-FEDC, U+FEDE-FEE0, U+FEE2-FEE4, U+FEE6-FEE8, U+FEEA-FEEC, U+FEEE, U+FEF0, U+FEF2-FEFC;
}
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/cairo-latin-400.woff2') format('woff2');
  unicode-range: U+0020-007E, U+00A0-0131, U+0134-0137, U+0139-013E, U+0141-0148, U+014A-017E, U+0192, U+01FA-01FF, U+0218-021B, U+0237, U+02BB-02BC, U+02C6-02C7, U+02DA, U+02DC-02DD, U+1E80-1E85, U+1EF2-1EF3, U+1EF8-1EF9, U+2013-2014, U+2018-201A, U+201C-201E, U+2020, U+2022, U+2026, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+2215;
}
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/cairo-latin-700.woff2') format('woff2');
  unicode-range: U+0020-007E, U+00A0-0131, U+0134-0137, U+0139-013E, U+0141-0148, U+014A-017E, U+0192, U+01FA-01FF, U+0218-021B, U+0237, U+02BB-02BC, U+02C6-02C7, U+02DA, U+02DC-02DD, U+1E80-1E85, U+1EF2-1EF3, U+1EF8-1EF9, U+2013-2014, U+2018-201A, U+201C-201E, U+2020, U+2022, U+2026, U+2039-203A, U+2044, U+20AC, U+2122, U+2212, U+2215;
}

/* ── Standard ligatures OFF — the `fl` defect (2026-08-25) ────────────────────────────────
 *
 * Pixelify Sans substitutes `f`+`l` with a ligature glyph that reads as a capital **A**:
 * "Customer flow" rendered "Customer Aow", "waffle" rendered "waAe". Live in headings, in both
 * locales — Turkish `şeffaf`, `teklif` and `fiyat` all sit in the affected set, so this was never
 * an English-only defect; English is only where it was noticed.
 *
 * BISECTED BEFORE BLAMING OUR PATCHES. We had patched this family twice in a week — Cyrillic, then
 * the lira — so the derivative was the obvious suspect and was not the culprit. Rendering `flow`
 * from each file directly:
 *
 *     stock pixelify-sans-latin.woff2   →  "Aow Auff"   BROKEN
 *     VerbitirPixel-Medium.ttf           →  "Aow Auff"   BROKEN (derived from stock)
 *
 * It is UPSTREAM. And it is not a subsetting artefact of the kind we expected — the `fl` glyph is
 * a real, distinct 17-contour glyph with its own advance (586, same as `f`), not a dropped target
 * resolving to a neighbouring glyph ID. It is simply drawn wrong in Google's font. Nothing we can
 * fix in a subset; the only lever is to stop asking for the substitution.
 *
 * WHY THIS IS SITE-WIDE AND NOT SCOPED TO THE PIXEL FAMILY
 * `font-variant-ligatures` inherits, and most pixel text is set through inline styles in generated
 * components, which no selector can reach. Scoping would mean editing ratified markup. Measured
 * before doing it — width of the same words with ligatures on and off:
 *
 *     word       Inter ON/OFF      Pixelify ON/OFF
 *     flow       80.5 / 80.5       77.56 / 83.64   differs
 *     fluff      76.2 / 76.2       84.84 / 99.84   differs
 *     office   107.89 / 107.89    115.97 / 124.89  differs
 *     şeffaf   109.13 / 109.13    133.38 / 138.28  differs
 *
 * Inter is byte-identical in every case, so this changes nothing about body text. It is a visual
 * change to the PIXEL face only, and it changes it from wrong to right.
 *
 * `common-ligatures` only. Kerning and contextual alternates are untouched.
 */
body {
  font-variant-ligatures: no-common-ligatures;
}

/* ── Locale switcher: the pills became links (2026-08-26) ─────────────────────────────────
 *
 * REGRESSION I SHIPPED, and this restores the ratified design rather than changing it.
 *
 * The switcher was `<button>` with no handler — correct while Turkish was the only locale, since
 * the brief forbids rendering a control that does nothing. With `/en/` serving, the pills had to
 * navigate, and a navigation control is a link: a button announces itself as an action, shows no
 * destination on hover or focus, cannot be opened in a new tab, and is invisible to a crawler —
 * which defeats a page whose whole purpose is being found in another language.
 *
 * What I missed is that EVERY rule for these pills is typed to the element:
 *   site.css:166,177        .vb-topbar .lang-pill button
 *   site.css:962,974        .vb-drawer .drawer-langs button
 *   animations.css:185–202  the hover underline
 *
 * So the markup change silently dropped all of it. Measured on the live homepage: both pills at
 * 16x19 with `padding: 0`, no background, no active fill, no gap — rendering as a single run
 * reading "TREN". Visibly broken, and no gate caught it, because every gate asks whether the
 * element is PRESENT and correct in behaviour. None of them looks at it.
 *
 * These selectors mirror the originals value-for-value; they are a re-application, not a redesign.
 * `site.css` and `animations.css` are byte-identity-protected, which is why they live here. When
 * those files are next authorised for edit, the right fix is `:is(button, a, span)` at source and
 * this block goes away.
 */
.vb-topbar .lang-pill :is(a, span) {
  border: none;
  background: transparent;
  padding: 4px 10px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 12px;
  color: var(--verbitir-forest-mid);
  cursor: pointer;
  font-family: inherit;
  text-decoration: none;
  /* from animations.css:185 — the hover underline needs the containing block */
  position: relative;
  overflow: hidden;
  transition: background 300ms ease, color 300ms ease;
}
.vb-topbar .lang-pill :is(a, span).active {
  background: var(--verbitir-forest);
  color: var(--verbitir-bg-cream);
}
.vb-topbar .lang-pill a::after {
  content: '';
  position: absolute;
  left: 8px; right: 8px; bottom: 4px;
  height: 2px;
  background: var(--verbitir-gold);
  border-radius: 2px;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 200ms var(--ease-out);
}
.vb-topbar .lang-pill a:hover::after { transform: scaleX(1); }
.vb-topbar .lang-pill :is(a, span).active::after { display: none; }

/* ── Drawer locale control: segmented, per Designer's ruling (2026-08-26) ─────────────────
 *
 * Designer corrected the brief and the correction IS the decision. The two surfaces had diverged
 * into different CONTROLS, not different sizes:
 *
 *     desktop   1 container border, 0 child borders, transparent children   → one object
 *     drawer    0 container border, 1 border per child, 6px gaps            → N objects
 *
 * A segmented control is one object with one outline, divided, with the selection filled: *one
 * setting, N mutually exclusive values, this one is current*. Separate bordered pills say *N
 * independent actions*. Choosing a language is one setting, so the desktop form is not merely more
 * compact — it is the one that describes the control truthfully. Designer's line: "Size didn't
 * diverge. Meaning did."
 *
 * The forward test settles it: `LOCALES` goes 2 → 4 when RU and AR land. Segmented subdivides into
 * the same object; separate pills become four isolated buttons that read as a menu.
 *
 * The 44px touch target is UNTOUCHED — `min-height: 44px` and `flex: 1` both survive. Segmenting
 * changes where the border sits, not how big the target is.
 */
.vb-drawer .drawer-langs {
  border: 1px solid var(--verbitir-line);
  border-radius: 999px;
  padding: 4px;
  gap: 0;
}
.vb-drawer .drawer-langs :is(a, span) {
  flex: 1;
  min-height: 44px;
  /* the drawer pills are their own elements, so they need centring that `button` gave for free */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  border-radius: 999px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--verbitir-forest-mid);
  cursor: pointer;
  text-decoration: none;
}
.vb-drawer .drawer-langs :is(a, span).active {
  background: var(--verbitir-forest);
  color: var(--verbitir-bg-cream);
}

/* ─────────────────────────────────────────────────────────────────────────────
 * D-14 · heading-order: the footer column headings, decoupled from their scale
 *
 * They were <h5>, so every route jumped h1 → h2 → h5 and failed axe's
 * heading-order rule identically on all nine — it is shared chrome. The fix
 * sat open for nine days for a real reason: `site.css` styles headings BY TAG
 * (`.vb-footer .footer-col h5`), so correcting the level would have changed the
 * type scale, turning an accessibility fix into a design change that was not
 * the web developer's to make.
 *
 * Aren's ruling of 27 Aug is to stop choosing between them: emit the correct
 * LEVEL and carry the existing SCALE on a class. The declarations below are
 * copied verbatim from `site.css:207-214` — that rule set font-size, weight,
 * tracking, transform, colour and margin explicitly and inherited nothing from
 * the browser's h5 default, which is exactly why the swap is lossless.
 *
 * Here rather than in `site.css` because that file is byte-identity-protected
 * (DEBT_LEDGER D-10). Verified by computed-style diff and by screenshot at
 * 1280 and 375, not by reasoning about the cascade.
 * ───────────────────────────────────────────────────────────────────────────── */
.vb-footer .footer-col .footer-col-title {
  font-size: 12px;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--verbitir-forest-mid);
  font-weight: 600;
  margin: 0 0 14px;
}

/* ── ARABIC TYPOGRAPHY — applying the stack that was ratified and never built (2026-08-28) ──────
 *
 * THE FONT WAS SHIPPED AND NEVER ASKED FOR. The four Cairo faces below have been declared, served
 * and gate-verified since 2026-08-25, and `Cairo` appeared in this repository ONLY as an
 * `@font-face` descriptor — never once in a `font-family` VALUE. So no element resolved to it, the
 * browser had no reason to fetch it, and every Arabic glyph on /ar/ fell through `Inter` and
 * `Pixelify Sans` (neither of which declares a single codepoint in U+0600-06FF) to the generic
 * `sans-serif` keyword: the platform default. Measured on the live host with CDP
 * `CSS.getPlatformFontsForNode`, the day after AR shipped:
 *
 *     h1       Geeza Pro (30 glyphs) | Pixelify Sans (5)
 *     p        Geeza Pro (70 glyphs) | Inter (20)
 *     .vb-btn  Geeza Pro (19 glyphs) | Inter (3)
 *     font files requested: pixelify-sans-latin.woff2, inter-latin.woff2   — no Cairo
 *
 * Geeza Pro is the macOS Arabic default. On Windows or Android the reader got something else again.
 *
 * THE STACK IS NOT A NEW DECISION. It was specified by Designer, ratified by Mohamed as the team's
 * native Arabic reader, and briefed to web-developer verbatim on 2026-08-25 —
 * `team_room/web-developer/inbox/2026-08-25_aren_designer_unblocked_you_ship_it.md:51`:
 *
 *     --font-arabic: 'Cairo', 'Inter', sans-serif;
 *
 * with the note: "Cairo has no ₺ and never will, so AR takes it from Inter — NAMED DELIBERATELY so
 * it never falls through to an arbitrary system face." It fell through to an arbitrary system face,
 * because the token was written in three team documents and zero stylesheets. The brief named the
 * exact failure and the last mile was not built.
 *
 * WHY THE TOKENS ARE OVERRIDDEN RATHER THAN THE SELECTORS ENUMERATED. Every font-family on all
 * eleven AR routes resolves through `--font-ui` or `--font-pixel`; no AR markup names a family
 * literally. Overriding the two tokens therefore reaches every consumer including ones added later.
 * Enumerating selectors instead would fail SILENTLY on a heading class nobody remembered — Arabic
 * quietly in Geeza Pro again — whereas a missed exception here fails VISIBLY, as a Latin brand
 * element rendering in Cairo. Prefer the failure mode you can see.
 *
 * `:root[lang="ar"]` and not `[dir="rtl"]`: a font follows the SCRIPT, not the direction. This file
 * loads for all four locales and the rule is inert on the other three by construction, which is the
 * same safety property `site.rtl.css` claims — obtained from the correct key.
 */
:root {
  /* Declared globally under the name the brief gave it, so the next reader finds the same token the
   * team documents describe. Inert outside [lang="ar"]; it is applied below. */
  --font-arabic: 'Cairo', 'Inter', sans-serif;
}
:root[lang="ar"] {
  --font-ui: var(--font-arabic);
  --font-pixel: var(--font-arabic);
}

/*
 * THE CARVE-OUTS. Three Latin-only elements keep the pixel brand voice on Arabic pages.
 *
 *   · THE WORDMARK. Designer's ruling is explicit — "Wordmark on AR: Stays Latin", with the
 *     regional precedent named (Careem, noon, Talabat). It is `var(--font-pixel)` at site.css:26,
 *     so the token override above would otherwise have changed it. BOTH instances are covered:
 *     `.vb-wordmark` in the topbar and the bare `.notranslate` span in the mobile drawer — the same
 *     two-instance split that left one of them bidi-mirrored until `verify-rtl` measured it.
 *   (The KPI numerals were listed here too. They are now handled globally and identically in every
 *   locale — see the KPI legibility block at the end of this file — so the carve-out was removed
 *   rather than left to fight it.)
 *
 * THE TIER PRICE IS DELIBERATELY *NOT* CARVED OUT, though the first draft of this rule did carve it
 * out. The brief settles it: "TR and RU take `₺` from the patched pixel face. AR takes it FROM
 * INTER — deliberately named." So on Arabic the price is expected to resolve through this stack,
 * with Cairo supplying the digits and Inter the `₺` that Cairo has in no subset (verified with
 * fontTools: U+20BA absent from both cairo-latin and cairo-arabic). Measured after the change:
 * `Inter(1) | Cairo(1)` on the `₺1.000` span. That is the specified behaviour, not a fallback.
 *
 * A `.vb-pixel-tile` selector was also in the first draft and was REMOVED: counted against the
 * rendered pages, it matches 0 elements on every AR route. Writing a rule for a class that does not
 * exist is the same defect this whole block is repairing, committed while repairing it — and it is
 * the fourth time in two days a hand-written selector has been checked against `site.css` instead
 * of against the page. Count the elements.
 */
:root[lang="ar"] .vb-wordmark,
:root[lang="ar"] .notranslate {
  /*
   * `!important` because ONE OF THE TWO WORDMARKS CARRIES AN INLINE `font-family: var(--font-pixel)`
   * — the drawer instance, `<span class="notranslate">` inside `.drawer-head`. An inline declaration
   * beats any selector at any specificity, so without this the token override above reached straight
   * through the carve-out and the drawer wordmark rendered in Cairo while the footer one did not.
   * Measured, not predicted: `CSS.getMatchedStylesForNode` showed this rule matching AND losing.
   *
   * That is the SECOND time in two days the same two wordmark instances have diverged for the same
   * structural reason — the first was `site.rtl.css`, where the isolation rule keyed on
   * `.vb-wordmark` and the drawer span does not carry that class, so one of them rendered
   * bidi-mirrored. Two instances of one brand asset, styled by different mechanisms. If a third
   * appears, the fix is to make the markup consistent, not to add a third rule here.
   */
  font-family: 'Verbitir Pixel', 'Pixelify Sans', 'Inter', sans-serif !important;
}

/* ── KPI VALUES ARE DATA, AND THE PIXEL FACE CANNOT CARRY DATA (2026-08-28) ─────────────────────
 *
 * MOHAMED READ HIS OWN INVESTOR PAGE'S NORTH-STAR METRIC AS 800. It says 500.
 *
 * That is the whole justification and it is not a matter of taste. `.vb-kpi .kpi-value` rendered
 * `var(--font-pixel)` at 32px, dark on white, and in Pixelify Sans the digit `5` has a squared top
 * that reads as `S` or `8`, and `6` reads as `8`. Rendered side by side at the real size:
 *
 *     Pixelify Sans   0123456789   -> `5` reads S/8, `6` reads 8;  "500" reads "800"
 *     Inter           0123456789   -> unambiguous
 *
 * A 60% error on the metric an investor page exists to communicate is a correctness failure, not a
 * legibility preference.
 *
 * WHY NOT THE BRAND PIXEL FACE. `'Verbitir Pixel'` looked like the answer — brand voice AND legible
 * in a first comparison. Measured with `CSS.getPlatformFontsForNode`, that row was painted entirely
 * by **Helvetica**: `verbitir-pixel-cyrillic.woff2` is 95 Cyrillic codepoints and
 * `verbitir-pixel-lira.woff2` is one glyph, so the family carries NO DIGITS AT ALL and the browser
 * fell through to the system. The comparison that looked like a brand win was a system font in
 * disguise — rung 3 of `.claude/rules/verification-gates.md`, one row below the answer.
 *
 * So the only faces that can carry a numeral here are Pixelify Sans and Inter, and one of them is
 * being misread.
 *
 * AN EXPLICIT STACK, NOT `var(--font-ui)`: a metric must look identical in all four locales, and
 * `--font-ui` is redefined to the Cairo stack under `[lang="ar"]`, which would paint Arabic pages'
 * digits from Cairo and the other three from Inter. Same number, two shapes.
 *
 * THE TIER PRICES ARE LEFT ALONE and that is deliberate, not an oversight: `₺0`, `₺1.000`, `₺2.999`
 * and `₺499` contain no `5` and no `6`, so they are legible in Pixelify today. They are one price
 * change away from not being. Raised to Designer via Aren as the real question — whether the brand
 * should have a display numeral that can carry data at all — which is a typography decision and is
 * not mine.
 */
.vb-kpi .kpi-value {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  /* Kept from site.css:616-624 so only the FACE changes: same size, weight, colour and tabular
   * figures, so the tiles keep their measured rhythm. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum';
  letter-spacing: -0.01em;
}


/* ─────────────────────────────────────────────────────────────────────────────────────────────
 * D-29 — footer tap targets. Visual size unchanged; hit area expanded.
 *
 * Five controls measured under 24px in their smaller dimension at 375px: the four `.footer-nav`
 * links at 22.4px and the `Çerez tercihleri` link in `.footer-strip` at 19.2px. They are present,
 * they look clickable, and they are not reliably tappable — WCAG 2.5.8 asks for 24px.
 *
 * **Reusing the pattern Designer already solved this with on the social row**: keep the visual size,
 * expand the hit area with a transparent inset pseudo-element. Nothing moves, nothing resizes, and
 * the type scale — which `site.css` sets by tag and D-10 protects — is untouched.
 *
 * `-3px` block-side only, never inline. Inline expansion on a stacked list of links would overlap
 * neighbours horizontally for no benefit; these are already 76–335px wide. 22.4 + 6 = 28.4 and
 * 19.2 + 6 = 25.2, both clear of the minimum. The vertical gaps were measured before choosing 3px:
 * expanding by more would make adjacent hit areas touch, which trades one defect for a worse one —
 * a control that activates the link above it.
 *
 * Aren signed D-29 over to web on 2026-08-31; it was filed as Designer's.
 * ───────────────────────────────────────────────────────────────────────────────────────────── */
.vb-frame .footer-nav a,
.vb-frame .footer-strip a,
.vb-frame .footer-strip button,
.vb-frame a[href^="mailto:"] {
  position: relative;
}
.vb-frame .footer-nav a::after,
.vb-frame .footer-strip a::after,
.vb-frame .footer-strip button::after,
.vb-frame a[href^="mailto:"]::after {
  content: '';
  position: absolute;
  inset: -3px 0;
  /* No background, no border: this is a hit area, not a visual change. */
}

/*
 * The last two were found by the fixed gate rather than by the original ticket, which is the point
 * of fixing the gate first: `Çerez tercihleri` is a `<button>`, not an `<a>`, so a selector written
 * from the ticket's wording missed it; and `investor@verbitir.com` on /yatirimci/ is an 18px mailto
 * link the ticket never mentioned. D-29 said "five footer links". It was six controls, in three
 * different shapes.
 *
 * The mailto rule is scoped to `.vb-frame` and to `mailto:` specifically rather than to all inline
 * links, because WCAG 2.5.8 exempts a link inside a block of prose and expanding those would make
 * neighbouring lines' hit areas overlap — trading one defect for a worse one.
 *
 * It also needs 4px rather than 3px, and the reason is worth stating: its box is 17.4px, so -3px
 * lands it on 23.4 — one pixel short, and the gate correctly still failed it. The number comes from
 * the measurement, not from copying the neighbouring rule.
 */
.vb-frame a[href^="mailto:"]::after { inset: -4px 0; }

/* ─────────────────────────────────────────────────────────────────────────────────────────────
 * D-14 — colour contrast. Signed over to web by Aren, 2026-08-31.
 *
 * Twelve distinct failing colour pairs, measured across six routes rather than taken from the
 * Lighthouse summary. Two foreground tokens account for all of them:
 *
 *   --verbitir-gold-deep   #C68A0F   2.42–2.98  (needs 4.5)
 *   --verbitir-forest-mid  #6B856E   3.84–4.03  (needs 4.5)
 *
 * **`tokens.css` carries the comment "AA-passing as text on white at 14px+" beside gold-deep. That
 * claim is false and always was: measured, it is 2.98 on white.** A comment asserting a contrast
 * ratio is not a measurement, and this one outlived every audit that read it.
 *
 * The new values are the MINIMAL darkening that clears 4.5 on the worst background each token
 * actually sits on, computed rather than eyeballed, with hue and saturation held constant so the
 * brand colour is the same colour, darker:
 *
 *   gold-deep   #C68A0F -> #8A600A   white 5.59 · cream 5.31 · yellow band 4.53
 *   forest-mid  #6B856E -> #617964   white 4.74 · cream 4.51
 *
 * The gold has to reach 4.53 on `#FFE873` — gold text on the yellow band is the hardest pair on the
 * site, and it is what forces the size of the change. A variant that passed only on white would
 * have left the eyebrow on that band failing at 3.85, which is the pair a reader is most likely to
 * struggle with.
 *
 * **The two NON-TEXT usages are restored to the original gold below.** gold-deep also paints a
 * border on `.vb-btn.gold` and on `.vb-drawer .drawer-login`, and a border is not text: darkening it
 * would be a design change with no accessibility benefit. Overriding the token and then putting the
 * two back is deliberate — it keeps one token rather than inventing a second name for the same
 * colour, which is how a palette drifts.
 *
 * Not in `tokens.css`: D-10 makes it byte-identity-protected.
 * ───────────────────────────────────────────────────────────────────────────────────────────── */
:root {
  --verbitir-gold-deep: #8A600A;
  --verbitir-forest-mid: #617964;
}
.vb-btn.gold { border-color: #C68A0F; }
.vb-drawer .drawer-login { border: 1px solid #C68A0F; }

/* ═════════════════════════════════════════════════════════════════════════════════════════════
 * Applied 2026-08-31 by the stylesheet owner. Two agents produced these blocks and correctly
 * refused to write them themselves — neither owned this file, and a shared stylesheet edited by
 * three agents in parallel is how a merge silently drops a rule. The reasoning in each block is
 * theirs; the placement is mine.
 * ═════════════════════════════════════════════════════════════════════════════════════════════ */
/* ──────── FOOTER SOCIAL ROW ──────── */
/* Seven official platform marks in our containers. We own the pill, the border, the gold hover
   and the spacing; the glyph inside is theirs — never redrawn, never gradient, never mirrored. */
.vb-footer .vb-social {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 20px;
}
.vb-footer .vb-social a {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  border: 1px solid var(--verbitir-line);
  background: transparent;
  transition: background 200ms var(--ease-out), border-color 200ms var(--ease-out);
}
/* Hit area to 46x46 without growing the 40px circle.
   -4px, NOT the spec's -3px: an absolutely positioned pseudo-element is inset from the PADDING
   box, and the 1px border makes that 38px, not 40px. Measured in Chrome at 375px:
   inset:-2px -> 42x42 (BELOW the 44px minimum), inset:-3px -> 44x44, inset:-4px -> 46x46.
   The spec's table says "adopt 46"; -4px is what actually produces 46. */
.vb-footer .vb-social a::after {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 999px;
}
.vb-footer .vb-social a:hover {
  background: var(--verbitir-gold);
  border-color: var(--verbitir-gold);
}
/* Do not remove. Seven identical circles with no visible focus is unusable by keyboard. */
.vb-footer .vb-social a:focus-visible {
  outline: 2px solid var(--verbitir-gold-deep);
  outline-offset: 2px;
}
.vb-footer .vb-social svg {
  width: 20px;
  height: 20px;
  fill: var(--verbitir-forest);
}

/* ...and this one line INSIDE the existing `@media (max-width: 767px)` footer block, beside
   `.vb-footer .footer-nav { align-items: center; }`. The mobile footer is `text-align: center`,
   which does nothing to a flex row. */
@media (max-width: 767px) {
  .vb-footer .vb-social { justify-content: center; }
}

/* SELECTOR NOTE: I used `.vb-footer .vb-social` to match how every other footer rule in
   site.css is written and to sit above any future bare `.vb-social`. The bare form the spec
   writes also works from production-overrides.css, which loads after site.css. The CLASS name
   is `vb-social` either way, which is the half that has to match my markup.

   RTL: nothing needed. Verified on /ar/ at 390px — `dir="rtl"` alone reverses the row
   (Instagram rightmost, LinkedIn leftmost), `flex-direction` stays `row`, and computed
   `transform` is `none` on all seven glyphs. Do NOT add `row-reverse`; it would double-reverse
   and put Instagram last. */

/* ── Inter Cyrillic for the Russian locale (2026-08-31) ────────────────────────────────────
 *
 * Closes DEBT_LEDGER D-28. Filed as Designer craft; it was not. Inter ships a Cyrillic subset
 * upstream, so this needed fetching and declaring, not cutting.
 *
 * ADDITIVE, exactly like the pixel Cyrillic and Cairo faces above: a new unicode-range on the
 * existing 'Inter' family, so nothing that already resolves to Inter changes. The RU page ALREADY
 * asks for Inter — site.css sets font-family: var(--font-ui) and tokens.css defines --font-ui as
 * 'Inter', … — so unlike D-22 there is no missing font-family rule to add. The face was simply
 * absent, and every Cyrillic codepoint fell past Inter and Pixelify (neither declares one) to the
 * generic sans-serif keyword: .SF NS on macOS, something else everywhere else. Measured with CDP
 * CSS.getPlatformFontsForNode before this block existed: 'Конфиденциальность' → .SF NS(18).
 *
 * THE RANGE IS THE EXACT COVERAGE OF THE FILE, NOT THE U+0400-04FF BLOCK. Those are different, and
 * the difference is the D-22 failure mode in both directions. The subset carries U+0400-045F,
 * U+0490-0491 and U+04B0-04B1 only — it does NOT carry U+0460-048F or the Cyrillic Supplement, so
 * declaring the whole block would advertise ~50 codepoints the file cannot draw and render them as
 * tofu instead of letting them fall through. Verified with fontTools: 102 codepoints in range, all
 * 102 with real contours, zero declared-but-absent, zero present-but-undeclared.
 *
 * U+2116 (№) is in the range ON PURPOSE and is not decoration: it IS used in the Russian copy, and
 * it sits outside U+0400-04FF, so a range that stops at the Cyrillic block ships one silently wrong
 * glyph. U+0301 likewise — it is in the file and declared by no other Inter face we ship.
 *
 * cyrillic-ext is deliberately NOT shipped: a codepoint census of every ru JSON found 58 distinct
 * non-Latin characters and not one of them falls outside this range. If RU copy later gains ґ, ѐ,
 * historic letters or ₴, that needs a second file — it will not fall back to this one.
 *
 * Inter 4.001;git-66647c0bb — the same upstream build as inter-latin.woff2 and
 * inter-latin-ext.woff2, so weights and metrics match across scripts. OFL-1.1; the notice in
 * /fonts/OFL.txt lists this file.
 */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/inter-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}