/* =========================================================================
   CAREERBRICKS — THE PUBLIC STYLESHEET.

   ⚠ THIS FILE IS HAND-WRITTEN AND THERE IS NO BUILD STEP. Do not add one
   without re-deriving the reason. Measured 7 September 2026: `package.json`
   and `vite.config.js` exist, `package-lock.json` does not, so deploy.yml's
   "Build front-end assets" step has printed a skip line and exited 0 on every
   deploy this repo has ever had. There is no setup-node in that workflow.

   The reasons for staying hand-written, all of them re-derived here rather
   than inherited:

     1. NOTHING NEEDS IT. The type is system-ui and the marks are local PNGs.
        `Instrument Sans` appears only in resources/css/app.css's Tailwind
        theme, which nothing renders. A build would buy a typeface the design
        does not use.
     2. FILAMENT'S ASSETS DO NOT COME FROM VITE. `filament:assets` COPIES
        pre-built files; it does not build. So the admin will not need it
        either.
     3. A BUILD IS A SECOND ARTEFACT THAT CAN BE STALE. bin/deploy.sh has no
        front-end step, so a manifest one release behind would serve a page
        with no styles and report a green deploy.

   ⚠ AND THE REASON THAT IS *NOT* A REASON, recorded so nobody repeats it:
   `vite.config.js` calls bunny('Instrument Sans'), which READS like a runtime
   CDN link to fonts.bunny.net. IT IS NOT. Read from the published package,
   the helper fetches at BUILD time, caches to disk, and emits the woff2 files
   as build assets - the result is self-hosted and adds no third-party request
   to any page. Anyone arguing against a build on privacy grounds is arguing
   from the name of the function rather than from what it does.

   ---------------------------------------------------------------------------
   WHY THIS IS A FILE AND NOT AN INLINE <style> BLOCK.

   The holding page carried its whole stylesheet inline, which was right for
   one page and is wrong for two. Inline means the same ~7KB on every request
   with no caching - and it means every class name is in every document before
   any element uses it, so assertSee('any-class') is true on every page and
   assertDontSee becomes a generator of false alarms. This project has hit that
   trap in three registers and it is the failure mode that gets a good check
   deleted.

   ⚠ The <style>-block brace test moved with it. See
   PublicStylesheetTest - the brace-depth walk is unchanged and now reads this
   file. A stray `}` here would still silently swallow the rule beneath it.
   ========================================================================= */


/* -------------------------------------------------------------------------
   THE TWO BRAND COLOURS, AND WHY EACH IS USED WHERE IT IS.

   Measured from the mark PNGs, which are lossless, so these values are the
   mark's own and not a compression artefact:

       blue #2397C3   on white 3.34:1   on near-black 5.44:1
       red  #CB2031   on white 5.54:1   on near-black 3.28:1
       blue against red directly        1.66:1

   So: RED carries small type on a light ground. BLUE never does - it is a
   field colour, a rule, or large display type only. And the two are never set
   on one another at any size.
   ------------------------------------------------------------------------- */
:root {
    --blue:   #2397C3;
    --red:    #CB2031;

    /* Neutrals biased very slightly toward the blue, so they read as chosen
       rather than as the browser's grey. */
    --ground: #FBFCFD;
    --panel:  #FFFFFF;
    --ink:    #15181B;
    --muted:  #5C666F;
    --rule:   #E2E7EB;

    --measure: 34rem;
    --s1: .5rem; --s2: 1rem; --s3: 1.5rem; --s4: 2rem; --s5: 3rem; --s6: 4.5rem;
}

/* Dark: the marks are fixed rasters drawn for a light ground, and red falls to
   3.28:1 on near-black. So the LOCKUP KEEPS ITS OWN LIGHT PLATE rather than
   being placed on the dark - and the red is lifted for text use. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --ground: #111417;
        --panel:  #171B1F;
        --ink:    #E9ECEF;
        --muted:  #9BA5AE;
        --rule:   #262C32;
        --red:    #F26D77;   /* 6.1:1 on #111417 - the brand red is unreadable there */
    }
}
:root[data-theme="dark"] {
    --ground: #111417; --panel: #171B1F; --ink: #E9ECEF;
    --muted: #9BA5AE; --rule: #262C32; --red: #F26D77;
}

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

