/* ============================================================================
   ژیار سامانه گستر — Design System
   tokens.css · foundation layer (tokens + fonts + reset + layout + components)
   RTL-first. Logical properties only. No external requests at runtime.
   Reference width for the brand type scale: 1440px.
   ========================================================================= */

/* ---------------------------------------------------------------------------
   0. CASCADE LAYERS
   Other specialists append to @layer components / utilities without fighting
   specificity. Utilities always win. Nothing in this file uses !important
   except .sr-only, so nothing here can trap a later author.
------------------------------------------------------------------------- */
@layer fonts, tokens, reset, base, layout, components, utilities;


/* ===========================================================================
   1. @FONT-FACE — self-hosted variable woff2. Never Google Fonts.
   ========================================================================= */
@layer fonts {

  /* Vazirmatn — Persian / Kurdish / Arabic-Indic digits / Latin fallback.
     Verified axis in the shipped file: wght 100..900.
     NO unicode-range on purpose: this face is the universal fallback and must
     own every codepoint we do not explicitly hand to Space Grotesk —
     including U+200C ZWNJ, which Persian orthography depends on. */
  @font-face {
    font-family: "Vazirmatn";
    src: url("../fonts/Vazirmatn-var.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
  }

  /* Space Grotesk — Latin ONLY: code, version numbers, technical labels,
     stat numerals, the ZHIAR bilingual lockup.
     Verified axis in the shipped file: wght 300..700 — NOT 100..900.
     Declaring the true range is deliberate: a 900 request then falls outside
     the declared range and the UA may synthesise, instead of silently
     clamping to 700 and pretending it succeeded.

     unicode-range deliberately EXCLUDES U+200B–U+200F (ZWNJ/ZWJ/LRM/RLM) and
     U+2066–U+2069 (bidi isolates). This file has no glyphs for them, and a
     zero-width joining control assigned to a font that lacks it splits the
     Arabic shaping run — «می‌شود» would visibly break apart. */
  @font-face {
    font-family: "Space Grotesk";
    src: url("../fonts/SpaceGrotesk-var-latin.woff2") format("woff2");
    font-weight: 300 700;
    font-style: normal;
    font-display: swap;
    unicode-range:
      U+0020-007E,      /* basic latin, digits, ascii punctuation */
      U+00A0-00FF,      /* latin-1 supplement */
      U+2010, U+2013-2014,
      U+2018-201D,
      U+2022, U+2026, U+2030, U+2032-2033,
      U+2039-203A, U+2044,
      U+20AC, U+2122, U+2212;
  }
}


/* ===========================================================================
   2. TOKENS
   ========================================================================= */
@layer tokens {
  :root {
    color-scheme: light;

    /* --- 2.1 Raw brand palette (guide page 07) ------------------------- */
    --night:        #171432;   /* شبِ ژیار */
    --night-900:    #0D0B1C;
    --night-700:    #322D55;
    --night-500:    #6B6590;
    --night-300:    #C9C3D8;
    --night-100:    #DEDCE8;

    --orange:       #D2811F;   /* نارنجی ژیار — SURFACE / FILL only on light */
    --orange-900:   #4A2A06;
    --orange-700:   #8E5210;   /* the ONLY orange permitted as text on light */
    --orange-300:   #EDB463;
    --orange-100:   #F8E3C4;

    --paper:        #FAF8F4;   /* کاغذ — default background */
    --white:        #FFFFFF;

    /* support greys, verbatim from the guide */
    --grey-700:     #5B5670;
    --grey-600:     #6E6980;
    --grey-500:     #8B8698;
    --grey-400:     #918CB0;
    --grey-300:     #B4AFCC;

    /* hairlines */
    --hair-paper:   #E4DFD6;
    --hair-card:    #EFEAE1;
    --hair-night:   #322D55;

    /* semantic — paper surfaces only, see spec §10 */
    --success:      #2F6B4F;
    --error:        #B0483A;

    /* --- 2.2 Semantic tokens (default context = PAPER) -----------------
       Components read ONLY these, never the raw palette above. Re-declaring
       them on .surface-night flips an entire subtree with zero overrides. */
    --bg:             var(--paper);
    --surface:        var(--white);        /* card on paper */
    --surface-sunk:   #F3F0EA;             /* wells, code blocks */
    --text:           var(--night);
    --text-strong:    var(--night-900);
    --text-muted:     var(--grey-700);     /* 6.58:1 on paper */
    --text-faint:     var(--night-500);    /* 5.09:1 on paper — labels only */
    --accent-text:    var(--orange-700);   /* 5.88:1 on paper */
    --accent-fill:    var(--orange);       /* SURFACE only */
    --accent-on-fill: var(--night-900);    /* 6.38:1 on orange — see spec §10 */
    --border:         var(--hair-card);    /* decorative */
    --border-strong:  var(--grey-500);     /* 3.32:1 — interactive boundaries */
    --link:           var(--orange-700);
    --link-hover:     var(--night);
    --focus-ring:     var(--night);        /* 16.74:1 on paper */
    --focus-halo:     var(--white);
    --select-bg:      var(--orange-100);
    --select-fg:      var(--orange-900);
    --logo-body:      currentColor;
    --logo-module:    var(--orange);
    --logo-latin:     var(--orange-700);

    /* --- 2.3 Type ------------------------------------------------------ */
    --font-fa:    "Vazirmatn", "Segoe UI", Tahoma, "Noto Naskh Arabic", system-ui, sans-serif;
    --font-latin: "Space Grotesk", "Vazirmatn", "Segoe UI", system-ui, sans-serif;
    --font-mono:  "Space Grotesk", ui-monospace, SFMono-Regular, Menlo, monospace;

    /* Fluid scale. Every clamp() hits the brand's desktop anchor EXACTLY at
       1440px and its mobile floor EXACTLY at 320px. Working:
         slope = (anchor − floor) / (1440 − 320)
         base  = floor − slope × 320                                        */
    --fs-hero:     clamp(2rem,      1.7143rem + 1.4286vw, 3.5rem);  /* 32 → 48@1440 → 56 cap */
    --fs-display:  clamp(1.75rem,   1.3929rem + 1.7857vw, 3rem);    /* 28 → 48@1440 → 48 cap */
    --fs-section:  clamp(1.375rem,  1.2321rem + 0.7143vw, 2.125rem);/* 22 → 30@1440 → 34 cap */
    --fs-subtitle: clamp(1.0625rem, 1.0089rem + 0.2679vw, 1.375rem);/* 17 → 20@1440 → 22 cap */
    --fs-body:     1rem;                                            /* 16 flat — see 2.3n */
    --fs-small:    0.8125rem;                                       /* 13 */
    --fs-label:    0.8125rem;                                       /* 13 · Latin/technical */
    --fs-stat:     clamp(2rem,      1.5714rem + 2.1429vw, 3.5rem);  /* 32 → 56@1440 → 56 cap */

    --fw-light:  300;
    --fw-body:   400;
    --fw-medium: 500;
    --fw-bold:   700;
    --fw-black:  900;   /* wordmark and very large numerals ONLY */

    /* Line heights. Guide values. 1.7 is the hard floor for anything prose. */
    --lh-hero:     1.3;
    --lh-display:  1.3;
    --lh-section:  1.4;
    --lh-subtitle: 1.6;   /* short subtitle/label runs only */
    --lh-lead:     1.75;  /* subtitle-SIZED prose — keeps the 1.7 Persian floor */
    --lh-body:     1.9;
    --lh-small:    1.7;
    --lh-ui:       1.6;  /* buttons/nav/pills — single line, clears ژ ی descenders */

    /* Persian measure — roughly 55–65 Persian characters. */
    --measure:       34em;
    --measure-tight: 28em;

    /* --- 2.4 Space — every step is a multiple of the logo module M -----
       M = width of one logo square = 14 units. The page is built out of the
       same unit the mark is built out of. Guide's observed values
       (10/14/18/22/24/44/48/60) all land within 2px of a step. */
    --m: 0.875rem;                   /* 14px = 1M */
    --sp-1:  0.25rem;   /*   4px */
    --sp-2:  0.4375rem; /*   7px = ½M  */
    --sp-3:  0.625rem;  /*  10px */
    --sp-4:  0.875rem;  /*  14px = 1M  */
    --sp-5:  1.3125rem; /*  21px = 1½M */
    --sp-6:  1.75rem;   /*  28px = 2M  */
    --sp-7:  2.625rem;  /*  42px = 3M  */
    --sp-8:  3.5rem;    /*  56px = 4M  */
    --sp-9:  5.25rem;   /*  84px = 6M  */
    --sp-10: 7rem;      /* 112px = 8M  */
    --sp-11: 10.5rem;   /* 168px = 12M */

    --gutter:    clamp(1.25rem, 0.9rem + 1.75vw, 2.5rem);   /* 20 → 40 */
    --section-y: clamp(3.5rem, 2.5rem + 4vw, 7rem);         /* 56 → 112 (4M → 8M) */
    --grid-gap:  clamp(1.3125rem, 1rem + 1.2vw, 2.625rem);  /* 21 → 42 (1½M → 3M) */

    --container:        75rem;   /* 1200 — content */
    --container-wide:   90rem;   /* 1440 — full-bleed inner cap */
    --container-narrow: 52rem;   /*  832 — team / prose blocks */
    --nav-h: 4rem;               /*   64 mobile; 72 from 768px (see 2.3n) */

    /* --- 2.5 Radii — guide runs 5–16px; 20px pill for status chips only */
    --r-xs:  5px;
    --r-sm:  8px;     /* buttons */
    --r-md:  10px;
    --r-lg:  12px;
    --r-xl:  14px;    /* cards */
    --r-2xl: 16px;    /* app-icon scale */
    --r-pill: 20px;   /* status chips ONLY */
    --r-quarter: 100%;/* the quarter-circle tile */

    /* --- 2.6 Elevation — the guide bans shadows on the LOGO, not on UI.
       Kept near-invisible: this brand is flat + hairline. */
    --shadow-sm:  0 1px 2px rgb(23 20 50 / 0.04);
    --shadow-md:  0 2px 6px rgb(23 20 50 / 0.05), 0 8px 24px rgb(23 20 50 / 0.05);
    --shadow-nav: 0 1px 0 var(--hair-paper);

    /* --- 2.7 Motion ---------------------------------------------------- */
    --dur-instant: 90ms;
    --dur-fast:    140ms;
    --dur-base:    240ms;
    --dur-slow:    420ms;
    --dur-grid:    900ms;   /* hero computational-grid step */
    --ease-out:    cubic-bezier(0.22, 0.61, 0.36, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
    --ease-snap:   cubic-bezier(0.16, 1, 0.30, 1);

    /* Scroll-reveal. ONE language, two verbs, one clock — mirrored in
       sections.js (GROUP_STAGGER 70ms, RING_STEP 46ms, RING_CAP 700ms).
         rise   (content) translateY(14px) → 0   · 520ms
         settle (modules) scale(.84)       → 1   · 360ms
       --rv-delay is written per element by sections.js. */
    --rv-ease:  cubic-bezier(0.16, 0.84, 0.44, 1);
    --rv-dur:   520ms;
    --rv-dur-module: 360ms;
    --rv-dist:  14px;

    /* --- 2.7n Hero lattice handshake ----------------------------------
       hero.js overwrites all five on the .hero element itself. The values
       here are the no-JS composition, and every consumer MUST supply the
       same fallback inline (a bare var() with no fallback inside calc()
       makes the whole declaration invalid at computed-value time). */
    --zh-pitch: 34px;
    --zh-tile:  28px;
    --zh-mark-reveal: 1;

    /* --- 2.8 Z-index --------------------------------------------------- */
    --z-base:   0;
    --z-raised: 10;
    --z-sticky: 100;
    --z-drawer: 200;
    --z-skip:   300;
  }

  /* --- 2.3n Step-ups that need a query rather than a clamp ------------- */
  @media (min-width: 768px)  { :root { --nav-h: 4.5rem; } }        /* 72 */
  @media (min-width: 1600px) { :root { --fs-body: 1.0625rem; } }   /* 17 */

  /* --- 2.9 Night surface context -------------------------------------- */
  .surface-night {
    color-scheme: dark;
    --bg:             var(--night);
    --surface:        var(--night-700);   /* card on night */
    --surface-sunk:   var(--night-900);
    --text:           var(--white);
    --text-strong:    var(--white);
    --text-muted:     var(--night-300);   /* 10.39:1 on night */
    --text-faint:     var(--grey-300);    /*  8.41:1 on night */
    --accent-text:    var(--orange-300);  /*  9.56:1 on night */
    --accent-fill:    var(--orange);
    --accent-on-fill: var(--night-900);
    --border:         var(--hair-night);
    --border-strong:  var(--night-500);
    --link:           var(--orange-300);
    --link-hover:     var(--white);
    --focus-ring:     var(--orange-300);  /*  9.56:1 on night */
    --focus-halo:     var(--night-900);
    --select-bg:      var(--orange);
    --select-fg:      var(--night-900);
    --logo-latin:     var(--orange-300);  /* #8E5210 is 2.85:1 on night — banned */
    background-color: var(--bg);
    color: var(--text);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  .surface-night-deep {
    --bg: var(--night-900);
    --surface: var(--night);
    background-color: var(--bg);
  }

  .surface-paper {
    color-scheme: light;
    --bg: var(--paper);
    --surface: var(--white);
    --text: var(--night);
    --text-muted: var(--grey-700);
    --text-faint: var(--night-500);
    --accent-text: var(--orange-700);
    --border: var(--hair-card);
    --border-strong: var(--grey-500);
    --link: var(--orange-700);
    --link-hover: var(--night);
    --focus-ring: var(--night);
    --focus-halo: var(--white);
    --select-bg: var(--orange-100);
    --select-fg: var(--orange-900);
    --logo-latin: var(--orange-700);
    background-color: var(--bg);
    color: var(--text);
  }
}


/* ===========================================================================
   3. RESET
   ========================================================================= */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  * { margin: 0; }

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    /* sticky nav must not cover an anchored heading */
    scroll-padding-block-start: calc(var(--nav-h) + var(--sp-5));
    tab-size: 2;
  }

  /* Smooth scrolling ONLY when motion is welcome. */
  @media (prefers-reduced-motion: no-preference) {
    html { scroll-behavior: smooth; }
  }

  body {
    min-block-size: 100vh;
    min-block-size: 100svh;
    background-color: var(--bg);
    color: var(--text);
    font-family: var(--font-fa);
    font-size: var(--fs-body);
    font-weight: var(--fw-body);
    line-height: var(--lh-body);
    /* NEVER letter-spacing on Persian — declared here so nothing inherits it */
    letter-spacing: normal;
    font-synthesis-weight: none;
    /* clip (not hidden/auto) so the sticky nav keeps working */
    overflow-x: clip;
  }

  img, picture, video, canvas, svg { display: block; max-inline-size: 100%; }
  img, video { block-size: auto; }

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

  p, h1, h2, h3, h4, h5, h6, li, dd, dt, figcaption {
    overflow-wrap: break-word;
    hyphens: none;           /* Persian never hyphenates */
  }

  ul[role="list"], ol[role="list"] { list-style: none; padding-inline-start: 0; }

  h1, h2, h3, h4 { font-weight: var(--fw-bold); text-wrap: balance; }
  p { text-wrap: pretty; }

  a { color: var(--link); text-underline-offset: 0.22em; text-decoration-thickness: from-font; }
  a:hover { color: var(--link-hover); }

  ::selection { background-color: var(--select-bg); color: var(--select-fg); }

  :focus { outline: none; }
  :focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
    border-radius: var(--r-xs);
    /* halo guarantees the ring stays ≥3:1 against whatever sits behind it */
    box-shadow: 0 0 0 6px var(--focus-halo);
  }

  /* Global motion kill-switch. */
  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.001ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.001ms !important;
      scroll-behavior: auto !important;
    }
  }
}


/* ===========================================================================
   4. BASE TYPOGRAPHY
   ========================================================================= */
@layer base {
  .t-hero     { font-size: var(--fs-hero);     line-height: var(--lh-hero);     font-weight: var(--fw-bold); }
  .t-display  { font-size: var(--fs-display);  line-height: var(--lh-display);  font-weight: var(--fw-bold); }
  .t-section  { font-size: var(--fs-section);  line-height: var(--lh-section);  font-weight: var(--fw-bold); }
  .t-subtitle { font-size: var(--fs-subtitle); line-height: var(--lh-subtitle); font-weight: var(--fw-medium); }
  .t-body     { font-size: var(--fs-body);     line-height: var(--lh-body);     font-weight: var(--fw-body); }
  .t-small    { font-size: var(--fs-small);    line-height: var(--lh-small);    font-weight: var(--fw-body); }
  /* .t-lead is running PROSE at subtitle size, so it takes the 1.7 Persian
     prose floor, not the scale's 1.6 subtitle value. --lh-subtitle stays 1.6
     for short subtitle/label runs, which is what the guide measured. */
  .t-lead {
    font-size: var(--fs-subtitle);
    line-height: var(--lh-lead);
    font-weight: var(--fw-body);
    color: var(--text-muted);
    max-inline-size: var(--measure);
  }

  h1 { font-size: var(--fs-hero);     line-height: var(--lh-hero); }
  h2 { font-size: var(--fs-section);  line-height: var(--lh-section); }
  h3 { font-size: var(--fs-subtitle); line-height: var(--lh-subtitle); font-weight: var(--fw-bold); }
  h4 { font-size: var(--fs-body);     line-height: var(--lh-subtitle); font-weight: var(--fw-bold); }

  /* Latin / technical opt-in. Tracking on Latin is permitted by the guide. */
  .font-latin, code, kbd, samp, pre {
    font-family: var(--font-latin);
    font-synthesis-weight: none;
  }
  code, kbd, samp {
    font-size: 0.9em;
    direction: ltr;
    unicode-bidi: isolate;
    background: var(--surface-sunk);
    border-radius: var(--r-xs);
    padding-inline: 0.35em;
    padding-block: 0.1em;
  }

  /* Every embedded Latin run is isolated so bidi cannot reorder it. */
  [dir="ltr"] { unicode-bidi: isolate; }
}


