/* ============================================================
   Advanced Intelligence Center (AIC) — Design System
   Colors & Typography CSS Variables
   Advanced Intelligence Center (AIC), University of Oulu
   ============================================================ */

/* ────────────────────────────────────────────────────────────
   FONTS
   Three typefaces, five loaded cuts. Archivo regular was removed on
   2.9.2026: it duplicated Schibsted Grotesk's job at the headline level.

   Display: Schibsted Grotesk carries hero, H1 and H2 — a warm, contemporary
            Nordic grotesk with true spurs, chosen for headline impact.
            Sentence case at all three levels. Size and weight build the
            hierarchy, not case and not a second typeface.
   Chrome:  Archivo Narrow — ALL CAPS chrome only: eyebrows, nav, zone labels,
            tags, badges, buttons, footer, slide section marks. The condensed
            width keeps short wide-tracked labels economical at small sizes.
   Impact:  Archivo Black — rare high-impact moments only (one hero stat, one
            big number). Never for general headings.
   Body:    Familjen Grotesk — body and UI, standing in for the University's
            Messina Sans. Weights 400–700.
   Mono:    IBM Plex Mono — technical and code contexts only.

   Archivo Narrow and Archivo Black are used without the family's regular cut.
   This is a deliberate choice, not a gap: the display voice comes from
   Schibsted Grotesk and the chrome from Archivo's condensed and heavy cuts.
   Archivo regular is not reinstated without a separate decision.

   The logo font ("The Brooklyn" / University custom "Oulu Brooklyn") is
   licensed for the logo and slogans only and is used nowhere else.

   OFFLINE / OFFICE FALLBACKS (see --font-* stacks below):
     Schibsted Grotesk→ Arial         (display, hero through H2)
     Archivo Narrow   → Arial Narrow  (condensed, same job, ships with Office)
     Archivo Black    → Arial Black   (single heavy weight, same job)
     Familjen Grotesk → Arial         (University's own Messina Sans fallback)
     IBM Plex Mono    → Consolas → Courier New
   All are OFL 1.1, so "Embed fonts in the file" is permitted — but that
   setting exists in WINDOWS PowerPoint and Word only. Mac Office has no
   equivalent: a Mac-produced PPTX carries font names, never font data, and
   every display face collapses to the recipient's fallback.
   Hand over as PDF (fonts embedded on any platform, once they resolve on the
   producing machine), or as a PPTX from Windows PowerPoint with embedding on.
   The Google Slides / Docs route is not in use (3.9.2026).
   PPTX TEMPLATE THEME FONT follows the handover route (14.9.2026):
     1. Embedded from Windows PowerPoint, or internal use on machines with the
        brand fonts installed → Heading = Schibsted Grotesk,
        Body = Familjen Grotesk; brand fonts at element level.
     2. Handed over for editing without embedding → theme font Arial set
        directly, and fallbacks at element level too (Arial, Arial Narrow,
        Arial Black, Consolas), never the brand fonts: an element-level font
        name overrides the theme and is substituted unpredictably.
     3. Read only → PDF with the brand fonts.
   The SemiBold cuts install as their own families; select
   them by name rather than bolding the regular cut.
   See README § "Fonts in Office and handover formats".
   ──────────────────────────────────────────────────────────── */
@import url('fonts.css');   /* self-hosted woff2 — see fonts.css */

