/*
 * northstardata.com — shared chrome stylesheet for the blog.
 *
 * GENERATED by build.php from the sources below. DO NOT EDIT THIS FILE —
 * the next build overwrites it. Edit the source and run build.php.
 *
 *   _inc/theme-light.css          the ACTIVE theme (the switch in _inc/head.php)
 *   _inc/fontface.php             the @font-face table
 *   _inc/css/chrome.css           scales, reset, buttons, header, bottom nav, footer
 *
 * asset_version 9
 */
        /* ====================================================================
         * THEME: LIGHT — the live theme.
         *
         * This file and theme-dark.css declare the SAME token names and
         * nothing else. One of them is included; the other is commented out.
         * See _inc/head.php, the 'styles' block — switching is two lines.
         *
         * Only colour lives here. The type, spacing, radius and control-height
         * scales are in css/chrome.css, because a theme that moved --sp-4 or
         * --nav-h would not be a theme, it would be a second layout.
         *
         * Every ratio written beside a token is COMPUTED, not estimated, by
         * tools/contrast-check.php, which parses this file. Re-run it after
         * changing any value here; it fails the run when a pair drops under
         * target (4.5:1 text, 3:1 borders and non-text).
         * ==================================================================== */
        :root {
            /* -- Tier 1: base ------------------------------------------- */
            --bg: #f4f7fc;
            --surface: #ffffff;
            --surface-2: #f8fafd;
            --text: #0a1733;            /* 16.53 on --bg · 17.75 on --surface */
            --text-2: #3a4663;          /*  8.75 on --bg ·  9.39 on --surface */
            --text-dim: #5b6479;        /*  5.52 on --bg ·  5.93 on --surface */
            --border: #dfe6f2;          /* decorative hairline — not a control edge */
            --border-strong: #7d879b;   /*  3.37 on --bg ·  3.61 on --surface — control outlines */
            --shadow: 0 1px 2px rgba(10,23,51,.05), 0 8px 24px rgba(10,23,51,.06);

            /* -- Tier 2: accent ----------------------------------------- */
            --primary: #0033A0;
            --primary-hover: #002680;
            --on-primary: #ffffff;      /* 10.60 on --primary · 13.22 on --primary-hover */
            --link: #0033A0;            /*  9.87 on --bg · 10.60 on --surface */
            --accent: #3bc6f0;          /* FILL AND GLYPH ONLY. 1.86 on --bg — never text,
                                           never a border, never a focus ring on light. */
            --accent-ink: #0a6f94;      /*  5.27 on --bg · 5.65 on --surface · 4.97 on --tile */
            --tile: #e3f3fa;
            /* The focus ring. NOT --accent: that measures 1.86 on --bg and 2.00
               on --surface, under the 3:1 non-text target, which is what the
               mockup used and why this token exists. The dark bands re-declare
               it to --cta-accent in css/chrome.css, where --accent-ink would
               only reach 3.14. */
            --focus: #0a6f94;           /*  5.27 on --bg ·  5.65 on --surface */
            /* Status dot. The mockup's #22b07d measures 2.77 on --surface —
               under target for a non-text indicator. Darkened to clear it. */
            --ok: #1c9168;              /*  3.96 on --surface ·  3.69 on --bg */

            /* -- Tier 3: chrome and bands -------------------------------- */
            --header-bg: rgba(255,255,255,.92);
            --band-bg: #0033A0;
            --band-text: #ffffff;       /* 10.60 on --band-bg */
            --band-num: #ffffff;        /* 10.60 on --band-bg */
            --band-dim: #dbe3f5;        /*  8.24 on --band-bg */
            --band-rule: rgba(255,255,255,.14);   /* decorative divider */
            --cta-bg: #0a1733;
            --cta-text: #ffffff;        /* 17.75 on --cta-bg */
            --cta-dim: #b8c4e0;         /* 10.15 on --cta-bg */
            --cta-accent: #6ee7ff;      /* 12.29 on --cta-bg */
            --cta-glow: rgba(59,198,240,.22);
            --cta-mail-bg: #3bc6f0;
            --cta-mail-ink: #04213a;    /*  8.20 on --cta-mail-bg */
            --cta-mail-hover: #6ee7ff;
            --cta-tel-border: rgba(255,255,255,.5);  /* 5.19 on --cta-bg — control edge */
            --cta-tel-hover: rgba(255,255,255,.08);
            --art-border: #dfe6f2;
            --art-bg: #011636;
            /* The inner pages' hero band. A gradient, not a flat colour: it has to
               fade into --bg where the band ends, or the seam reads as a line. No
               text is ever painted on it directly — the hero card and the art frame
               sit on top — so it has no contrast pair of its own. */
            --hero-bg: linear-gradient(180deg, #eef3fa 0%, #f4f7fc 100%);
            --name-2: #0a6f94;          /*  5.62 on --header-bg over --bg */
        }
        /* Self-hosted webfonts — see 'fonts' in _inc/config.php. */
        @font-face { font-family: 'Archivo'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/archivo-latin-600.woff2?v=9') format('woff2'); }
        @font-face { font-family: 'Archivo'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/archivo-latin-700.woff2?v=9') format('woff2'); }
        @font-face { font-family: 'Archivo'; font-style: normal; font-weight: 800; font-display: swap; src: url('/fonts/archivo-latin-800.woff2?v=9') format('woff2'); }
        @font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/inter-latin-400.woff2?v=9') format('woff2'); }
        @font-face { font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap; src: url('/fonts/inter-latin-500.woff2?v=9') format('woff2'); }
        @font-face { font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fonts/inter-latin-600.woff2?v=9') format('woff2'); }
        @font-face { font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap; src: url('/fonts/inter-latin-700.woff2?v=9') format('woff2'); }
        @font-face { font-family: 'JetBrains Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fonts/jetbrains-mono-latin-400.woff2?v=9') format('woff2'); }
        /* ====================================================================
         * SHARED CHROME — every generated page gets this, byte for byte.
         *
         * The header, the bottom nav and the footer are the same markup on all
         * 18 pages (see _inc/nav.php, bottom-nav.php, footer.php), so they are
         * the same CSS too. Everything below the header is the page family's
         * own sheet: home.css, services.css, or legal/.
         *
         * Colour comes from the theme — _inc/theme-light.css or theme-dark.css,
         * included just above this in _inc/head.php. Nothing here hardcodes a
         * colour that a theme should own.
         *
         * THE SCALES LIVE HERE, NOT IN THE THEME FILES
         * A theme that moved --sp-4 or --nav-h would not be a theme, it would
         * be a second layout. Type, spacing, radius and control heights are
         * the same in light and dark, so they are declared once, here.
         *
         * TWO BREAKPOINTS
         * 960px and 720px, and that is the whole list. The eight the old
         * sheets carried between them (600, 700, 767, 768, 900, 939, 940, 969)
         * were each added to fix one element, and no two pages agreed on where
         * a layout changed. 960 is where the header stops fitting its full
         * wordmark plus five links plus the phone number; 720 is where the
         * desktop nav gives way to the bottom bar.
         * ==================================================================== */
        :root {
            /* type */
            --font: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
            --font-head: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
            --fs-xs: 12px;
            --fs-sm: 14px;
            --fs: 16px;
            --fs-md: 18px;
            --fs-lg: 20px;
            --fs-xl: 28px;
            --fs-2xl: 42px;
            /* spacing */
            --sp-1: 4px;
            --sp-2: 8px;
            --sp-3: 12px;
            --sp-4: 16px;
            --sp-5: 24px;
            --sp-6: 32px;
            --sp-7: 48px;
            --sp-8: 64px;
            /* radius */
            --r-sm: 6px;
            --r: 10px;
            --r-lg: 16px;
            /* controls and frame */
            --ctl-h: 44px;
            --nav-h: 64px;
            --bottom-h: 58px;
            --container: 1200px;
        }

        /* ---------------------------------------------------------- base -- */
        *, *::before, *::after { box-sizing: border-box; }
        /*
         * scroll-padding-top tracks --nav-h, so an anchor never lands under the
         * fixed header. It has to be a calc() off the token rather than a
         * number: --nav-h drops to 58px at 720px, and the old sheets' hardcoded
         * 100px was wrong at every width once the header stopped being 84px.
         */
        html {
            scroll-behavior: smooth;
            scroll-padding-top: calc(var(--nav-h) + env(safe-area-inset-top, 0px) + 12px);
            -webkit-text-size-adjust: 100%;
        }
        body {
            margin: 0;
            background: var(--bg);
            color: var(--text);
            font: 400 var(--fs)/1.6 var(--font);
            -webkit-font-smoothing: antialiased;
        }
        img { max-width: 100%; display: block; }
        a { color: var(--link); }
        h1, h2, h3 { margin: 0; color: var(--text); font-family: var(--font-head); letter-spacing: -0.01em; }
        /*
         * HEADLINES ARE ONE SOLID COLOUR.
         *
         * The <em> elements are content — they are in the copy and they stay in
         * the markup — but they carry no colour or slant of their own. The
         * earlier design painted them accent-blue italic, which split every
         * headline into two voices and left the accent doing work the eyebrow
         * and the links should do.
         */
        h1 em, h2 em, h3 em { font-style: normal; color: inherit; }
        p { margin: 0; }
        /*
         * The focus ring is --focus, NOT --accent. --accent measures 1.86:1 on
         * --bg in the light theme; the 3:1 non-text target is the one a focus
         * ring exists to meet. See tools/contrast-check.php.
         */
        a:focus-visible,
        button:focus-visible {
            outline: 2px solid var(--focus);
            outline-offset: 2px;
            border-radius: var(--r-sm);
        }
        .wrap { max-width: var(--container); margin: 0 auto; padding: 0 var(--sp-5); }

        /* -------------------------------------------------------- buttons -- */
        .btn {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: var(--sp-2);
            height: var(--ctl-h);
            padding: 0 20px;
            border-radius: var(--r);
            font: 600 15px/1 var(--font);
            text-decoration: none;
            white-space: nowrap;
            border: 1px solid transparent;
            transition: background .15s, border-color .15s;
        }
        .btn-primary { background: var(--primary); color: var(--on-primary); }
        .btn-primary:hover { background: var(--primary-hover); }
        .btn-outline { background: var(--surface); color: var(--link); border-color: var(--border-strong); }
        .btn-outline:hover { border-color: var(--link); }

        /* --------------------------------------------------------- header -- */
        .nav-top {
            position: fixed;
            inset: 0 0 auto 0;
            z-index: 20;
            background: var(--header-bg);
            backdrop-filter: saturate(1.4) blur(10px);
            -webkit-backdrop-filter: saturate(1.4) blur(10px);
            border-bottom: 1px solid var(--border);
            padding-top: env(safe-area-inset-top, 0px);
        }
        .nav-inner { height: var(--nav-h); display: flex; align-items: center; gap: var(--sp-5); }
        .brand { display: flex; align-items: center; gap: var(--sp-3); text-decoration: none; color: var(--text); flex: none; }
        /*
         * The mark is a 40px raster in a rounded tile. The artwork already
         * carries its own dark field, so the tile is overflow + radius rather
         * than a painted background — nothing to keep in step with the image.
         */
        .brand-mark {
            width: 40px;
            height: 40px;
            border-radius: 9px;
            overflow: hidden;
            flex: none;
            box-shadow: 0 0 0 1px rgba(110, 231, 255, .25);
        }
        .brand-text { display: flex; flex-direction: column; line-height: 1.15; }
        /*
         * The wordmark is Archivo, like the headings — it is the one piece of
         * display type that appears on every page. It needs saying explicitly
         * because these are <span>s: the h1/h2/h3 rule above does not reach
         * them, and without this they silently fell back to Inter 700 and the
         * header stopped matching the rest of the page.
         */
        .brand-name, .brand-name-short { font-family: var(--font-head); font-weight: 700; font-size: 16px; white-space: nowrap; }
        .brand-name-second { color: var(--name-2); }
        .brand-name-short { display: none; }
        .brand-tag {
            font-family: var(--font);
            font-size: 11px;
            font-weight: 600;
            letter-spacing: .08em;
            color: var(--accent-ink);
            margin-top: 3px;
            white-space: nowrap;
            /* The tagline is set in caps, as it was before the restyle and as
               the approved design shows it. Doing it in CSS rather than in the
               config string keeps the visible-text extraction — and therefore
               the SEO diff — reading the same words it always has. */
            text-transform: uppercase;
        }
        .nav-links { display: flex; gap: 2px; list-style: none; margin: 0 0 0 auto; padding: 0; }
        .nav-links a {
            display: block;
            padding: 8px 11px;
            font-size: 15px;
            font-weight: 500;
            color: var(--text-2);
            text-decoration: none;
            border-radius: var(--r-sm);
        }
        .nav-links a:hover { color: var(--text); background: var(--tile); }
        .nav-links a.active { color: var(--text); }
        .nav-phone {
            display: flex;
            align-items: center;
            gap: 6px;
            font-size: 15px;
            font-weight: 600;
            color: var(--text);
            text-decoration: none;
            white-space: nowrap;
        }
        .nav-phone i { color: var(--accent-ink); font-size: 14px; }
        .nav-cta { height: 40px; }

        /* ---------------------------------------------------- bottom nav -- */
        /*
         * Signature UX pattern — present on every page, never removed. Same
         * five links and the same hrefs as before; a flat blurred bar now
         * instead of a floating pill, so it reads as part of the chrome rather
         * than as a widget sitting on top of it.
         */
        .nav-bottom { display: none; }
        .nav-bottom a i { font-size: 1.05rem; }

        /* --------------------------------------------------------- footer -- */
        .site-footer { margin-top: var(--sp-8); border-top: 1px solid var(--border); background: var(--surface); }
        .foot-grid {
            display: grid;
            grid-template-columns: 1.4fr 1fr 1fr 1fr;
            gap: var(--sp-6);
            padding: var(--sp-7) 0 var(--sp-6);
        }
        /* A column label, not a heading — see the note in _inc/footer.php. */
        .foot-head {
            margin: 0 0 var(--sp-3);
            font-family: var(--font-head);
            font-size: 13px;
            font-weight: 700;
            letter-spacing: .06em;
            text-transform: uppercase;
            color: var(--text);
        }
        .foot-grid a {
            display: block;
            font-family: var(--font);
            color: var(--text-2);
            text-decoration: none;
            font-size: 15px;
            padding: 3px 0;
        }
        .foot-grid a:hover { color: var(--link); }
        /* The Contact column's email link carries an envelope — the same glyph
           _inc/scripts.php writes back when it de-obfuscates the address, so the
           link looks the same before and after the script runs. */
        .foot-grid a i { color: var(--accent-ink); font-size: .9em; }
        /* .foot-grid a wins on specificity, so the brand restates both. */
        .foot-grid a.brand { display: flex; padding: 0; color: var(--text); font-size: var(--fs); }
        .foot-brand p { color: var(--text-dim); font-size: 15px; margin-top: var(--sp-3); max-width: 34ch; }
        .foot-base {
            border-top: 1px solid var(--border);
            padding: var(--sp-4) 0;
            font-size: 14px;
            color: var(--text-dim);
            display: flex;
            justify-content: space-between;
            gap: var(--sp-4);
            flex-wrap: wrap;
        }
        .foot-base a { color: var(--text-dim); }

        /* -------------------------------------------------- reading scope -- */
        /*
         * <main class="reading"> on every page whose body is long-form prose:
         * the 11 service pages and the 6 legal pages. Under the LIGHT theme it
         * does nothing — the tokens already hold these values. Under the DARK
         * theme, theme-dark.css re-declares the base and accent tiers inside
         * this scope so the reading area stays light between a dark header and
         * a dark footer. See the block at the foot of theme-dark.css.
         */
        main { padding-top: var(--nav-h); }
        main.reading { display: block; }

        /* ===================================================== <= 960px ==== */
        @media (max-width: 960px) {
            /*
             * The header runs out of room here, and it runs out in a specific
             * order. Measured at 961px with the full wordmark: brand 237 + gap
             * 24 + five links 368 + gap 24 + phone 135 + gap 24 + CTA 120 +
             * padding 48 = 980. The phone number is the one item that is
             * duplicated two inches below in the hero card, so it goes first;
             * the wordmark shortens next, because the tagline under it is wider
             * than the name above it and both have to go together or nothing
             * moves.
             */
            .nav-phone { display: none; }
            .nav-links a { padding: 8px 7px; font-size: 14px; }
            .brand-name, .brand-tag { display: none; }
            .brand-name-short { display: block; }
            .foot-grid { grid-template-columns: 1fr 1fr; }
        }

        /* ===================================================== <= 720px ==== */
        @media (max-width: 720px) {
            :root { --nav-h: 58px; }
            .wrap { padding: 0 var(--sp-4); }
            .nav-links, .nav-cta { display: none; }
            .brand-mark { width: 36px; height: 36px; }
            /* The phone comes back: with the links gone there is room, and it
               is the fastest way to reach a one-person consultancy. */
            .nav-phone { display: flex; margin-left: auto; }
            .nav-bottom {
                display: flex;
                position: fixed;
                inset: auto 0 0 0;
                z-index: 20;
                background: var(--header-bg);
                backdrop-filter: saturate(1.4) blur(10px);
                -webkit-backdrop-filter: saturate(1.4) blur(10px);
                border-top: 1px solid var(--border);
                padding-bottom: env(safe-area-inset-bottom, 0px);
            }
            .nav-bottom a {
                flex: 1;
                height: var(--bottom-h);
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;
                gap: 2px;
                font-size: 11px;
                font-weight: 600;
                color: var(--text-2);
                text-decoration: none;
            }
            .nav-bottom a.active { color: var(--link); box-shadow: inset 0 2px 0 var(--accent-ink); }
            body { padding-bottom: calc(var(--bottom-h) + env(safe-area-inset-bottom, 0px)); }
            .foot-grid { grid-template-columns: 1fr; gap: var(--sp-5); padding-top: var(--sp-6); }
            .foot-base { flex-direction: column; gap: var(--sp-2); }
        }