/* ===========================================================================
   5. LAYOUT ARCHITECTURE
   ========================================================================= */
@layer layout {
  .container {
    inline-size: 100%;
    max-inline-size: var(--container);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }
  .container--wide   { max-inline-size: var(--container-wide); }
  .container--narrow { max-inline-size: var(--container-narrow); }
  .container--prose  { max-inline-size: var(--measure); }

  .section { padding-block: var(--section-y); position: relative; isolation: isolate; }
  .section--tight { padding-block: var(--sp-8); }
  .section--band  { padding-block: var(--sp-8); }   /* the slogan band */
  .section--hero  { padding-block: var(--sp-9); }

  /* Section head: orange square marker + eyebrow, then the h2, then the lede.
     THE ONE OPENER. Every section below the hero uses exactly this, so the
     page has a single rhythm and the most-repeated orange element on the site
     costs almost no area — which is how a 10% budget should be spent. */
  .section__head { margin-block-end: var(--sp-7); max-inline-size: var(--measure); }
  .section__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-3);
    font-size: var(--fs-small);
    line-height: var(--lh-small);
    /* guide p08 type scale: "متن ریز و برچسب (small) 400 · 13/1.7".
       برچسب = label, so eyebrows are 400. Only .pill is 500 (guide p13). */
    font-weight: var(--fw-body);
    color: var(--accent-text);
    margin-block-end: var(--sp-3);
  }
  /* the module marker — a SOLID ORANGE SQUARE. 10px, matching .stat__marker.
     One value site-wide; never 8px, never a dot, never rounded. */
  .section__eyebrow::before {
    content: "";
    inline-size: 10px;
    block-size: 10px;
    background: var(--orange);
    flex: none;
  }

  /* h2 of a section. Brand section role: 700 · 30 / 1.4 at 1440. */
  .section__title {
    font-size: var(--fs-section);
    line-height: var(--lh-section);
    font-weight: var(--fw-bold);
    color: var(--text);
    max-inline-size: 20ch;
    text-wrap: balance;
  }
  /* the one-paragraph lede under a section title — running PROSE, so it takes
     the 1.7 Persian floor via --lh-lead (1.75), not the 1.6 subtitle value. */
  .section__lede {
    font-size: var(--fs-subtitle);
    line-height: var(--lh-lead);
    font-weight: var(--fw-body);
    color: var(--text-muted);
    max-inline-size: var(--measure);
    margin-block-start: var(--sp-4);
  }

  .grid { display: grid; gap: var(--grid-gap); grid-template-columns: repeat(12, minmax(0, 1fr)); }
  .autogrid {
    display: grid;
    gap: var(--grid-gap);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17.5rem), 1fr));
  }
  .autogrid--wide { grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr)); }
  .stack > * + * { margin-block-start: var(--flow, var(--sp-5)); }
  .cluster { display: flex; flex-wrap: wrap; gap: var(--sp-4); align-items: center; }

  /* Seam: a row of quarter-circle tiles at a Night↔Paper boundary.
     Colour comes from currentColor, so it inherits the section it sits in. */
  .seam {
    block-size: var(--m);
    display: grid;
    grid-template-columns: repeat(auto-fill, var(--m));
    overflow: clip;
  }
  .seam > i { background: currentColor; }
  .seam > i:nth-child(3n)   { border-start-start-radius: var(--r-quarter); }
  .seam > i:nth-child(4n+1) { background: transparent; }
  .seam > i:nth-child(11n)  { background: var(--orange); }
}