body {
    margin: 0;
    background: var(--ground);
    color: var(--ink);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 1.0625rem;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

.wrap {
    max-width: var(--measure);
    margin: 0 auto;
    /* padding-top / padding-bottom, never the shorthand - a shorthand here
       would wipe the horizontal padding the moment another class shares this
       element, which is a fault this project has five instances of. */
    padding-left: var(--s3);
    padding-right: var(--s3);
}

main { padding-top: var(--s6); padding-bottom: var(--s6); }

/* ---- the mark ---- */
.mark { display: block; width: 100%; max-width: 15rem; height: auto; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .mark-plate {
        background: #FFFFFF;
        border-radius: 14px;
        padding: var(--s3);
        display: inline-block;
    }
}
:root[data-theme="dark"] .mark-plate {
    background: #FFFFFF; border-radius: 14px; padding: var(--s3); display: inline-block;
}

/* The mark is a link on every page except the one it points at, so it needs
   the same focus treatment as any other link and none of the colour. */
.mark-link { display: inline-block; }
.mark-link:focus-visible { outline: 3px solid var(--blue); outline-offset: 4px; border-radius: 4px; }

/* ---- type ---- */
h1 {
    font-family: ui-rounded, "SF Pro Rounded", "Segoe UI Variable Display",
                 "Segoe UI", system-ui, sans-serif;
    font-size: clamp(1.75rem, 5.5vw, 2.6rem);
    line-height: 1.12;
    letter-spacing: -0.015em;
    text-wrap: balance;
    margin: var(--s5) 0 var(--s3);
    font-weight: 700;
}

.lede { font-size: 1.15rem; margin: 0 0 var(--s2); }
.lede + p { margin: 0 0 var(--s2); }
.muted { color: var(--muted); }

/* ---- the routes out ---- */
.routes { display: grid; gap: var(--s3); margin-top: var(--s5); }

.route {
    background: var(--panel);
    border: 1px solid var(--rule);
    border-radius: 12px;
    padding: var(--s3);

    /* ⚠ THE MARK'S SPLIT LIVES HERE, NOT AS A HORIZONTAL RULE.

       It was a full-width 4px two-tone bar under the heading. That is the
       visual grammar of a PROGRESS BAR - and on a page headlined "being built"
       it did not merely resemble one, it implied a specific claim: roughly
       half done. Nobody has said that. The device was asserting a fact of its
       own, which is worse than being decorative.

       Turned on its side it cannot be read as progress, and it does MORE work
       than before: the two edges together are still the wordmark's blue/red
       split, and each one now also tells the routes apart. */
    border-left-width: 3px;
}

/* ⚠ THE MAPPING WAS RE-DERIVED WHEN THE PANELS MERGED, NOT LEFT TO DESCRIBE A
   STRUCTURE THAT NO LONGER EXISTS.

   It used to read: blue is the "career" half of the wordmark and this is the
   career route, the hiring that happens today; red is the "bricks" half, which
   is CareerBricks itself, the thing not open yet. That was true of THREE panels,
   where "hiring today" was its own panel.

   There are now two, and the employer panel carries both - a referral that
   works today and a portal that does not. So the distinction the colours draw
   is the one that survived the merge:

       BLUE  - this panel can help you today
       RED   - this one cannot, yet

   which is still the wordmark's own split rather than a decorative choice, and
   is still legible as one. */
.route--career { border-left-color: var(--blue); }
.route--bricks { border-left-color: var(--red); }

.route h2 {
    font-size: .8125rem; text-transform: uppercase; letter-spacing: .08em;
    margin: 0 0 var(--s1); color: var(--muted); font-weight: 600;
}
.route p { margin: 0 0 var(--s1); }

/* Red on a light panel is 5.54:1 - the one brand colour that may carry small
   type. */
a { color: var(--red); text-decoration-thickness: 1px; text-underline-offset: 3px; }

/* ⚠ THE ROUTE LINKS ARE THE ONLY ACTIONS ON THESE PAGES, and as plain inline
   text they measured 22px tall on a phone - under the 24px WCAG 2.2 minimum
   and far under a comfortable thumb.

   Measured, not assumed: at 375px they were 213x22 and 171x22.

   padding-top / padding-bottom rather than the shorthand, per the fault this
   project has five instances of.

   ⚠ IT IS KEYED ON A CLASS, NOT ON :last-child, AND THAT CHANGE WAS FORCED.
   The selector used to be `.route p:last-child a`, which was correct while
   every panel ended in its one link. Merging the employer panels gave that
   panel TWO links, and :last-child would have silently left the first of them
   at 22px - a WCAG failure on the link an employer who is hiring today is most
   likely to press, with nothing on the page looking wrong. A structural
   selector that happens to match is the coincidence fault; naming the thing is
   the fix. */
.route p.go a {
    display: inline-block;
    padding-top: .7rem;
    padding-bottom: .7rem;
    font-weight: 600;
}
a:hover { text-decoration-thickness: 2px; }
a:focus-visible { outline: 3px solid var(--blue); outline-offset: 3px; border-radius: 2px; }

/* ---- the ground we cover ----------------------------------------------
   Families of work, as prose blocks. Deliberately NOT a grid of cards: a card
   grid is the visual grammar of a listings page, and these are not listings.
   The page's shape is a louder claim than any label on it.
   ----------------------------------------------------------------------- */
.families { margin-top: var(--s5); }

.family {
    border-top: 1px solid var(--rule);
    padding-top: var(--s3);
    padding-bottom: var(--s2);
}

.family h2 {
    font-size: 1.0625rem;
    margin: 0 0 var(--s1);
    font-weight: 700;
    letter-spacing: -0.005em;
}

.family p { margin: 0; color: var(--muted); }

/* The closing note on what these are not. It is the most important paragraph
   on the site and it is set to read as a statement rather than a disclaimer -
   a tinted box with a warning icon would make it look like small print, which
   is exactly how small print gets skipped. */
.plainly {
    margin-top: var(--s5);
    border-left: 3px solid var(--red);
    padding-left: var(--s3);
}
.plainly p { margin: 0 0 var(--s2); }
.plainly p:last-child { margin-bottom: 0; }

/* ---- onward ---- */
.onward { margin-top: var(--s5); }
.onward a { font-weight: 600; display: inline-block; padding-top: .7rem; padding-bottom: .7rem; }

footer {
    border-top: 1px solid var(--rule);
    padding-top: var(--s3); padding-bottom: var(--s5);
    font-size: .9375rem; color: var(--muted);
}
footer a { color: inherit; }
footer p { margin: 0 0 var(--s1); }
footer p:last-child { margin-bottom: 0; }

/* ⚠ A GLOBAL RESET, NOT A PER-CLASS ONE. An author rule that sets `display`
   beats the user agent's [hidden] rule, and the markup gives no sign - this
   project shipped a dead "Share" button on every story page that way, with the
   attribute present and the element visible at 44px. A per-class fix repairs
   the instance and leaves the trap for the next author rule. */
[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }
