/* ==========================================================================
   EDIC Design Tokens  —  v3
   --------------------------------------------------------------------------
   The single source of truth for colour, type, space, radius and motion.

   Every value in this file is deliberate and every value is used. Nothing
   here may be overridden by a page-level stylesheet; if a page needs a value
   that is not in this file, the correct fix is to add it here once.

   Namespace: --ed-*   (deliberately distinct from the legacy --brand-*,
   --op-*, --ms-*, --epr-* tokens so the two systems cannot collide during
   the migration.)
   ========================================================================== */

/* ==========================================================================
   BOX MODEL
   Bootstrap's Reboot supplied `*,::after,::before{box-sizing:border-box}`, and
   deleting bootstrap.min.css took it with it - which silently flipped every
   element in the portal to content-box. Most of the layout is grid and flex
   with auto sizing, so it stayed invisible; it shows up wherever an explicit
   size meets padding, such as two .h-100 cards that then failed to match
   height because each added its own padding on top of the 100%.

   It lives in this file for the same reason the reduced-motion guarantee
   does: this is the only stylesheet every page loads, standalone
   error_base.html and bi/panel_unavailable.html included.
   ========================================================================== */

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

/* ==========================================================================
   SELF-HOSTED FACES
   The factory LAN has no guaranteed route to the public internet, so every
   face the portal depends on is declared against a file in static/fonts/.
   Without this rule the preload in base.html fetches Vazirmatn and then
   nothing claims it, and Persian silently falls back to Tahoma.
   ========================================================================== */

