/* ================================================================
   PROJECTS PAGE UPLIFT — review build
   ----------------------------------------------------------------
   Layered AFTER css/styles.css (live 2026-07-17 baseline, 691,764 B).
   Every rule here is ADDITIVE — styles.css itself is untouched, so
   this can be reviewed, reverted, or folded into the monolith later.

   Addresses the Fable review of 2026-07-31:
     A-2/A-3/A-4  nav a11y + focus + hit areas
     B-1/B-2/B-3/B-4  hero rebuild (Direction 1 + honest reel)
     C-2/C-3/C-5/C-7/C-8  card + layout defects
     D-2  light-theme contrast on every money figure
   ================================================================ */


/* ----------------------------------------------------------------
   0a. MISSING DESIGN TOKEN  --space-7            [found in preview]
   The spacing scale defines --space-1..6, 8, 10, 12, 16, 20 but NOT
   --space-7, and 12 rules in styles.css use it. An unresolvable var()
   invalidates the whole declaration at computed-value time, so all 12
   collapse to `padding: 0`:

     .projects-summary        styles.css:15477   <- this page's KPI strip
     .aace-timeline           styles.css:16228
     .p50p90-viz              styles.css:17501
     .fa-buildup              styles.css:17934
     .ppp-hierarchy           styles.css:18186
     .evm-dash                styles.css:19423
     + 6 more guide components

   Verified live: getComputedStyle('.projects-summary').padding === "0px".
   It hides on mobile because the <=900px rule uses --space-5, which
   does exist. One line repairs all twelve.
   ---------------------------------------------------------------- */
:root {
  --space-7: 1.75rem;
}


/* ----------------------------------------------------------------
   0b. TOKEN NAME COLLISION  --text-body          [found in preview]
   --text-body is declared TWICE in :root —
       styles.css:35   --text-body: #666666;   (Text Colors)
       styles.css:50   --text-body: 1rem;      (Typography)
   The later declaration wins, so in LIGHT theme every
   `color: var(--text-body)` is invalid at computed-value time and
   the element falls back to inherit. That is the root cause behind
   the washed-out light theme, not just the individual rules.

   In DARK theme the [data-theme="dark"] block re-declares
   --text-body: #a3a3a3 (styles.css:129) — later still — so the
   colour works but every `font-size: var(--text-body)` breaks
   instead. The token is broken in both themes, just differently.

   PROPER FIX (needs a styles.css edit, not done here): rename the
   colour token to --color-text-body at styles.css:35 and :129 and
   update the `color: var(--text-body)` call sites. Until then this
   file supplies an unambiguous colour token for the elements on
   this page that need one.
   ---------------------------------------------------------------- */
:root {
  --cnx-text-body: #666666;
}

[data-theme="dark"] {
  --cnx-text-body: #a3a3a3;
}


/* ----------------------------------------------------------------
   0. Skip link + focus visibility                       [A-3]
   The stylesheet defines focus styles for only four components;
   with an 80px fixed nav a skip link matters.
   ---------------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 2000;
  background: var(--color-accent);
  color: #000000;
  font-size: var(--text-small);
  font-weight: var(--font-semibold);
  letter-spacing: 0.04em;
  padding: var(--space-3) var(--space-5);
  text-decoration: none;
}

.skip-link:focus {
  left: 0;
}

.nav__link:focus-visible,
.nav__dropdown-link:focus-visible,
.nav__toggle:focus-visible,
.theme-toggle:focus-visible,
.btn:focus-visible,
.project-card__link:focus-visible,
.footer__link:focus-visible,
.footer__legal-link:focus-visible,
.footer__social-link:focus-visible,
.footer__logo-link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* The active nav link is bright teal on a light nav bar in light
   theme = 2.03:1 at 14px. (It measures 9.8:1 in dark theme, which is
   why it reads as fine there.) Found in the preview sweep. */
:root:not([data-theme="dark"]) .nav__link--active {
  color: #086a5f;
}

:root:not([data-theme="dark"]) .nav__link--active::after {
  background: #086a5f;
}

/* The live stylesheet's AA remediation darkens .btn--secondary to
   #086a5f everywhere and only restores bright teal inside
   .section--dark (styles.css:27083-27084). The page header is dark
   but is NOT .section--dark, so the new hero CTA landed at 3.05:1.
   Restore the bright teal there, same as the .section--dark rule. */