:root {

  /* ──────────────────────────────────────────────
     BASE COLOR PALETTE
     Extracted from official logo assets
     ─────────────────────────────────────────── */

  /* PRINT NOTE (AIC Brand Book, 23.5.2024): for printed products use the
     Pantone Matching System, not CMYK — four-colour process cannot reproduce
     the depth of the Electric Blue. White = CMYK 0/0/0/0, Black = PMS Black,
     CMYK 0/0/0/100. */

  /* Primary — Royal Blue */
  --aic-blue-950:  #0a0360;   /* near-black blue, darkest */
  --aic-blue-900:  #1707a9;   /* brand primary — "Electric Blue". Print: PMS Blue 072 C (preferred) · CMYK 98/98/0/1 · RGB 23,7,169 */
  --aic-blue-800:  #2211c4;
  --aic-blue-700:  #3525d6;
  --aic-blue-600:  #4a3ee0;
  --aic-blue-500:  #6055e8;
  --aic-blue-400:  #7a72ef;
  --aic-blue-200:  #c0baf8;
  --aic-blue-100:  #e2e0fc;
  --aic-blue-50:   #f0effe;

  /* Primary — Amber Orange */
  --aic-orange-900: #a35d00;   /* oli #a86000; 4,49:1 harmaalla #f6f6f9 (saavutettavuustesti havainto 2, 1.10.2026). Nyt 5,09:1 valkoisella, 4,72:1 harmaalla */
  --aic-orange-800: #cc7800;
  --aic-orange-700: #e88e00;
  --aic-orange-600: #fe9f13;   /* brand primary — "Sun Orange". Print: PMS 137 C · CMYK 0/44/100/0 · RGB 254,159,19 */
  --aic-orange-500: #ffb03a;
  --aic-orange-400: #ffc060;
  --aic-orange-200: #ffe4b0;
  --aic-orange-100: #fff3d8;
  --aic-orange-50:  #fffaf0;

  /* Neutral */
  --aic-neutral-950: #0e0e14;
  --aic-neutral-900: #1a1a28;
  --aic-neutral-800: #2c2c40;
  --aic-neutral-700: #40405a;
  --aic-neutral-600: #5a5a78;
  --aic-neutral-500: #787898;
  --aic-neutral-400: #9898b4;
  --aic-neutral-300: #b8b8cc;
  --aic-neutral-200: #d8d8e4;
  --aic-neutral-100: #ebebf2;
  --aic-neutral-50:  #f6f6f9;
  --aic-white:       #ffffff;

  /* ──────────────────────────────────────────────
     SEMANTIC COLOR TOKENS
     ─────────────────────────────────────────── */

  --color-brand-primary:    var(--aic-blue-900);      /* #1707a9 */
  --color-brand-accent:     var(--aic-orange-600);    /* #fe9f13 */
  --color-brand-bg:         var(--aic-blue-900);
  --color-brand-bg-dark:    var(--aic-blue-950);

  /* Surfaces */
  --color-surface-base:     var(--aic-white);
  --color-surface-subtle:   var(--aic-neutral-50);
  --color-surface-raised:   var(--aic-white);
  --color-surface-overlay:  rgba(23,7,169, 0.06);
  --color-surface-dark:     var(--aic-neutral-900);
  --color-surface-brand:    var(--aic-blue-900);

  /* Foregrounds */
  /* CONTRAST FLOOR FOR TEXT ON WHITE, added 14.9.2026.
     --aic-neutral-600 (#5a5a78) is the LIGHTEST neutral usable for text on
     white: 6.63:1. Everything lighter fails the 4.5:1 minimum —
     neutral-500 #787898 is 4.25:1 and neutral-400 #9898b4 is 2.81:1.
     --color-fg-tertiary is therefore for non-text use (rules, dividers,
     disabled marks), not for small chrome labels. Three separate defects
     on 14.9.2026 came from reaching for neutral-400/500 for footer and
     label text; use --color-fg-muted instead. */
  --color-fg-primary:       var(--aic-neutral-950);
  --color-fg-secondary:     var(--aic-neutral-700);
  --color-fg-tertiary:      var(--aic-neutral-500);
  --color-fg-muted:         var(--aic-neutral-600);
  --color-fg-on-brand:      var(--aic-white);
  /* Hairline divider on a solid brand-blue surface. Added 15.9.2026: on-brand
     dividers had been written as literal rgba(255,255,255,.34) in artifacts. */
  --color-border-on-brand:  rgba(255,255,255, 0.34);
  --color-fg-on-dark:       var(--aic-white);
  /* ORANGE AS TEXT, rule 22.9.2026. Orange text on a light surface is ALWAYS
     orange-900 (#a35d00, 5,1:1 on white, 4,7:1 on neutral-50), INCLUDING hover and focus states:
     text is text in every state (WCAG 1.4.3). orange-600 is for rules, rings,
     surfaces and the mark, and as text only on brand blue (6,2:1 on blue-900,
     measured). The focus ring is a different rule (1.4.11, 3:1, non-text) and
     is decided separately.

     Two named tokens, because the single name --color-fg-accent invites the
     reading "orange text anywhere".

     CHECKED 22.9.2026, surface by surface, across the site CSS: nothing to fix.
     Every orange-600 text and hover sits on brand blue (blue-900 or blue-950).
     The only orange-600 on a light surface are three arrow glyphs
     (.pairs a.row .act:after, .ret:before, .envx-band a.ext .m), which are
     marks rather than text and belong to the same 1.4.11 decision as the
     focus ring. */
  --color-fg-accent-on-brand: var(--aic-orange-600);
  --color-fg-accent-on-light: var(--aic-orange-900);
  /* DEPRECATED 22.9.2026, alias of --color-fg-accent-on-brand. Kept because
     downstream files depend on it; use the two named tokens in new work. */
  --color-fg-accent:        var(--aic-orange-600);
  --color-fg-link:          var(--aic-blue-900);

  /* Borders */
  --color-border-default:   var(--aic-neutral-200);
  --color-border-strong:    var(--aic-neutral-300);
  --color-border-brand:     var(--aic-blue-900);
  --color-border-accent:    var(--aic-orange-600);

  /* States */
  --color-focus:            var(--aic-orange-600);
  --color-hover-overlay:    rgba(23,7,169, 0.06);
  --color-pressed-overlay:  rgba(23,7,169, 0.12);

  /* ──────────────────────────────────────────────
     BACKGROUND AND OVERLAY SYSTEM, decided 17.9.2026
     See preview/backgrounds.html for the card and the right/wrong pairs.

     SIX BACKGROUND TYPES, nothing else: solid brand blue
     (--color-surface-brand) · light neutral (--color-surface-subtle) ·
     dark neutral (--color-surface-dark) · photo with an overlay ·
     network field on dark · network field on a light surface. A seventh
     type is a defect, not a variation.

     TWO OVERLAY LAYERS, and they do different jobs. Do not read them as
     two tastes of one value:
       TINT is flat brand blue and answers "is the photo content or
       structure". Two values only, .55 and .80.
       SCRIM is a gradient in blue-950 and answers "does the type reach
       4.5:1 where it actually sits". It is anchored to an edge; the
       surface sets the direction, the token carries the stops.
     A flat .55 tint does NOT on its own guarantee 4.5:1 on a photo's
     lightest areas — staging's photo header stacks tint + scrim for
     exactly that reason. Reach for the scrim, never for a darker tint.

     THE SCRIM SHADE IS ALWAYS BLUE-950. Two literals in the project
     predate this and are corrected, not kept: rgba(9,3,72) (#090348, in
     dead staging hero rules) and rgba(12,4,86) (#0c0456, strategy deck
     cover right edge). No new blue is minted for a background.

     GRADIENT RULE, rewritten 17.9.2026 (supersedes the blanket ban in
     CLAUDE.md § Color): a gradient in ONE already-decided blue, used as
     a named overlay layer, is allowed. A gradient that mixes hues or
     mints a shade is not. Decorative gradients remain banned.
     ─────────────────────────────────────────── */
  --color-overlay-photo-read:  rgba(23,7,169, 0.55);   /* photo is content, read through the tint */
  --color-overlay-photo-tint:  rgba(23,7,169, 0.80);   /* photo is structure, type sits on top */
  --color-scrim-base:          10,3,96;                /* blue-950 as rgb triplet, for rgb()/rgba() */
  /* Stop lists, not whole gradients: the surface chooses the direction.
     background:linear-gradient(to top, var(--scrim-field-stops)) */
  --scrim-field-stops:  rgba(10,3,96,0.65) 0%, rgba(10,3,96,0.221) 55%, rgba(10,3,96,0) 100%;
  --scrim-photo-stops:  rgba(10,3,96,0.92) 0%, rgba(10,3,96,0.72) 30%, rgba(10,3,96,0.18) 66%, rgba(10,3,96,0) 88%;
  /* Network field: minimum band height for the motif to read as a field
     rather than noise. Measured 15.9.2026, three failed attempts below it. */
  --field-min-band: 30mm; /* @kind spacing */

  /* Feedback */
  --color-success:   #1a8a4a;
  --color-warning:   var(--aic-orange-600);
  --color-error:     #c0392b;
  --color-info:      var(--aic-blue-700);

  /* ──────────────────────────────────────────────
     CATEGORICAL ACCENT (rare, documented exception)
     Blue and orange are the only BRAND colors — never add a third
     brand-facing accent. This token exists ONLY for cases where a UI
     needs to visually tell categories/parts apart (e.g. a badge, a tag
     list, an internal tool) and neutral tone, blue/orange tints, and
     non-color differentiation (icon, border, type) all fall short.
     Defined in oklch, deliberately lower-chroma than the brand accent
     so it reads as supporting, never mistaken for a third brand color.
     Do not add more hues here — one categorical accent is the ceiling.
     See preview/colors-categorical-extension.html for the decision guide.
     ─────────────────────────────────────────── */
  --color-category-accent:      oklch(58% 0.09 210);
  --color-category-accent-tint: oklch(95% 0.02 210);
  --color-category-accent-text: oklch(38% 0.08 210);

  /* ──────────────────────────────────────────────
     TYPOGRAPHY
     ⚠ Substitution notice — see fonts/ for actuals
     ─────────────────────────────────────────── */

  /* Font families — primary (web) with offline / MS Office fallbacks */
  --font-display:         'Schibsted Grotesk', 'Familjen Grotesk', 'Arial', sans-serif;
  --font-display-narrow:  'Archivo Narrow', 'Arial Narrow', sans-serif;
  --font-display-black:   'Archivo Black', 'Arial Black', sans-serif;
  --font-body:     'Familjen Grotesk', Arial, 'Helvetica Neue', sans-serif;
  --font-mono:     'IBM Plex Mono', 'Consolas', 'Courier New', monospace;

  /* DEPRECATED 2.9.2026. Same typeface as --font-display. Retained only so
     existing material does not break. Do not use in new work — use
     --font-display. Removed once current material has been reviewed. */
  --font-display-hero:    var(--font-display);

  /* Font sizes — fluid scale */
  --text-xs:    0.75rem;    /* 12px */
  --text-sm:    0.875rem;   /* 14px */
  --text-base:  1rem;       /* 16px */
  --text-md:    1.125rem;   /* 18px */
  --text-lg:    1.25rem;    /* 20px */
  --text-xl:    1.5rem;     /* 24px */
  --text-2xl:   2rem;       /* 32px */
  --text-3xl:   2.5rem;     /* 40px */
  --text-4xl:   3rem;       /* 48px */
  --text-5xl:   4rem;       /* 64px */
  --text-6xl:   5.5rem;     /* 88px */

  /* Font weights */
  --weight-light:    300;
  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;
  --weight-extrabold:800;

  /* Line heights */
  --leading-tight:   1.1;
  --leading-snug:    1.3;
  --leading-normal:  1.5;
  --leading-relaxed: 1.7;

  /* Letter spacings */
  --tracking-tight:  -0.02em;
  --tracking-normal:  0;
  --tracking-wide:    0.05em;
  --tracking-wider:   0.10em;
  --tracking-widest:  0.18em;

  /* ──────────────────────────────────────────────
     SEMANTIC TYPE ROLES
     ─────────────────────────────────────────── */

  /* Hero / display — Schibsted Grotesk. Sentence case, weight 700, tight
     tracking. Chosen for headline impact; the spurred letterforms give the
     display voice its character. Archivo Black is NOT used here — see
     type-stat below. */
  --type-hero-family:   var(--font-display);
  --type-hero-size:     var(--text-6xl);
  --type-hero-weight:   700;
  --type-hero-leading:  var(--leading-tight);
  --type-hero-tracking: var(--tracking-tight);
  --type-hero-transform: none;

  /* H1 — Schibsted Grotesk, sentence case (matches hero) */
  --type-h1-family:   var(--font-display);
  --type-h1-size:     var(--text-4xl);
  --type-h1-weight:   700;
  --type-h1-leading:  var(--leading-tight);
  --type-h1-tracking: var(--tracking-tight);
  --type-h1-transform: none;

  /* H2 — Schibsted Grotesk, sentence case. Separated from hero and H1 by size
     and weight, not by case and not by a second typeface.

     H2 is not ALL CAPS. Across the system, ALL CAPS is reserved for chrome
     labels (--type-label): eyebrows, nav, zone labels, tags, buttons. If H2
     were also all caps, a heading and a label would look alike and two
     different roles would blur. In Finnish the difference is sharper still:
     long compound words set in caps slow reading down, and slide headings are
     typically exactly that length. */
  --type-h2-family:   var(--font-display);
  --type-h2-size:     var(--text-3xl);
  --type-h2-weight:   600;
  --type-h2-leading:  var(--leading-snug);
  --type-h2-tracking: var(--tracking-normal);
  --type-h2-transform: none;

  /* H3 — Schibsted Grotesk. CORRECTED 14.9.2026 to match the brand page and
     brand-rules.md (decided 7.9.2026). H3 previously pointed at Familjen
     Grotesk "for contrast against the all-caps display"; that justification
     lapsed on 2.9.2026 when display moved to sentence case. H3 now follows
     the display face, and the typeface changes only below H3, in body copy. */
  --type-h3-family:   var(--font-display);
  --type-h3-size:     var(--text-xl);
  --type-h3-weight:   var(--weight-semibold);
  --type-h3-leading:  var(--leading-snug);

  /* Label / eyebrow / nav / badge / button — Archivo Narrow, medium-to-semibold
     weight, wide tracking. Condensed width keeps short all-caps chrome
     economical at small sizes. */
  --type-label-family:   var(--font-display-narrow);
  --type-label-size:     var(--text-sm);
  --type-label-weight:   600;
  --type-label-tracking: var(--tracking-widest);
  --type-label-transform: uppercase;

  /* Stat / impact number — Archivo Black. Single heavy weight, reserved for
     rare high-impact moments (one hero stat, one big number). Never use for
     general headings — this is the one deliberate exception to the
     light-to-medium display-weight rule. */
  --type-stat-family:   var(--font-display-black);
  --type-stat-size:     var(--text-6xl);
  --type-stat-weight:   400;
  --type-stat-leading:  var(--leading-tight);

  /* Body */
  --type-body-family:   var(--font-body);
  --type-body-size:     var(--text-base);
  --type-body-weight:   var(--weight-regular);
  --type-body-leading:  var(--leading-relaxed);

  /* Body small */
  --type-body-sm-family:  var(--font-body);
  --type-body-sm-size:    var(--text-sm);
  --type-body-sm-weight:  var(--weight-regular);
  --type-body-sm-leading: var(--leading-normal);

  /* Mono */
  --type-mono-family:  var(--font-mono);
  --type-mono-size:    var(--text-sm);
  --type-mono-weight:  var(--weight-regular);

  /* ──────────────────────────────────────────────
     SPACING SCALE
     ─────────────────────────────────────────── */
  --space-1:   4px;
  --space-2:   8px;
  --space-3:   12px;
  --space-4:   16px;
  --space-5:   20px;
  --space-6:   24px;
  --space-8:   32px;
  --space-10:  40px;
  --space-12:  48px;
  --space-16:  64px;
  --space-20:  80px;
  --space-24:  96px;
  --space-32:  128px;

  /* ──────────────────────────────────────────────
     BORDER RADIUS
     ─────────────────────────────────────────── */
  --radius-none:   0;
  --radius-sm:     2px;
  --radius-md:     4px;
  --radius-lg:     8px;
  --radius-xl:     12px;
  --radius-2xl:    20px;
  --radius-full:   9999px;

  /* ──────────────────────────────────────────────
     SHADOW SYSTEM
     ─────────────────────────────────────────── */
  --shadow-sm:  0 1px 3px rgba(23,7,169, 0.08);
  --shadow-md:  0 4px 16px rgba(23,7,169, 0.12);
  --shadow-lg:  0 8px 32px rgba(23,7,169, 0.16);
  --shadow-xl:  0 16px 48px rgba(23,7,169, 0.20);

  /* ──────────────────────────────────────────────
     TRANSITIONS
     ─────────────────────────────────────────── */
  --transition-fast:   150ms ease;   /* @kind other */
  --transition-base:   250ms ease;   /* @kind other */
  --transition-slow:   400ms ease;   /* @kind other */
  --transition-enter:  300ms cubic-bezier(0.22, 1, 0.36, 1);   /* @kind other */

  /* ──────────────────────────────────────────────
     LAYOUT
     ─────────────────────────────────────────── */
  --max-width-content: 1140px;
  --max-width-text:    680px;
  --nav-height:        72px;

  /* ──────────────────────────────────────────────
     MARK LOCKUP — three-line descriptor
     Added 14.9.2026, definition corrected same day. Ratio locked at 1.0:
     the AIC mark's letters, the AI/O mark's letters and the descriptor's
     INK all equal H.

     H is the descriptor's ink height, NOT three line boxes. The top and
     bottom line boxes carry leading above the caps and below the baseline,
     so 3 × line-height overstates the visible text by ~14%. Measuring that
     way is what made this recur: it forces the marks up and they then read
     taller than the type beside them.

       H = 2 × line-height + --lockup-descriptor-cap-ratio × font-size
       AIC mark width  = H × --lockup-mark-ratio-aic
       AI/O mark width = H × --lockup-mark-ratio-aio

     Size the descriptor from AIC, never from the AI/O bounding box — that
     box is H / 0.80953, because the slash overshoots the cap line above and
     below. "AI/O is taller" refers to that box, not to its letters.

     NAV EXCEPTION: in nav chrome the descriptor follows the nav spec
     (9.7/10 px against a 33.3 px mark), which satisfies the rule to within
     0.35 px. Below 600 px the descriptor is dropped rather than shrunk
     below 9 px. On the site .lang and .itee are hidden only in the nav's
     compact state (nav.cmp); in the open state they stay visible below
     600 px too.

     Ratios derive from the two viewBoxes: AIC 1770.2 × 880 (letters fill
     the box, so box height = H) and AI/O 615.83 × 276.73 (cap height 224.02
     of 276.73, so box height = H / 0.80953).
     Specimen and size table: preview/lockup-descriptor-height.html
     ─────────────────────────────────────────── */
  --lockup-descriptor-family:      var(--font-display-narrow);
  --lockup-descriptor-weight:      600;
  --lockup-descriptor-tracking:    .075em;
  --lockup-descriptor-line-height: 16px;
  --lockup-descriptor-size:        15px;
  /* Archivo Narrow cap height as a fraction of font-size, measured in
     browser via canvas actualBoundingBoxAscent. Needed for H. */
  --lockup-descriptor-cap-ratio:   0.686;   /* @kind other */
  --lockup-mark-ratio-aic:         2.012;   /* @kind other */
  --lockup-mark-ratio-aio:         2.749;   /* @kind other */
}