/* ===========================================================================
   6. COMPONENTS
   ========================================================================= */
@layer components {

  /* --- 6.1 Buttons (guide p13: radius 8, padding 11/22, 500 · 14) ------- */
  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-3);
    padding-block: 11px;
    padding-inline: 22px;
    min-block-size: 44px;          /* touch target — brand padding alone gives 39 */
    border-radius: var(--r-sm);
    border: 1px solid transparent;
    font-size: 0.875rem;           /* 14 */
    font-weight: var(--fw-medium);
    line-height: var(--lh-ui);
    letter-spacing: normal;        /* never on Persian */
    text-decoration: none;
    cursor: pointer;
    background: none;
    transition:
      background-color var(--dur-fast) var(--ease-out),
      border-color     var(--dur-fast) var(--ease-out),
      color            var(--dur-fast) var(--ease-out),
      transform        var(--dur-fast) var(--ease-out);
  }
  .btn:active { transform: translateY(1px); }
  .btn--lg { padding-block: 14px; padding-inline: 26px; font-size: 0.9375rem; min-block-size: 50px; }

  .btn--primary { background-color: var(--night); color: var(--white); }
  .btn--primary:hover { background-color: var(--night-700); color: var(--white); }
  .surface-night .btn--primary { background-color: var(--white); color: var(--night-900); }
  .surface-night .btn--primary:hover { background-color: var(--night-100); color: var(--night-900); }

  /* ACCENT — deliberate, documented deviation.
     Guide p13 specifies white text on Orange 500 = 3.04:1, which fails AA for
     14px/500 text. The guide's OWN accessibility rule keeps Orange 500 as a
     surface ("فقط برای سطح رنگی، دکمه و ماژول‌های لوگو"), so the fill stays
     brand-exact and the text colour is the free variable: Night 900 = 6.38:1. */
  .btn--accent {
    background-color: var(--orange);
    color: var(--night-900);
    font-weight: var(--fw-bold);
  }
  .btn--accent:hover { background-color: var(--orange-300); color: var(--night-900); }

  /* GHOST BORDER — the border IS the affordance, so it must clear SC 1.4.11's
     3:1 on whatever it actually sits on. Three values were proposed; this is
     the ruling, and it is different per surface because the physics are:
       · on Paper/white  #8B8698  = 3.32 / 3.52:1 ✓
         (the guide's #C9C3D8 is 1.71:1 on white — it FAILS, documented deviation)
       · on Night        #C9C3D8  = 9.25:1 over a Night-700 tile seen through
         the hero scrim, 8.19:1 worst case. This IS the guide's own ghost
         token, restored. The previously proposed #6B6590 measures only
         2.93:1 against that same composited backdrop — it fails. */
  .btn--ghost {
    background-color: var(--white);
    color: var(--night);
    border-color: var(--border-strong);
  }
  .btn--ghost:hover { background-color: var(--paper); border-color: var(--night-500); }
  .surface-night .btn--ghost {
    background-color: transparent;
    color: var(--white);
    border-color: var(--night-300);
  }
  .surface-night .btn--ghost:hover { background-color: var(--night-700); border-color: var(--white); }
  /* success / failure states for the clipboard button (sections.js) */
  .btn.is-done { border-color: var(--success); color: var(--success); }
  .btn.is-fail { border-color: var(--error);   color: var(--error); }
  .surface-night .btn.is-done { border-color: var(--orange-300); color: var(--orange-300); }
  .surface-night .btn.is-fail { border-color: var(--orange-300); color: var(--orange-300); }
  /* a copy button that cannot work is never rendered (sections.js proves the
     Clipboard API in a secure context before setting html[data-clip="on"]) */
  .btn--copy { display: none; }
  html[data-clip="on"] .btn--copy { display: inline-flex; }

  .btn--link {
    padding: 0; min-block-size: 0;
    color: var(--accent-text);
    text-decoration: underline;
    text-underline-offset: 0.25em;
  }

  /* --- 6.2 Status pill (guide p13) ------------------------------------- */
  .pill {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    background-color: var(--orange-100);
    color: var(--orange-900);          /* 10.32:1 */
    border-radius: var(--r-pill);
    padding-block: 5px;
    padding-inline: 12px;
    font-size: var(--fs-small);
    font-weight: var(--fw-medium);
    line-height: var(--lh-ui);
    letter-spacing: normal;
  }
  .pill::before {
    content: "";
    inline-size: 7px; block-size: 7px;
    background: var(--orange-700);
    flex: none;
  }
  .pill--quiet { background: var(--night-100); color: var(--night); }
  .pill--quiet::before { background: var(--night-500); }
  .surface-night .pill { background-color: var(--orange-900); color: var(--orange-100); }
  .surface-night .pill::before { background: var(--orange); }

  /* --- 6.3 Cards -------------------------------------------------------- */
  .card {
    background-color: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    padding: var(--sp-6);
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
  }
  .surface-night .card { border-color: rgb(255 255 255 / 0.07); }
  .card--flush { padding: 0; overflow: clip; }
  .card--link  { text-decoration: none; color: inherit; transition: border-color var(--dur-fast) var(--ease-out); }
  .card--link:hover { border-color: var(--border-strong); color: inherit; }
  /* one corner rounded to a quarter circle — the brand tile as a card */
  .card--tile { border-end-start-radius: 40%; }

  .card__title { font-size: var(--fs-subtitle); line-height: var(--lh-subtitle); font-weight: var(--fw-bold); color: var(--text); }
  .card__body  { color: var(--text-muted); }
  .card__icon  { inline-size: 40px; block-size: 40px; color: var(--text); }

  /* --- 6.4 Stat tile (guide p13) ----------------------------------------
     Big numeral in Space Grotesk 700 dir=ltr, orange square marker, thin bar.
     RULE: the bar is NEVER the sole carrier of a value — the numeral is always
     present, which is why the fill/track pair is exempt from SC 1.4.11.
     CONTENT RULE: only real, verifiable facts. No invented counts. */
  .stat { display: flex; flex-direction: column; gap: var(--sp-3); }
  .stat__marker { inline-size: 10px; block-size: 10px; background: var(--orange); }
  .stat__num {
    font-family: var(--font-latin);
    font-weight: var(--fw-bold);
    font-size: var(--fs-stat);
    line-height: 1.1;
    direction: ltr;
    unicode-bidi: isolate;
    text-align: start;               /* stays flush to the RTL start edge */
    font-variant-numeric: tabular-nums lining-nums;
    letter-spacing: -0.01em;         /* Latin only — permitted */
    color: var(--text-strong);
  }
  .stat__label { font-size: var(--fs-small); line-height: var(--lh-small); color: var(--text-muted); }
  .stat__bar {
    block-size: 6px;
    background: var(--night-100);
    border-radius: var(--r-xs);
    overflow: clip;
    box-shadow: inset 0 0 0 1px var(--grey-500);  /* makes the bar itself perceivable */
  }
  .surface-night .stat__bar { background: var(--night-700); box-shadow: none; }
  .stat__fill {
    block-size: 100%;
    inline-size: var(--value, 0%);
    background: var(--orange);
    border-radius: inherit;
  }

  /* --- 6.5 Nav — sticky, RTL, ZERO JavaScript, zero hidden state ---------
     A single-page site with ~6 anchors does not need a disclosure widget.
     The link row scrolls horizontally on narrow viewports and simply fits
     from 768px up. No [open] state, no ARIA to keep in sync, no engine
     dependency, keyboard-native, and every destination stays visible. */
  .nav {
    position: sticky;
    inset-block-start: 0;
    z-index: var(--z-sticky);
    background-color: var(--paper);
    box-shadow: var(--shadow-nav);
  }
  @supports (background: color-mix(in srgb, red 50%, transparent)) {
    .nav { background-color: color-mix(in srgb, var(--paper) 90%, transparent); }
  }
  @supports (backdrop-filter: blur(2px)) {
    .nav { backdrop-filter: saturate(1.4) blur(12px); }
  }

  .nav__bar {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    min-block-size: var(--nav-h);
  }
  /* DOM order: brand first → in dir="rtl" it renders at the inline-start (right). */
  .nav__brand { flex: none; display: inline-flex; align-items: center; text-decoration: none; color: var(--night); }

  .nav__scroll {
    flex: 1 1 auto;
    min-inline-size: 0;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* fade at the overflowing edge = the scroll affordance */
    mask-image: linear-gradient(to left, #000 calc(100% - 2rem), transparent);
  }
  .nav__scroll::-webkit-scrollbar { display: none; }

  .nav__list {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    list-style: none;
    padding: 0;
    margin: 0;
    inline-size: max-content;
  }
  .nav__link {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex: none;
    white-space: nowrap;
    min-block-size: 44px;
    padding-inline: var(--sp-4);
    border-radius: var(--r-sm);
    font-size: 0.9375rem;
    font-weight: var(--fw-body);
    line-height: var(--lh-ui);
    letter-spacing: normal;
    color: var(--night);
    text-decoration: none;
    transition: background-color var(--dur-fast) var(--ease-out),
                color            var(--dur-fast) var(--ease-out);
  }
  .nav__link:hover { background-color: var(--night-100); color: var(--night); }

  /* Reserve the ACTIVE (500) width up front so promoting a link from 400 to
     500 never nudges its neighbours. Vazirmatn is variable, so the weight
     change itself is smooth and free. */
  .nav__link::before {
    content: attr(data-label);
    font-weight: var(--fw-medium);
    display: block;
    block-size: 0;
    overflow: hidden;
    visibility: hidden;
  }
  /* the scroll-spy indicator: a 2px orange RULE — orange as a shape, never as
     the link text, so the orange-on-light text ban is untouched */
  .nav__link::after {
    content: "";
    position: absolute;
    inset-inline: var(--sp-3);
    inset-block-end: 6px;
    block-size: 2px;
    background: var(--orange);
    transform: scaleX(0);
    transform-origin: inline-end;      /* grows right → left, with the reading direction */
    transition: transform var(--dur-base) var(--rv-ease);
  }
  .nav__link.is-active { font-weight: var(--fw-medium); color: var(--text-strong); }
  .nav__link.is-active::after { transform: scaleX(1); }
  @media (prefers-reduced-motion: reduce) { .nav__link::after { transition: none; } }

  .nav__cta { flex: none; display: none; }

  /* Over the Night hero. The OPAQUE bar is the default AND the no-JS state:
     Paper + Night text is legible over any background, and sections.js only
     ever REMOVES it. The failure mode is a plain readable bar, never white
     text on Paper. */
  html.nav-over-hero .nav {
    background-color: transparent;
    box-shadow: none;
    backdrop-filter: none;
  }
  html.nav-over-hero .nav__brand,
  html.nav-over-hero .nav__link { color: var(--paper); }
  html.nav-over-hero .nav__link:hover { background-color: rgb(255 255 255 / 0.10); color: var(--paper); }
  html.nav-over-hero .nav__link.is-active { color: var(--paper); }
  html.nav-over-hero .nav { --focus-ring: var(--orange-300); --focus-halo: var(--night-900); }

  @media (min-width: 768px) {
    .nav__scroll { overflow-x: visible; mask-image: none; display: flex; justify-content: flex-end; }
    .nav__list { gap: var(--sp-2); }
  }
  @media (min-width: 1024px) {
    .nav__cta { display: inline-flex; }
  }
  @media (min-width: 1440px) {
    .nav__bar { gap: var(--sp-6); }
  }

  .skip-link {
    position: absolute;
    inset-block-start: var(--sp-3);
    inset-inline-start: var(--sp-3);
    z-index: var(--z-skip);
    transform: translateY(-250%);
    background: var(--night);
    color: var(--white);
    padding: var(--sp-3) var(--sp-5);
    border-radius: var(--r-sm);
    text-decoration: none;
    font-size: var(--fs-small);
  }
  .skip-link:focus-visible { transform: none; color: var(--white); }

  /* --- 6.6 Logo ---------------------------------------------------------
     Body stroke = currentColor (follows the surrounding text colour).
     Modules    = var(--logo-module), orange by default.
     .is-mono   = modules adopt currentColor too.                           */
  .logo {
    display: inline-flex;
    align-items: center;
    gap: var(--logo-gap, 0.5em);
    color: var(--text);
    text-decoration: none;
  }
  .logo__mark {
    inline-size: var(--logo-size, 40px);
    block-size: var(--logo-size, 40px);
    flex: none;
    overflow: visible;
  }
  .logo__mark .logo-body   { stroke: var(--logo-body); }
  .logo__mark .logo-module { fill: var(--logo-module); }
  .logo.is-mono { --logo-module: currentColor; }

  .logo__word {
    font-family: var(--font-fa);
    font-weight: var(--fw-black);
    font-size: var(--logo-word-size, 1.5rem);
    line-height: 1.15;
    letter-spacing: normal;   /* Persian — never tracked */
    color: currentColor;
  }
  .logo__stack { display: flex; flex-direction: column; align-items: flex-start; gap: 0.12em; }

  /* Lockup 3 — subtitle capped at 40% of «ژیار» by the brand rule.
     MUST be calc() off --logo-word-size, not `em`: .logo__sub is a SIBLING of
     .logo__word, so `em` would resolve against .logo__stack (16px) and silently
     render the subtitle at ~25% instead of 38%. */
  .logo__sub {
    font-size: calc(var(--logo-word-size, 1.5rem) * 0.38);
    font-weight: var(--fw-medium);
    line-height: 1.4;
    color: var(--text-muted);
    letter-spacing: normal;
  }
  /* Lockup 4 — ZHIAR, Space Grotesk, 0.3em tracking (Latin: permitted). */
  .logo__latin {
    font-family: var(--font-latin);
    font-size: calc(var(--logo-word-size, 1.5rem) * 0.34);
    font-weight: var(--fw-medium);
    line-height: 1.4;
    letter-spacing: 0.3em;
    margin-inline-end: -0.3em;     /* cancel the trailing tracking space */
    color: var(--logo-latin);
    direction: ltr;
    unicode-bidi: isolate;
  }
  .logo.is-mono .logo__latin { color: currentColor; }

  .logo--vertical { flex-direction: column; gap: 0.4em; text-align: center; }
  .logo--vertical .logo__stack { align-items: center; }
  .logo--sm { --logo-size: 28px; --logo-word-size: 1.125rem; }
  .logo--lg { --logo-size: 64px; --logo-word-size: 2.25rem; }
  /* Lockups 3 and 4 carry a second line, so they need a larger base to stay
     legible while still honouring the ≤40% cap. The brand minimum lockup size
     is 80px, so these are never used small anyway. */
  .logo--formal,
  .logo--bilingual { --logo-size: 56px; --logo-word-size: 2rem; }
  /* Clear space = one module M per side. M = 14% of the mark's box. */
  .logo--clearspace { padding: calc(var(--logo-size, 40px) * 0.14); }

  /* App-icon lockup: Night square, ~24% radius, white body + orange modules. */
  .logo-appicon {
    inline-size: var(--appicon-size, 68px);
    block-size: var(--appicon-size, 68px);
    border-radius: calc(var(--appicon-size, 68px) * 0.24);
    background: var(--night);
    color: var(--white);
    display: grid;
    place-items: center;
    --logo-module: var(--orange);
  }
  .logo-appicon .logo__mark { --logo-size: calc(var(--appicon-size, 68px) * 0.62); }

  /* --- 6.7 Team ----------------------------------------------------------
     Two people centred in a 1200px row is the classic startup-template look:
     two cards floating in a sea of white. THE SECTION HEADER IS THE THIRD
     COLUMN. The row is then full of meaning instead of air, the header sits
     at the reading start (right), and the two people read as a list that
     continues from it rather than as an isolated pair.

     The grid is explicit, never auto-fit: auto-fit flipped to 2-up around
     740px while each card was still only ~336px wide, which crushed the bio
     column to 97px. The card is VERTICAL (portrait above text) at every
     width — a side-by-side avatar cannot coexist with a narrow column. */
  .team {
    display: grid;
    gap: var(--grid-gap);
    grid-template-columns: 1fr;
    align-items: start;
  }
  @media (min-width: 44rem) {  /* 704 — two people side by side */
    .team { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .team__head { grid-column: 1 / -1; margin-block-end: var(--sp-3); }
  }
  @media (min-width: 65rem) {  /* 1040 — header becomes the third column */
    .team { grid-template-columns: minmax(12.5rem, 0.8fr) repeat(2, minmax(0, 1fr)); }
    .team__head { grid-column: auto; margin-block-end: 0; }
  }
  .team__head .section__lede { margin-block-start: var(--sp-4); }

  .person {
    --avatar-size: min(100%, 14rem);
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    padding: var(--sp-6);
  }
  @media (min-width: 64rem) { .person { padding: var(--sp-7); gap: var(--sp-6); } }

  .person__name { font-size: var(--fs-subtitle); font-weight: var(--fw-bold); line-height: var(--lh-subtitle); }
  .person__role { font-size: var(--fs-small); line-height: var(--lh-small); color: var(--accent-text); font-weight: var(--fw-medium); }
  .person__bio  { color: var(--text-muted); }
  .person__bio li { margin-block-start: var(--sp-2); }

  /* Opt-in horizontal variant — ONLY valid in a full-width 1-up team list. */
  .person--row { --avatar-size: 10rem; }
  @media (min-width: 30rem) {
    .person--row { display: grid; grid-template-columns: 10rem 1fr; align-items: start; }
  }

  /* --- 6.8 Portrait frame + placeholder -----------------------------------
     THE SWAP: replace the single <span class="avatar__ph">…</span> with
     <img class="avatar__img" src="…" alt="…">. Nothing else changes.

     ONE REAL PHOTO NOW EXISTS (محمد یوسفی) and one does not (سمیه باجلانی),
     so the two cards must read as a coherent PAIR with only one of them
     photographic. What makes them a pair is everything OUTSIDE the image:
     identical 4:5 frame, identical radius, identical Night ground, and the
     same offset orange quarter-circle tile escaping the block-start corner.
     That tile is on .avatar, not on the placeholder, so it survives the swap.

     There is deliberately NO "photo pending" caption. The client's late
     direction bans «به‌زودی» anywhere on the site, and a caption would also
     make the placeholder read as unfinished work rather than as brand
     geometry. The placeholder is a designed portrait tile built from the
     brand's two shapes — square and quarter circle — and nothing else. */
  .avatar {
    position: relative;
    inline-size: 100%;
    max-inline-size: var(--avatar-size, 13rem);
    aspect-ratio: 4 / 5;
    border-radius: var(--r-xl);
    /* NO overflow:clip here — the offset brand tile must escape the frame. */
  }
  /* quarter-circle brand tile peeking out behind the outer block-start corner */
  .avatar::before {
    content: "";
    position: absolute;
    z-index: 0;
    inset-block-start: calc(var(--sp-3) * -1);
    inset-inline-end: calc(var(--sp-3) * -1);
    inline-size: var(--sp-6);
    block-size: var(--sp-6);
    background: var(--orange);
    border-end-start-radius: var(--r-quarter);
  }
  .avatar__img,
  .avatar__ph {
    position: absolute;
    inset: 0;
    z-index: 1;
    inline-size: 100%;
    block-size: 100%;
    border-radius: inherit;
    overflow: clip;
    object-fit: cover;
    object-position: center 20%;
    background: var(--night);
  }
  .avatar__ph { display: block; }
  .avatar__ph > svg { inline-size: 100%; block-size: 100%; display: block; }

  /* --- 6.9 Footer -------------------------------------------------------- */
  .footer { padding-block: var(--sp-8) var(--sp-6); font-size: var(--fs-small); line-height: var(--lh-small); }
  .footer__grid {
    display: grid;
    gap: var(--sp-6);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    padding-block-end: var(--sp-6);
    border-block-end: 1px solid var(--border);
  }
  .footer__title { font-size: var(--fs-small); font-weight: var(--fw-bold); color: var(--text); margin-block-end: var(--sp-3); }
  .footer__list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-2); }
  .footer__list a { color: var(--text-muted); text-decoration: none; }
  .footer__list a:hover { color: var(--text); text-decoration: underline; }
  .footer__addr { font-style: normal; color: var(--text-muted); max-inline-size: var(--measure); }
  .footer__legal {
    padding-block-start: var(--sp-5);
    display: flex; flex-wrap: wrap;
    gap: var(--sp-4) var(--sp-6);
    justify-content: space-between;
    color: var(--text-faint);
  }

  /* --- 6.10 Brand tile field (square + quarter circle) -------------------- */
  .tilefield {
    --tile: 28px;
    display: grid;
    grid-template-columns: repeat(auto-fill, var(--tile));
    grid-auto-rows: var(--tile);
    gap: 0;
    overflow: clip;
  }
  .tile         { background: var(--night-700); }
  .tile--empty  { background: transparent; }
  .tile--orange { background: var(--orange); }
  .tile--qc-ss  { border-start-start-radius: var(--r-quarter); }
  .tile--qc-se  { border-start-end-radius:   var(--r-quarter); }
  .tile--qc-es  { border-end-start-radius:   var(--r-quarter); }
  .tile--qc-ee  { border-end-end-radius:     var(--r-quarter); }

  /* --- 6.11 Scroll reveal ------------------------------------------------
     THE NO-JS GUARANTEE, EXACTLY: the base stylesheet renders every element
     in its FINAL, VISIBLE state. The hidden pre-state exists only inside a
     DOUBLE GATE — `html.js` AND prefers-reduced-motion: no-preference — and
     `js` is live-checked by a 1200ms watchdog in the inline <head> bootstrap,
     which strips it again unless sections.js sets
     document.documentElement.dataset.reveal = 'ready'.
       JS disabled          → `js` never added → nothing was ever hidden ✓
       sections.js 404/CSP  → watchdog strips `js` after 1.2s ✓
       IntersectionObserver missing → the module removes `js` itself ✓
       reduce               → this whole block does not exist ✓            */
  @media (prefers-reduced-motion: no-preference) {
    html.js .reveal {
      opacity: 0;
      transform: translate3d(0, var(--rv-dist), 0);
      transition: opacity   var(--rv-dur) var(--rv-ease) var(--rv-delay, 0ms),
                  transform var(--rv-dur) var(--rv-ease) var(--rv-delay, 0ms);
    }
    html.js .reveal.is-in { opacity: 1; transform: none; }

    /* settle — modules scale rather than rise */
    html.js .reveal--module {
      transform: scale(0.84);
      transform-origin: center;
      --rv-dur: var(--rv-dur-module);
    }
    html.js .reveal--module.is-in { transform: none; }
  }
}