@font-face {
    font-family: "Vazirmatn";
    src: url("../fonts/vazirmatn/Vazirmatn-Variable.woff2") format("woff2-variations"),
         url("../fonts/vazirmatn/Vazirmatn-Variable.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

/* Inter, split the way Google splits it: the Latin subset covers everything
   the English portal actually renders, and latin-ext is only fetched if a
   character needs it. Both are variable, so one file serves every weight in
   the type scale rather than the seven static files the CDN link requested. */
@font-face {
    font-family: "Inter";
    src: url("../fonts/inter/Inter-Variable-latin.woff2") format("woff2-variations"),
         url("../fonts/inter/Inter-Variable-latin.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
                   U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
                   U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
                   U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Inter";
    src: url("../fonts/inter/Inter-Variable-latin-ext.woff2") format("woff2-variations"),
         url("../fonts/inter/Inter-Variable-latin-ext.woff2") format("woff2");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
                   U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
                   U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
                   U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    /* ---------------------------------------------------------------------
       BRAND
       Sampled from the Espandar logo master (#00B0F0). The 700 step is the
       interactive default because it is the lightest step that clears
       WCAG AA (5.19:1) against white with white text.
       --------------------------------------------------------------------- */
    --ed-azure-50:  #eff9fe;
    --ed-azure-100: #d8f1fc;
    --ed-azure-200: #aae3f9;
    --ed-azure-300: #6fd1f5;
    --ed-azure-400: #2abef3;
    --ed-azure-500: #00b0f0;   /* brand identity colour */
    --ed-azure-600: #0092cc;
    --ed-azure-700: #00759f;   /* interactive default */
    --ed-azure-800: #0a5c7c;
    --ed-azure-900: #0e4a63;

    --ed-violet-500: #6e3ae0;  /* secondary brand accent, used sparingly */
    --ed-navy-900:   #001028;

    /* ---------------------------------------------------------------------
       NEUTRALS
       A single cool-grey ramp. These are the only greys in the system.

       500 and 600 are darker than the palette they started from. They carry
       --ed-text-tertiary and --ed-text-secondary, and at #86868b/#6e6e73
       those failed WCAG AA against the surfaces they actually sit on -
       3.05:1 for tertiary on the canvas, where 4.5:1 is the floor for text
       this size. 600 is moved further than AA alone requires so the three
       text weights stay tellable apart; matching them to the minimum put
       secondary and tertiary on the same value.
       --------------------------------------------------------------------- */
    --ed-grey-0:   #ffffff;
    --ed-grey-50:  #f5f5f7;
    --ed-grey-100: #ebebef;
    --ed-grey-200: #e0e0e5;
    --ed-grey-300: #d2d2d7;
    --ed-grey-400: #aeaeb2;
    --ed-grey-500: #6a6a6f;
    --ed-grey-600: #55555a;
    --ed-grey-700: #48484a;
    --ed-grey-800: #2c2c2e;
    --ed-grey-900: #1d1d1f;

    /* ---------------------------------------------------------------------
       STATUS
       --------------------------------------------------------------------- */
    --ed-green-500:  #217f38;
    --ed-green-tint: #e8f6ec;
    --ed-amber-500:  #a45e00;
    --ed-amber-tint: #fdf1e0;
    --ed-red-500:    #c8102e;
    --ed-red-tint:   #fdecee;

    /* ---------------------------------------------------------------------
       SEMANTIC SURFACES  (light theme)
       Components reference ONLY these, never the ramps above.
       --------------------------------------------------------------------- */
    --ed-canvas:          var(--ed-grey-50);
    --ed-surface:         var(--ed-grey-0);
    --ed-surface-sunken:  var(--ed-grey-50);
    --ed-surface-hover:   var(--ed-grey-50);
    --ed-fill-subtle:     var(--ed-grey-100);

    --ed-text:            var(--ed-grey-900);
    --ed-text-secondary:  var(--ed-grey-600);
    --ed-text-tertiary:   var(--ed-grey-500);
    --ed-text-on-accent:  #ffffff;

    --ed-separator:       var(--ed-grey-300);
    --ed-separator-soft:  var(--ed-grey-200);

    --ed-accent:          var(--ed-azure-700);
    --ed-accent-hover:    var(--ed-azure-800);
    --ed-accent-tint:     var(--ed-azure-50);
    --ed-accent-ring:     rgba(0, 176, 240, .38);

    --ed-success:         var(--ed-green-500);
    --ed-success-tint:    var(--ed-green-tint);
    --ed-warning:         var(--ed-amber-500);
    --ed-warning-tint:    var(--ed-amber-tint);
    --ed-danger:          var(--ed-red-500);
    --ed-danger-tint:     var(--ed-red-tint);

    /* ---------------------------------------------------------------------
       TYPOGRAPHY
       Five sizes. Named by role, not by size, so that a change of scale
       never requires a change of markup.

       It was ten. Ten was more steps than the portal had distinctions to
       make, and counting the real call sites showed where: three of them
       (15/13/12/11px) sat inside a 4px band and carried 82 of 105 usages,
       so the step a component picked out of that band was arbitrary rather
       than meaningful - which is exactly what made the UI look unresolved.
       Two more were dead weight: `headline` held the same value as `body`
       and differed only by weight, and `callout` split the 1px between
       `body` and `subhead`.

       The merges, and what carries the distinction each one used to:
         display  <- display + title-1     page title, hero figure
         title    <- title-2 + title-3     section and card heading
         body     <- headline + callout    weight now separates headline
         subhead  <- subhead + footnote    colour already separated metadata
         caption                           labels, overlines, badges

       Secondary text is the important one: `.ed-row-meta`, `.ed-stat-label`
       and their kin never relied on the 1px drop from subhead to footnote.
       Every one of them already sets --ed-text-secondary, and colour is the
       stronger signal at that size. The size step was doing nothing.
       --------------------------------------------------------------------- */
    --ed-font: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Text",
               "Segoe UI", Roboto, sans-serif;
    --ed-font-fa: "Vazirmatn", "Inter", -apple-system, BlinkMacSystemFont,
                  "Segoe UI", Tahoma, sans-serif;
    --ed-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;

    /* Tabular figures for every number that sits in a column or a KPI. */
    --ed-numeric: "tnum" 1, "lnum" 1;

    /* The metric step exists so a dashboard has a focal layer. A KPI figure
       and a page title were both --ed-text-display, which left every screen
       with two dozen equally loud 24px things and nothing to read first. */
    --ed-text-metric:  2rem;      /* 32px  KPI figure, the first thing read */
    --ed-text-display: 1.5rem;    /* 24px  page title                      */
    --ed-text-title:   1.125rem;  /* 18px  section and card heading        */
    --ed-text-body:    0.9375rem; /* 15px  default reading size, controls  */
    --ed-text-subhead: 0.8125rem; /* 13px  dense UI, tables, metadata      */
    --ed-text-caption: 0.6875rem; /* 11px  labels, overlines, badges       */

    --ed-leading-tight: 1.15;
    --ed-leading-snug:  1.3;
    --ed-leading-body:  1.5;

    --ed-weight-regular:  400;
    --ed-weight-medium:   500;
    --ed-weight-semibold: 600;

    /* Optical tracking: large text tightens, small text opens up. */
    --ed-tracking-display: -0.022em;
    --ed-tracking-title:   -0.014em;
    --ed-tracking-body:    -0.005em;
    --ed-tracking-caption:  0.005em;
    --ed-tracking-overline: 0.06em;

    /* ---------------------------------------------------------------------
       SPACE  —  4pt base
       --------------------------------------------------------------------- */
    --ed-space-1:  0.25rem;   /*  4 */
    --ed-space-2:  0.5rem;    /*  8 */
    --ed-space-3:  0.75rem;   /* 12 */
    --ed-space-4:  1rem;      /* 16 */
    --ed-space-5:  1.25rem;   /* 20 */
    --ed-space-6:  1.5rem;    /* 24 */
    --ed-space-8:  2rem;      /* 32 */
    --ed-space-10: 2.5rem;    /* 40 */
    --ed-space-12: 3rem;      /* 48 */
    --ed-space-16: 4rem;      /* 64 */

    /* ---------------------------------------------------------------------
       RADIUS  —  three steps and a pill. That is the whole set.
       --------------------------------------------------------------------- */
    --ed-radius-sm:   8px;
    --ed-radius-md:   12px;
    --ed-radius-lg:   18px;
    --ed-radius-pill: 999px;

    /* ---------------------------------------------------------------------
       ELEVATION
       Depth comes from hairlines and background contrast, not from shadow.
       Shadow is reserved for surfaces that genuinely float above the page.
       --------------------------------------------------------------------- */
    --ed-shadow-raised:  0 1px 2px rgba(0, 0, 0, .04),
                         0 4px 12px rgba(0, 0, 0, .06);
    --ed-shadow-overlay: 0 8px 28px rgba(0, 0, 0, .12),
                         0 2px 6px rgba(0, 0, 0, .08);

    /* ---------------------------------------------------------------------
       MOTION
       --------------------------------------------------------------------- */
    --ed-ease:      cubic-bezier(0.22, 0.61, 0.36, 1);
    --ed-duration:  180ms;

    /* Layout */
    --ed-measure: 68ch;          /* max line length for prose */
    --ed-sidebar-width: 264px;
    --ed-topbar-height: 60px;
}

/* ==========================================================================
   DARK THEME
   Only the semantic layer is redefined, apart from the three tints, which
   the ramp restates as translucent so they read on a dark surface.
   ========================================================================== */
[data-theme="dark"] {
    --ed-canvas:          #000000;
    --ed-surface:         #1c1c1e;
    --ed-surface-sunken:  #141416;
    --ed-surface-hover:   #2c2c2e;
    --ed-fill-subtle:     #2c2c2e;

    --ed-text:            #f5f5f7;
    --ed-text-secondary:  #b0b0b5;
    --ed-text-tertiary:   #949499;

    --ed-separator:       #38383a;
    --ed-separator-soft:  #2c2c2e;

    --ed-accent:          var(--ed-azure-400);
    --ed-accent-hover:    var(--ed-azure-300);
    --ed-accent-tint:     rgba(0, 176, 240, .14);
    --ed-text-on-accent:  #001028;

    --ed-green-tint:      rgba(48, 209, 88, .16);
    --ed-amber-tint:      rgba(255, 159, 10, .16);
    --ed-red-tint:        rgba(255, 69, 58, .16);
    --ed-success:         #30d158;
    --ed-warning:         #ff9f0a;
    --ed-danger:          #ff5a50;

    --ed-shadow-raised:   0 1px 2px rgba(0, 0, 0, .5),
                          0 4px 12px rgba(0, 0, 0, .4);
    --ed-shadow-overlay:  0 8px 28px rgba(0, 0, 0, .6),
                          0 2px 6px rgba(0, 0, 0, .5);
}

/* ==========================================================================
   PERSIAN TYPOGRAPHY
   Vazirmatn carries a larger x-height than Inter, so at an identical px
   value Persian text reads noticeably heavier and more crowded.

   That correction is a HEADING correction, not a blanket one. It only pays
   for itself where a run of text is large enough for the extra mass to
   show; at UI sizes the same subtraction takes away room that Vazirmatn's
   dots and diacritics actually need, so the two scales deliberately
   converge at body and share every step below it. Restating those steps
   here at a smaller value is what made Persian metadata harder to read than
   the English it translates.

   The leading still opens across the board - that is the lever that makes
   Persian breathe, and it costs no legibility.
   ========================================================================== */
[lang="fa"] {
    --ed-font: var(--ed-font-fa);

    --ed-text-metric:  1.875rem;  /* 30px */
    --ed-text-display: 1.375rem;  /* 22px */
    --ed-text-title:   1.0625rem; /* 17px */
    /* body and below are shared with Latin - see above. */

    --ed-leading-tight: 1.35;
    --ed-leading-snug:  1.55;
    --ed-leading-body:  1.8;

    /* Persian does not use optical tracking the way Latin does; negative
       tracking breaks the joins between letters. */
    --ed-tracking-display: 0;
    --ed-tracking-title:   0;
    --ed-tracking-body:    0;
    --ed-tracking-caption: 0;
    --ed-tracking-overline: 0.02em;
}

/* ==========================================================================
   REDUCED MOTION
   A blanket rule on purpose: the point of the preference is that nothing
   animates, including anything added later that forgets to opt in.

   It lives here rather than in a component sheet because this is the only
   stylesheet every page loads. error_base.html and bi/panel_unavailable.html
   are standalone -- they do not pull in edic-chrome.css -- so a guarantee
   parked there would quietly not apply to them.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 1ms !important;
        animation-duration: 1ms !important;
        /* Duration alone is not enough. A looping animation that forgets to
           opt out still runs -- at 1ms a cycle, roughly a thousand times a
           second, which is a strobe rather than stillness and is exactly the
           thing this preference exists to prevent. Capping the count is what
           makes the blanket rule an actual guarantee. */
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}