.page-header .btn--secondary {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

.page-header .btn--secondary:hover {
  color: var(--color-black);
  background: var(--color-accent);
}

/* Same trap again, site-wide: .section-header__eyebrow is darkened to
   #086a5f for light contexts (styles.css:26998) and restored to bright
   teal only under .section--dark (styles.css:27022). In dark THEME a
   plain .section is not .section--dark, so every section eyebrow on
   every page sits at 3.05:1. Pre-existing; measured in the preview. */
[data-theme="dark"] .section-header__eyebrow {
  color: var(--color-accent);
}

/* Desktop nav links were ~30px tall (padding: var(--space-2) 0).   [A-4] */
@media (min-width: 769px) {
  .nav__menu .nav__link {
    padding-top: var(--space-3);
    padding-bottom: var(--space-3);
  }
}


/* ----------------------------------------------------------------
   1. Hero — "proof ledger"                          [B-2, Dir 1]
   CTAs under the description, and the portfolio KPI strip promoted
   out of the body and into the dark header. The header renders dark
   in BOTH themes, so the strip's dark treatment is pinned here
   rather than left to [data-theme="dark"].
   ---------------------------------------------------------------- */
.page-header__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-8);
}

.projects-summary--hero {
  margin: var(--space-12) 0 0;
  background:
    linear-gradient(180deg, rgba(43, 203, 186, 0.07), rgba(43, 203, 186, 0.02)),
    rgba(255, 255, 255, 0.02);
  border-color: rgba(43, 203, 186, 0.25);
  border-left-color: var(--color-accent);
}

.projects-summary--hero .projects-summary__kpi {
  border-left-color: rgba(43, 203, 186, 0.16);
}

.projects-summary--hero .projects-summary__eyebrow {
  color: var(--color-accent);
}

/* Bright teal on the near-black header = 9.6:1 (the light-theme
   override in section 5 must not reach inside the header). */
.projects-summary--hero .projects-summary__num {
  background: linear-gradient(135deg, var(--color-accent), var(--color-accent-light));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--color-accent);
}

.projects-summary--hero .projects-summary__sub {
  color: #9a9a9a; /* 6.9:1 on the header; --text-muted was 3.7:1 */
}

/* The base strip collapses to ONE column below 560px (styles.css:15763).
   In the body that was fine; in the header it made the strip 409px tall
   and the whole header 1191px — 1.4 screens on a 390x844 phone before
   any content. Two columns holds the proof above ~1 screen. */
@media (max-width: 560px) {
  .projects-summary--hero {
    margin-top: var(--space-8);
    grid-template-columns: 1fr 1fr;
  }

  .projects-summary--hero .projects-summary__kpi {
    padding: var(--space-3) 0 0 !important;
  }

  .projects-summary--hero .projects-summary__kpi:nth-child(-n+2) {
    border-top: none;
    padding-top: 0 !important;
  }

  .projects-summary--hero .projects-summary__kpi:nth-child(odd) {
    padding-right: var(--space-3) !important;
  }

  .projects-summary--hero .projects-summary__kpi:nth-child(even) {
    padding-left: var(--space-3) !important;
  }
}


/* ----------------------------------------------------------------
   2. Reel — honest data, brand palette, legible type   [B-1, B-4]
   Tiles are now rebuilt in the HTML from the page's own register.
   Here: collapse the six-colour sector palette to brand teal (so the
   hero stops running a different colour system from its own content),
   raise the 8px captions, and drop the amber money colour.
   ---------------------------------------------------------------- */
.reel-tile,
.reel-tile-civil,
.reel-tile-rail,
.reel-tile-energy,
.reel-tile-water,
.reel-tile-marine,
.reel-tile-mining,
.reel-tile-defence {
  --tile-c1: #14313a;
  --tile-c2: #061418;
  --tile-glow: rgba(43, 203, 186, 0.45);
  --tile-accent: #2bcbba;
}

.reel-tile-cat {
  font-size: 10px; /* was 8px, unchanged at mobile */
  letter-spacing: 0.14em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reel-tile-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reel-tile-val,
.reel-meta span {
  color: var(--color-accent); /* was amber #fbbf24 */
}

/* 10 real tiles per loop instead of 6 — hold the original scroll rate. */
.reel-track {
  animation-duration: 63s;
}


/* ----------------------------------------------------------------
   3. Dark-mode card titles rendered grey, not white      [C-2]
   `.project-card .project-card__title { color: inherit }` in the
   sector-pill block (styles.css:15586) out-specifies the base rule
   at styles.css:9411, so titles inherited body #a3a3a3.
   ---------------------------------------------------------------- */
.project-card .project-card__title {
  color: var(--text-primary);
}

/* Same defect, same block: __client and __service are also in that
   `color: inherit` list, so they inherited .project-card__meta's
   --text-muted instead of their own --text-body rule (styles.css:9427).
   Measured in the preview: 2.52:1 in light theme — the client names
   ("Powerlink Queensland", "WSP", "TMR") were the least legible text
   on the page. Restores to 5.7:1 light / 6.9:1 dark. */
.project-card .project-card__client,
.project-card .project-card__service {
  color: var(--cnx-text-body); /* not --text-body: see 0b */
}


/* ----------------------------------------------------------------
   4. Metadata contrast                                   [C-3]
   --text-muted is #737373 in dark (3.7:1 on the #1a1a1a card) and
   #a3a3a3 in light (2.5:1 on white). Both fail AA at 12–13px, and
   this is where the client names live.
   ---------------------------------------------------------------- */
[data-theme="dark"] .projects-summary:not(.projects-summary--hero) .projects-summary__sub,
[data-theme="dark"] .project-card__value-eyebrow,
[data-theme="dark"] .experience-item__client {
  color: #8f8f8f; /* 5.2:1 on #1a1a1a */
}

/* The hero strip is excluded: it sits on the always-dark page header,
   where #565656 measures 2.7:1. Its own light-grey override lives in
   section 1 and must not be out-specified by this rule. */
:root:not([data-theme="dark"]) .projects-summary:not(.projects-summary--hero) .projects-summary__sub,
:root:not([data-theme="dark"]) .project-card__value-eyebrow,
:root:not([data-theme="dark"]) .experience-item__client {
  color: #565656; /* 7.0:1 on white — the house remediation neutral */
}


/* ----------------------------------------------------------------
   5. Light theme — every money figure was 1.5–2.9:1      [D-2]
   Reuses the palette the live stylesheet already established in its
   WCAG remediation block: #086a5f (6.5:1, AA for text) and
   #1b9688 (3.3:1, the documented "3:1 on white" step).
   Scoped with :root:not([data-theme="dark"]) so dark mode keeps the
   bright teal, and .projects-summary--hero is excluded because the
   page header is dark in both themes.
   ---------------------------------------------------------------- */
:root:not([data-theme="dark"]) .projects-summary:not(.projects-summary--hero) .projects-summary__num,
:root:not([data-theme="dark"]) .project-card__value,
:root:not([data-theme="dark"]) .experience-item__value {
  background: linear-gradient(135deg, #086a5f 0%, #1b9688 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: #086a5f;
}

/* 14px link at 2.0:1 was the worst offender on the page. */
:root:not([data-theme="dark"]) .project-card__link {
  color: #086a5f;
}

:root:not([data-theme="dark"]) .project-card__link:hover {
  color: #05504a;
}

:root:not([data-theme="dark"]) .projects-summary:not(.projects-summary--hero) .projects-summary__eyebrow,
:root:not([data-theme="dark"]) .experience-item__sector-label {
  color: #086a5f;
}

/* Pill text, pill border, card left border and the hover glow all read
   from --sector-color, so darkening it once fixes the set. */
:root:not([data-theme="dark"]) .project-card,
:root:not([data-theme="dark"]) .experience-item {
  --sector-color: #086a5f;
}

:root:not([data-theme="dark"]) .project-card__tag {
  color: #086a5f;
  background: rgba(8, 106, 95, 0.09);
}


/* ----------------------------------------------------------------
   6. One hover system, not two                           [C-5]
   The base card runs a top-border wipe (styles.css:9352); the later
   sector-pill block re-adds a lift + radial glow (styles.css:15563).
   Both fire at once. Keep the lift + glow, retire the wipe.
   ---------------------------------------------------------------- */
.project-card::before {
  display: none;
}


/* ----------------------------------------------------------------
   7. Experience items advertised a link they don't have  [C-7]
   They lift and shadow on hover but contain no anchor. Until they
   link to detail pages, remove the false affordance and keep a
   flat, honest hover.
   ---------------------------------------------------------------- */
.experience-item:hover {
  transform: none;
  box-shadow: none;
}

[data-theme="dark"] .experience-item:hover {
  background: #1f1f1f;
}

:root:not([data-theme="dark"]) .experience-item:hover {
  background: rgba(43, 203, 186, 0.05);
}


/* ----------------------------------------------------------------
   8. CTA band was indigo #1a1a2e (styles.css:341)        [C-8]
   The only non-neutral surface on a strictly black/teal page.
   ---------------------------------------------------------------- */
[data-theme="dark"] .section--accent {
  background: #111716;
}

[data-theme="dark"] .section--accent .cta__bg-shape {
  opacity: 0.5;
}
