/* ==========================================================================
   tokens.css — the ONLY place raw values live.
   styles.css consumes these; never hardcode values there.
   Light theme on :root; dark overrides under [data-theme="dark"].

   Surface metaphor: a sheet of warm paper resting on a cutting mat.
   The mat is fixed and full-bleed behind everything; <body> IS the paper.
   Because <body> is a size container, headings and page margins are sized
   in `cqi` — 1% of the paper's width — so type scales with the sheet, not
   the viewport.
   ========================================================================== */

:root {
  color-scheme: light;

  /* ------ Surface: the mat ------
     The default mat is a hand-authored SVG panel of a ruled cutting mat —
     a 50x25-unit grid at 24px pitch (bold every 5 units), axis rulers
     numbered 0-50 along the top edge and 0-25 down the right edge only,
     and a quarter-circle protractor fanning 15/30/45/60° from the
     bottom-left origin. It renders once (`background-repeat: no-repeat`)
     and is scaled with `background-size: cover`, anchored
     `background-position: left bottom` (see styles.css's `html::before`),
     so the ruled origin always sits at the actual bottom-left corner of
     the viewport — a single continuous grid, not a tiled chunk. Recoloured
     entirely via color-mix(), literal in the SVG markup below. color-mix()
     resolves at paint time inside the image itself — it needs no CSS
     custom-property inheritance, so the exact same template is reused by
     js/main.js to build a live SVG for any user-picked color.
     --color-mat stays as the plain fallback field colour and the source of
     truth for "what color is the mat right now" (read by JS, shown in the
     picker UI). See --mat-texture below for the grain layered on top.

     The mat keeps its original green. kami's single-accent rule governs the
     *paper* — the sheet and everything printed on it — not the desk the sheet
     is lying on; the mat sits behind the paper and never has text on it, so a
     saturated field there costs nothing and is the site's own signature. The
     picker offers the original six colours plus a kami-derived warm-neutral
     set (see the .surface-picker markup). */
  --color-mat: #095848;
  --mat-image: url("../assets/mat-light.svg");

  /* ------ Surface texture: fibrous grain over the mat, LIT relief over
     the paper ------
     Two different mechanisms now, on purpose — not just two colour passes
     of one technique. --mat-texture is unchanged: flat feTurbulence noise,
     alpha shaped by a gamma curve, layered on --mat-image (html::before)
     via `screen`. --paper-texture is a different pipeline, matched to
     marijanapav.com/stamps's actual paper effect rather than this site's
     own earlier flat-grain approach: feTurbulence feeds feDiffuseLighting
     (a distant light at 45°/60° azimuth/elevation lighting the noise as a
     bump map), which produces real raised-fibre relief — measured output
     spans RGB 155-255 at these settings, not the flat gamma-shaped alpha
     the old pipeline produced. A closing feColorMatrix pins that lit RGB
     to a CONSTANT alpha (0.20 light / 0.04 dark, see below), then it's
     layered via `background-blend-mode: normal` (styles.css) — normal
     alpha-composites the lit pixel straight over --color-bg, which is
     mechanically the same thing marijanapav's own `opacity: 0.2;
     mix-blend-mode: normal` pseudo-element does, just delivered as a tiled
     background-image instead of a live full-viewport filter (this site's
     `<body>` deliberately isn't a containing block for positioned
     descendants — see styles.css's "The paper" comment — so a live
     absolutely-positioned overlay isn't a clean fit; a tileable data-URI
     needs no positioning at all and renders identically).

     `normal` blend can't self-limit the way the old `multiply`/`screen`
     could (multiply only darkens, screen only lightens) — a lit texture
     has both peaks AND valleys in the same image, so it pushes contrast
     in both directions at once. That was solved numerically, not by eye:
     rendered the actual filter to a canvas, sampled its real min/max
     (155/255 at these settings), then binary-searched the composite alpha
     per theme against the worst single pixel for EVERY foreground token
     that can sit directly on the paper — body text, secondary text, AND
     the accent (an inline link is real paper content, not just body/
     secondary copy). Light theme has real headroom (worst case, the
     accent, still 5.68:1 at the reference's own 0.20 opacity — the
     recipe's literal values, unmodified). Dark theme does not: its
     amber/bronze accent (see the dark override below) only has 5.34:1
     of contrast to begin with, and a *white*-lit texture pushes hardest
     on exactly that token, since both trend toward white together. 0.20
     there put the accent as low as 3.19:1 — well under AA. 0.04 is what
     clears every token with margin (accent worst-case 4.75:1; body text
     and secondary both stay ≥12:1). That's a lower alpha than light
     theme's, same asymmetry the old dark-theme override already used
     (0.10 vs light's 0.32) and for the identical underlying reason: dark
     theme's palette has less contrast budget to spend on texture. */
  --mat-texture: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'300'%20height%3D'300'%3E%3Cfilter%20id%3D'n'%20x%3D'0'%20y%3D'0'%20width%3D'100%25'%20height%3D'100%25'%3E%3CfeTurbulence%20type%3D'fractalNoise'%20baseFrequency%3D'0.28%200.28'%20numOctaves%3D'5'%20seed%3D'11'%20stitchTiles%3D'stitch'%20result%3D't'%2F%3E%3CfeColorMatrix%20in%3D't'%20type%3D'matrix'%20values%3D'0%200%200%201%200%20%200%200%200%201%200%20%200%200%200%201%200%20%200%200%200%201%200'%20result%3D'g'%2F%3E%3CfeComponentTransfer%20in%3D'g'%20result%3D's'%3E%3CfeFuncR%20type%3D'gamma'%20amplitude%3D'1'%20exponent%3D'1.6'%20offset%3D'0'%2F%3E%3CfeFuncG%20type%3D'gamma'%20amplitude%3D'1'%20exponent%3D'1.6'%20offset%3D'0'%2F%3E%3CfeFuncB%20type%3D'gamma'%20amplitude%3D'1'%20exponent%3D'1.6'%20offset%3D'0'%2F%3E%3CfeFuncA%20type%3D'gamma'%20amplitude%3D'1'%20exponent%3D'1.6'%20offset%3D'0'%2F%3E%3C%2FfeComponentTransfer%3E%3CfeColorMatrix%20in%3D's'%20type%3D'matrix'%20values%3D'1%200%200%200%200%20%201%200%200%200%200%20%201%200%200%200%200%20%200%200%200%200.22%200'%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D'300'%20height%3D'300'%20filter%3D'url(%23n)'%2F%3E%3C%2Fsvg%3E");
  --paper-texture: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20width%3D%27240%27%20height%3D%27240%27%3E%3Cfilter%20id%3D%27n%27%20x%3D%270%27%20y%3D%270%27%20width%3D%27100%25%27%20height%3D%27100%25%27%3E%3CfeTurbulence%20type%3D%27fractalNoise%27%20baseFrequency%3D%270.8%27%20numOctaves%3D%275%27%20seed%3D%277%27%20stitchTiles%3D%27stitch%27%20result%3D%27noise%27%2F%3E%3CfeDiffuseLighting%20in%3D%27noise%27%20lighting-color%3D%27%23ffffff%27%20surfaceScale%3D%272%27%20diffuseConstant%3D%271%27%20result%3D%27lit%27%3E%3CfeDistantLight%20azimuth%3D%2745%27%20elevation%3D%2760%27%2F%3E%3C%2FfeDiffuseLighting%3E%3CfeColorMatrix%20in%3D%27lit%27%20type%3D%27matrix%27%20values%3D%271%200%200%200%200%20%200%201%200%200%200%20%200%200%201%200%200%20%200%200%200%200%200.20%27%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%27240%27%20height%3D%27240%27%20filter%3D%27url%28%23n%29%27%2F%3E%3C%2Fsvg%3E");

  /* ------ Color: light theme (ink on warm parchment) ------
     Every value below is a kami token (references/tokens.json), with two
     documented exceptions marked inline. kami's own semantics carry over
     directly: parchment is the page, ivory is the *lifted* surface (brighter
     than the page, not darker — the fill IS the lift), warm sand is the
     interactive surface, and ink blue is the only chromatic color.

     Note the inversion this brings: --color-bg-subtle used to be DARKER than
     the paper (#f2efe8 on #faf8f4). Under kami a raised card is brighter than
     the sheet it sits on, which is how paper actually behaves. Anything that
     needs to read as pressed-in rather than lifted uses --color-surface-
     interactive instead. */
  --color-bg: #f5f4ed;              /* kami Parchment — the paper itself */
  --color-bg-subtle: #faf9f5;       /* kami Ivory — cards, tiles, code blocks */
  --color-surface-interactive: #e8e6dc; /* kami Warm Sand — buttons, pressed chrome */
  --color-border: #e8e6dc;          /* kami Border — dividers, hairlines */
  --color-border-soft: #e5e3d8;     /* kami Border Soft — row separators */
  /* NOT a kami token. kami's --border is 1.08:1 on parchment, which cannot
     satisfy WCAG 1.4.11 (3:1) for a border that identifies an interactive
     component. Derived on kami's own warm ramp between Stone (#6b6a64) and
     Border (#e8e6dc): 4.20:1 on paper, 4.40:1 on ivory, 3.70:1 on warm sand. */
  --color-border-strong: #7a746a;
  --color-text: #141413;            /* kami Near Black — 16.72:1 paper, 17.50:1 ivory */
  --color-text-secondary: #504e49;  /* kami Olive — 7.54:1 paper, 6.64:1 warm sand.
                                       kami's Stone (#6b6a64) was rejected as a
                                       third text level: it measures 4.34:1 on
                                       warm sand, i.e. it fails AA on the
                                       interactive surface. Two levels only. */
  /* The accent now TRACKS THE MAT. #095848 (green) is the default mat colour
     baked into this file, so the default accent is the deep-green ink that
     colour derives to — not a fixed ink-blue independent of the mat.
     js/main.js recomputes all four accent tokens (accent, hover, on-accent,
     tint-brand) whenever a visitor changes the mat, from a verified lookup
     table for the picker's built-in swatches, or algorithmically (same
     formula, run live) for a custom colour typed into the native picker.
     Every derived pair is solved the same way the fixed ink-blue was: binary
     search for the lightness, at the mat's own hue, that clears 4.5:1 against
     parchment, warm sand, AND the worst single pixel the paper's own grain can
     produce — see js/main.js section 4 for the full derivation and
     docs/DESIGN-GUIDELINES.md for the worked numbers. A genuinely hueless mat
     (the grayscale picker options, or a near-desaturated custom pick) has no
     colour to derive from and falls back to this ink-blue pair. */
  --color-accent: #116151;          /* green mat, derived — 6.68:1 paper, 5.88:1 warm sand */
  --color-accent-hover: #0c4338;    /* deeper — 10.15:1 */
  --color-on-accent: #faf9f5;       /* ivory on accent — verified >=4.5:1 for
                                       every derived accent, light or dark */
  /* Primary buttons (solid fill) are brand green, kept distinct from
     --color-accent (used for links, focus, secondary/outline buttons) —
     desk.css re-points this at the header/mat's own green so a primary
     button matches the site's identity color, not the link color. */
  --color-primary: var(--color-accent);
  --color-primary-hover: var(--color-accent-hover);
  --color-focus: var(--color-accent);
  --color-paper-edge: rgb(0 0 0 / 0.05);   /* 1px ring defining the sheet */
  --color-image-edge: oklch(0 0 0 / 0.1);  /* hairline over photographic art */

  /* ------ Scrim: the case-study image lightbox ------
     Deliberately theme-invariant (no [data-theme="dark"] override below)
     — a near-opaque black reads correctly separating the enlarged image
     from the page behind it whether that page is the light or dark
     paper, so one set of tokens covers both. At 0.92 alpha the scrim is
     opaque enough that contrast between --color-on-scrim and the scrim
     is effectively independent of whatever's behind it: even the
     worst case (pure white content behind the scrim) still composites
     to 15.5:1, and every other page is darker than that, i.e. higher
     contrast still. See js/main.js's lightbox section and styles.css's
     ".lightbox" rules. */
  --color-scrim: rgb(0 0 0 / 0.92);
  --color-on-scrim: rgb(255 255 255 / 0.92);        /* caption text, close icon */
  --color-on-scrim-muted: rgb(255 255 255 / 0.14);  /* close button fill */
  --color-on-scrim-muted-hover: rgb(255 255 255 / 0.26);

  /* ------ Tint & concept: both simple aliases of the accent pair ------
     Design and engineering used to be two different colours (and tags used
     to have two different fills). Both are now unified to the single accent
     the mat is currently driving — "no need for separate colours" — so both
     are declared ONCE here, as aliases, and never redeclared per theme: a
     custom property's `var()` reference re-resolves against whatever
     --color-accent/--color-tint-brand are in scope, including a JS inline
     override, so aliasing is enough to make the underlines, the work-card
     tag pills, the cert/writing status chips, the ghost-button hover fill,
     and inline code all track the mat with zero extra JS.

     --color-tint-brand is kami's own "quietest fill" pattern — solid, never
     rgba (WeasyPrint's alpha-compositing bug is print-only, but the rule
     travels: a hand-mixed rgba here would still fight the mat-driven accent
     under any future dark/light recolour). js/main.js derives it the same
     way it derives the accent: mixed toward the current paper at a fixed
     cosmetic ratio, walked down only if that fails the 4.5:1 floor against
     the accent text sitting on it. */
  --color-tint-brand: #e0e7df;   /* green mat, derived */
  --color-tag-bg: var(--color-tint-brand);
  --color-concept: var(--color-accent);
  /* ------ Typography ------
     Body copy and headings run on Inter (self-hosted InterVariable — see
     the @font-face block in styles.css — sourced from rsms.me/inter/).
     Body text is deliberately plain: Regular (400) weight and a tight
     -2% tracking (--tracking-body), Inter's own recommendation for text
     sizes. Headings additionally enable Inter's full bundle of character
     variants (--font-feature-alt) — single-story a, open digits, alternate
     1/3, compact f/t, and the rest — the modern equivalent of the
     "Inter UI var alt" cut from Inter's older releases (that exact named
     family/file is no longer published; font-feature-settings reproduces
     the same alternate glyph set on today's InterVariable, which is also
     why font-feature-settings is used here rather than the newer
     font-variant-alternates: character-variant() — rsms.me's own
     stylesheet notes the newer syntax isn't broadly supported yet). */
  --font-sans: "InterVariable", "Segoe UI", system-ui, sans-serif;
  /* Headings and button/link labels run on Commissioner (self-hosted variable
     font, FLAR/VOLM/slnt/wght axes) — body copy stays on Inter. Its own
     default axis values match the Figma reference ("FLAR" 0, "VOLM" 0), so
     no font-variation-settings override is needed beyond weight. */
  --font-heading: "Commissioner", var(--font-sans);
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", monospace;
  /* Reem Kufi substitutes for Commissioner (headings/buttons) in RTL; IBM
     Plex Sans Arabic substitutes for Inter (body) and IBM Plex Mono
     (eyebrow/mono) in RTL. Reem Kufi is geometric Kufi — the script of
     architecture, tilework and inscription — concept-true on a drafting-
     table site rather than merely decorative; Plex Sans Arabic is a UI
     face built for small sizes, unlike Harmattan (a SIL text face for
     West African Arabic) which thinned out badly at 15-17px. Both verified
     live on the Google Fonts css2 API. See the RTL override below for
     where each token applies. */
  --font-sans-arabic-heading: "Reem Kufi", "Commissioner", "InterVariable", system-ui, sans-serif;
  --font-sans-arabic-body: "IBM Plex Sans Arabic", "InterVariable", system-ui, sans-serif;
  /* Handwriting face for the sticky-note component's label/annotation text
     only (never headings, body copy, or RTL — Architects Daughter has no
     Arabic coverage, see the RTL override below). Falls back to the
     heading font rather than the body font if it fails to load, since a
     note's label sits closer to a heading's job (a short, scannable
     phrase) than to running body copy. */
  --font-hand: "Architects Daughter", var(--font-heading);
  --tracking-body: -0.02em;
  --tracking-heading: -0.025em;
  --font-feature-alt:
    "liga" 1, "calt" 1,
    "cv01" 1, "cv02" 1, "cv03" 1, "cv04" 1, "cv05" 1, "cv06" 1, "cv07" 1,
    "cv08" 1, "cv09" 1, "cv10" 1, "cv11" 1, "cv12" 1, "cv13" 1;

  /* ------ Type scale ------
     Proportions follow kami's ladder (36/22/16/13/11/10/9pt) compressed into
     the span this site actually has: display is capped where it already sits
     and body is pinned at 16px, so the whole ladder lives inside 2.5x rather
     than kami's 3.6x. Compressing kami's exponents into that span gives
     40 / 22 / 19 / 17 / 16 / 15 at the wide end, which is what the values
     below round to.

     Only --text-display and --text-h2 are fluid, and they now share ONE
     window. That is the fix for a real defect: the three heading tiers used
     to scale in cqi over completely disjoint ranges (display over paper
     718-1026px, h2 over 870-1130px, h3 over 1133-1267px), so the ratios
     between them changed with viewport width and the hierarchy collapsed at
     the most common one — at an 864px sheet the ladder flattened to
     33.7/20/17/16, where h3 sat 1px above body. Both fluid tiers now reach
     their maximum at the same sheet width, and the tiers below them are
     fixed, because a stable ladder matters more at 17-19px than fluidity
     does.

     --text-display is unchanged: it is the agreed ceiling for h1.
     --text-body is deliberately NOT scaled: 16px is the floor for readable
     prose and anything smaller triggers iOS input zoom. */
  --text-display: clamp(1.75rem, 3.9cqi, 2.5rem);   /* 28 → 40px */
  --text-h2: clamp(1.3125rem, 2.14cqi, 1.375rem);   /* 21 → 22px, same window as display */
  --text-h3: 1.1875rem;                             /* 19px */
  --text-lead: 1.0625rem;                           /* 17px — intro paragraphs */
  --text-body: 1rem;                                /* 16px */
  /* A handwriting face's x-height reads smaller than a sans face at the
     same size — sized up from --text-body so handwritten note copy
     (.sticky-note) stays as legible as the body text around it, not
     smaller-looking. */
  --text-hand: 1.3125rem;                           /* 21px */
  /* Larger hand tier for a note meant to be read as its own object (the
     NDA disclosure), not scanned alongside body copy like a stat label. */
  --text-hand-lg: 1.625rem;                         /* 26px */
  /* 14px, raised from 13px. kami's ladder discipline puts the 12px floor on
     uppercase micro-labels and badges only — prose stops at 14 — and this
     token carries prose (card descriptions, theses, contact meta). */
  --text-small: 0.875rem;
  --text-mono: 0.75rem;                             /* 12px — uppercase labels only */

  --leading-tight: 1.2;    /* headings — kami tight tier 1.1–1.3 */
  --leading-body: 1.6;     /* reading prose on screen */
  --leading-dense: 1.45;   /* card copy, meta, captions — kami dense tier 1.40–1.45 */
  --measure: 65ch;

  /* ------ Spacing (Carbon-style scale) ------ */
  --space-01: 0.125rem;
  --space-02: 0.25rem;
  --space-03: 0.5rem;
  --space-04: 0.75rem;
  --space-05: 1rem;
  --space-06: 1.5rem;
  --space-07: 2rem;
  --space-08: 2.5rem;
  --space-09: 3rem;
  --space-10: 4rem;
  --space-11: 5rem;
  --space-12: 6rem;

  /* ------ Layout: the paper ------
     Width is a hard requirement (60% desktop / ~75% tablet / 100% mobile),
     so it is expressed here and nowhere else. The desktop clamp() resolves to
     exactly 60vw between ~1173px and ~2133px viewports — the range that
     matters — with a 44rem floor so narrow laptops stay readable and an 80rem
     ceiling so ultrawides don't produce an absurd sheet. */
  --paper-inline: 100%;
  --paper-inset-block-start: 0;

  /* Inner page margins and section rhythm scale with the sheet, same as type. */
  --paper-margin-inline: clamp(var(--space-05), 6.5cqi, var(--space-12));
  --section-rhythm: clamp(var(--space-09), 5.5cqi, var(--space-11));

  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-xl: 1.25rem;
  /* Actions are pills, labels are chips. kami specifies pill buttons for its
     one screen template and small-radius chips for tags; keeping the two
     shapes distinct is what stops a tag from reading as a button. */
  --radius-pill: 9999px;

  /* ------ Elevation ------
     Ring + contact shadow + two diffuse layers: the sheet reads as barely
     floating rather than cut out. */
  --shadow-paper:
    inset 0 0 0 1px var(--color-paper-edge),
    0 1px 2px rgb(0 0 0 / 0.08),
    0 10px 28px rgb(0 0 0 / 0.16),
    0 28px 72px rgb(0 0 0 / 0.12);

  /* Lighter elevation for small floating chrome (the surface-picker trigger
     and its popover) — the paper's shadow is deliberately dramatic; this
     isn't. */
  --shadow-float:
    inset 0 0 0 1px var(--color-paper-edge),
    0 2px 6px rgb(0 0 0 / 0.1),
    0 8px 20px rgb(0 0 0 / 0.14);

  /* kami's "whisper" — one soft, outline-free layer, the only depth cue a
     card gets. It is deliberately not a ring: a ring layered over a card that
     already has an edge stacks three outlines and reads digital rather than
     papery. Rings are for buttons, whispers are for cards. */
  --shadow-whisper: 0 4px 24px rgb(0 0 0 / 0.05);

  /* A note sitting slightly proud of the page at rest, not just on hover —
     unlike --shadow-whisper (a hover-only cue), this is always-on, so it
     needs a touch more contact definition than a bare diffuse blur gives. */
  --shadow-note:
    0 1px 1px rgb(0 0 0 / 0.06),
    0 4px 10px rgb(0 0 0 / 0.1);

  /* ------ Sticky note: paper-on-paper material ------
     A visibly different stock from --color-bg-subtle (the flat card fill) —
     warm, sun-yellowed paper, the way a Post-it reads next to plain paper.
     Not an accent-tinted surface: --color-accent already means
     "interactive/brand" everywhere else on the site, and a note is neither.
     Both pairs verified >=4.5:1 (11.08:1 light, 8.76:1 dark). */
  --color-note-bg: #fbf3d4;
  --color-note-text: #3d3418;
  --color-note-edge: #e5dcb6;

  /* ------ Motion (Carbon productive easing) ------ */
  --duration-fast: 150ms;
  --duration-base: 300ms;
  --ease: cubic-bezier(0.2, 0, 0.38, 0.9);

  /* Scroll reveal: slower and softer than a UI transition, because it is
     content arriving rather than a control responding. */
  --duration-reveal: 520ms;
  --ease-entrance: cubic-bezier(0, 0, 0.3, 1);   /* Carbon expressive entrance */
  --reveal-stagger: 60ms;
  --reveal-rise: var(--space-05);

  /* ------ Focus ------ */
  --focus-ring: 2px solid var(--color-focus);
  --focus-offset: 2px;
}

/* Tablet: the sheet lifts off the mat and gains visible side margins. */
@media (min-width: 48em) {
  :root {
    --paper-inline: 78vw;
    --paper-inset-block-start: var(--space-07);
  }
}

/* Desktop: 60% of the viewport, bounded. */
@media (min-width: 64em) {
  :root {
    --paper-inline: clamp(44rem, 60vw, 80rem);
    --paper-inset-block-start: var(--space-09);
  }
}

/* ------ RTL: Arabic type ------
   Two faces split the roles that were LTR's three: Reem Kufi substitutes
   for Commissioner (headings, buttons — --font-heading is overridden too,
   since h1-h6/.btn set it explicitly and would otherwise win over body's
   inherited font-family), IBM Plex Sans Arabic substitutes for both Inter
   (body) and IBM Plex Mono (.eyebrow/.mono, which set --font-mono
   explicitly and would otherwise win the same way). Arabic must never be
   letter-spaced. */
[dir="rtl"] body {
  font-family: var(--font-sans-arabic-body);
  letter-spacing: 0;
}
[dir="rtl"] h1,
[dir="rtl"] h2,
[dir="rtl"] h3,
[dir="rtl"] h4,
[dir="rtl"] h5,
[dir="rtl"] h6,
[dir="rtl"] .btn,
[dir="rtl"] .site-logo {
  font-family: var(--font-sans-arabic-heading);
  letter-spacing: 0;
}
[dir="rtl"] .eyebrow,
[dir="rtl"] .mono,
[dir="rtl"] .mode-select-trigger,
[dir="rtl"] .mode-select-option,
[dir="rtl"] .segmented-bar-btn {
  font-family: var(--font-sans-arabic-body);
  letter-spacing: 0;
}
/* Architects Daughter has no Arabic coverage — without this, RTL content
   inside a sticky note or highlight card would silently fall through
   Commissioner then Inter (neither has Arabic either) all the way to
   the browser's own default sans, inconsistent with every other Arabic
   string on the site. */
[dir="rtl"] .sticky-note,
[dir="rtl"] .highlight-card {
  font-family: var(--font-sans-arabic-body);
  letter-spacing: 0;
}