/* ===========================================================================
   7. UTILITIES
   ========================================================================= */
@layer utilities {
  .sr-only {
    position: absolute !important;
    inline-size: 1px; block-size: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap; border: 0;
  }
  .u-ltr        { direction: ltr; unicode-bidi: isolate; }
  .u-nums-latin { font-family: var(--font-latin); font-variant-numeric: tabular-nums lining-nums; direction: ltr; unicode-bidi: isolate; }
  .u-measure    { max-inline-size: var(--measure); }
  .u-center     { margin-inline: auto; }
  .u-muted      { color: var(--text-muted); }
  .u-accent     { color: var(--accent-text); }
  .u-nowrap     { white-space: nowrap; }
  .u-no-track   { letter-spacing: normal; }
  .u-flow-sm    { --flow: var(--sp-3); }
  .u-flow-lg    { --flow: var(--sp-7); }
  .u-hide-below-md { display: none; }
  @media (min-width: 768px) {
    .u-hide-below-md { display: revert; }
    .u-hide-from-md  { display: none; }
  }
}


/* ===========================================================================
   8. PREFERENCE QUERIES
   ========================================================================= */

/* 8.1 DARK MODE — deliberately NOT an inversion. Rationale in spec §9.
   Two concessions only: soften pure-white card fills toward Paper and deepen
   the Night sections. Hue, ratio and hierarchy are untouched. */
@media (prefers-color-scheme: dark) {
  /* .surface-paper must be listed explicitly: it re-declares --surface to
     restore the paper context after a night section, which would otherwise
     shadow this override and leave its cards pure white. */
  :root, .surface-paper {
    --surface:      #F6F3EE;   /* was #FFFFFF — 18.0:1 with Night, still AAA */
    --surface-sunk: #EFEBE3;
    --hair-card:    #E4DFD6;   /* one step stronger so cards still read */
  }
  .surface-night      { --bg: var(--night-900); }
  .surface-night-deep { --bg: #08070F; }
}

/* 8.2 Increased contrast */
@media (prefers-contrast: more) {
  :root {
    --text-muted:    var(--night);
    --text-faint:    var(--grey-700);
    --border:        var(--grey-500);
    --border-strong: var(--night-500);
  }
  .surface-night {
    --text-muted: var(--white);
    --text-faint: var(--night-100);
    --border:     var(--night-500);
  }
  a { text-decoration: underline; }
  .card, .person { border-width: 2px; }
}

/* 8.3 Forced colours (Windows High Contrast) */
@media (forced-colors: active) {
  .btn { border: 1px solid ButtonBorder; }
  .logo__mark .logo-module { fill: CanvasText; }
  .logo__mark .logo-body   { stroke: CanvasText; }
  .avatar::before, .stat__marker, .section__eyebrow::before { forced-color-adjust: none; }
  :focus-visible { outline-color: Highlight; box-shadow: none; }
}

/* 8.4 Print
   Backgrounds are not printed by default, so every Paper-on-Night surface
   must be re-coloured or it prints white-on-white. Note #EDB463 on white is
   1.9:1 — the slogan has to fall back to the text-on-light orange, #8E5210
   (5.88:1), which is exactly the guide's own rule. */
@media print {
  .nav, .skip-link, .tilefield, .seam,
  .hero__fallback, .hero__field, .hero__scrim, .hero__motion,
  .mg, .loc, .postal, .btn--copy { display: none; }

  .surface-night, .surface-night-deep { background: #fff; color: #171432; }
  .surface-night .section__title,
  .surface-night .section__lede,
  .surface-night .goal__mission,
  .surface-night .addr,
  .surface-night .values__item { color: #171432; }
  .surface-night .section__eyebrow { color: #8E5210; }

  .hero { background: #fff; min-block-size: auto; }
  .hero__title, .hero__eyebrow, .hero__lead { color: #171432; }
  .hero__slogan { color: #8E5210; }               /* Orange-700 — 5.88:1 on white */
  .hero__mark { opacity: 1 !important; }
  .btn { background: none !important; color: #171432 !important; border-color: #171432 !important; }

  .section { padding-block: 1.2cm; break-inside: avoid; }
  .reveal { opacity: 1 !important; transform: none !important; }
  a[href^="http"]::after,
  a[href^="mailto"]::after { content: " (" attr(href) ")"; font-size: 0.75em; }
}
