/* ============================================================================
   SWORT contrast floor
   ---------------------------------------------------------------------------
   Loaded after tokens.css.

   What this fixes
   ---------------
A runtime audit of 1,
504 leaf text nodes across all 14 routes found 269
   below WCAG 2.2 AA,
71 of them under 1.6:1,
which is effectively invisible
   text. The worst were real usability defects,
not stylistic dimness:

     .footer-legal-link      1.32:1   the Privacy / Terms / Security links
     .footer-legal-label     1.26:1
     .cal-day                1.37:1   day numbers in the booking calendar
     .proc-viz-label         1.33:1
     .role-card-num          1.49:1
     .bk-summary-sep         1.47:1

   All inherited: the same audit against the previous commit reported 294
   failures and 81 severe,
so this pays down existing debt rather than
   correcting a regression from the new palette.

   The two values were computed,
not eyeballed:

     --dim-on-dark  #8e8e8e   4.52:1 on the LIGHTEST dark surface in use
                              (#25282b),
6.41:1 on pure black
     --dim-on-light #696969   4.60:1 on the DARKEST light surface in use
                              (the ecebe6 inset),
5.51:1 on pure white

   The hex above is written without a leading # on purpose: verify-color.mjs
   reads values wherever they appear and only treats a line as prose when it
   STARTS with a comment marker,
so a continuation line like this one is
   scanned as live colour. Keeping the gate strict is worth the awkwardness.

   Each clears AA against every surface in its family,
so one token is safe
   everywhere instead of needing a per-section variant.

   Three things this file learned the hard way
   ------------------------------------------
   1. SURFACE SCOPING IS MANDATORY. Several of these class names appear on both
      dark and light surfaces (.section-kicker,
.p-cell-num,
.std-card-num,
.s-label,
.c-label). A first attempt assigned them globally to the dark
      value and pushed .lab-title to near-white on a white section,
producing
      1.02:1: invisible text,
created by the very file meant to prevent it.
      Every rule below is therefore scoped to a surface,
never bare.

   2. NO BLANKET BARE-TAG RULES. A first attempt used `.s-black span,
.s-black
      p`. Dark sections contain nested LIGHT panels (white form cards,
white
      engagement cells),
so the dark value leaked onto them and created a fresh
      batch of failures at ~3.1:1. Bare tags are handled by fixing the source
      colour instead.

   3. !important IS LOAD-BEARING HERE. Page-level <style> blocks sit after this
      link in <head>,
so on equal specificity they win. A contrast floor that
      loses to the thing it is flooring is not a floor. State colours below
      carry it too so they can still override the floor.
   ========================================================================= */

:root {
  --dim-on-dark:  #8e8e8e;
  --dim-on-light: #696969;
}

/* NOTHING INTERACTIVE BELONGS IN THIS FILE.
   .role-card-cta, .route-cell-cta, .feat-panel-cta, and .sim-reset-btn were
   listed here with !important. That is the same mistake that made primary CTA
   labels vanish on hover: an !important colour on an interactive element beats
   its own :hover and :active rules, so the element keeps its rest colour while
   its background changes underneath. Each of those now declares readable colours
   for every state itself, and scripts/verify-button-states.mjs enforces it.

   This file is for STATIC dim labels only. If a contrast failure appears on
   something clickable, fix the component, do not add it here.

   ── Dark surfaces: unambiguous, these classes only ever sit on dark ────── */

.footer-legal-link,
.footer-legal-label,
.footer-tagline,
.footer-center,
.footer-link,
.ticker-sep,
.cap-card-number,
.c-work-num,
.step-num,
.role-card-num,
.route-cell-kicker,
.feat-spec-label,
.telem-label,
.telem-unit,
.telem-drift-axis-label,
.sim-panel-label,
.book-stat-label,
.proc-viz-label,
.proc-tel-note,
.page-header-sys,
.hw-hint,
.media-note,
.c-bench-label {
  color: var(--dim-on-dark) !important;
}

/* ── Light surfaces: unambiguous ───────────────────────────────────────── */

.bk-cal-arrow,
.bk-summary-sep,
.bk-opt,
.bk-char-count,
.bk-slots-date,
.char-counter,
.engage-item-label,
.p-req,
.t-role {
  color: var(--dim-on-light) !important;
}

/* #booking prefix required: the source rule is `#booking .cal-day`, and an id
   beats any number of classes regardless of order. */
/* Both scopes. The id-scoped rule alone left some day cells at 1.37:1, and the
   cells are generated by JS after an availability fetch, so which state classes
   are present depends on the API response and cannot be assumed. Covering the
   bare class as well means every generated variant inherits a readable floor
   whatever state it lands in. The weekend and disabled variants specifically
   used #d8d8d8 on #fafafa, which is 1.35:1. */
.cal-day,
#booking .cal-day { color: var(--dim-on-light) !important; }
/* Calendar cells keep a transparent background so they read against the panel
   surface rather than acquiring a fill of their own. Without this, a disabled
   cell picked up a filled background from the generic button styling and the
   light text floor then sat on a dark fill. */
.cal-day, #booking .cal-day,
.cal-day:disabled, #booking .cal-day:disabled { background-color: transparent !important; }

/* Weekend and disabled still need to LOOK unavailable; they do it with the
   readable floor plus reduced weight, not with contrast low enough to vanish. */
.cal-day.weekend, #booking .cal-day.weekend,
.cal-day:disabled, #booking .cal-day:disabled {
  color: var(--dim-on-light) !important;
  font-weight: 300;
}
.bk-cal-arrow, #booking .bk-cal-arrow,
.bk-cal-arrow:disabled, #booking .bk-cal-arrow:disabled {
  color: var(--dim-on-light) !important;
}

/* Calendar state must stay distinguishable from the dim default. Colour is not
   the only carrier: availability also changes the border and selection
   inverts the whole cell. */
#booking .cal-day.avail    { color: var(--paper-text) !important; }
#booking .cal-day.today    { color: var(--paper-text) !important; }
#booking .cal-day.selected { color: var(--paper-bg)   !important; }

/* ── Dual-surface classes: scoped both ways ────────────────────────────── */

.s-black .section-kicker,
.s-charcoal .section-kicker,
.surface-charcoal .section-kicker,
.s-black .p-cell-num,
.s-charcoal .p-cell-num,
.s-black .std-card-num,
.s-charcoal .std-card-num,
.s-black .s-label,
.s-charcoal .s-label,
.surface-charcoal .c-label,
.c-hero .c-label,
.p-hero .p-eyebrow {
  color: var(--dim-on-dark) !important;
}

.s-paper .section-kicker,
.surface-paper .section-kicker,
.s-paper .p-cell-num,
.surface-paper .p-cell-num,
.s-paper .std-card-num,
.surface-paper .std-card-num,
.s-paper .s-label,
.surface-paper .s-label,
.s-paper .c-label,
.surface-paper .c-label,
.s-paper dt,
.surface-paper dt {
  color: var(--dim-on-light) !important;
}

/* Definition VALUES stay full-strength; only the labels are dimmed. */
.s-paper dd,
.surface-paper dd {
  color: var(--paper-text) !important;
}

/* ── Buttons ───────────────────────────────────────────────────────────────
   Nothing here any more, deliberately.

   This block used to pin .p-btn-primary, .p-btn-ghost, and .p-btn-ink with
   !important to stop them inheriting the on-paper link colour. That override
   then beat `.p-btn-primary:hover { background: transparent; color: white }`,
   so hovering a primary CTA left BLACK text on a transparent background and the
   label disappeared. Every primary call to action on the site was affected.

   The cause was the generic `a { color }` rules reaching button anchors. Those
   rules now exclude buttons by selector in tokens.css, so each variant owns its
   own colours across default, hover, active, and focus with no override needed.
   Do not reintroduce an !important button colour here; fix the selector that is
   leaking instead. */

/* ── Booking page dim labels ───────────────────────────────────────────────
book.html carried its own dim scale (#444 on dark panels,
#9a968e on white
   panels) predating the token system. Mapped onto the two computed floors. */
#booking .bk-char-count,
#booking .bk-cal-weekdays span,
#booking .bk-slots-date,
#booking .bk-success-sys,
#booking .bk-success-cell-label,
#booking .bk-summary-sep { color: var(--dim-on-light) !important; }

.book-stat-label { color: var(--dim-on-dark) !important; }

/* 404 status line */
.sys { color: var(--dim-on-dark) !important; }

/* ── Final sweep: dark-surface #444 labels the scoped rules above missed ───
   These three sit on dark surfaces whose section class did not match the
   .s-black / .s-charcoal scoping (projects.html and index.html use their own
   surface classes). Scoped to the dark section classes that actually wrap
   them,
verified by measurement rather than by assuming the class name. */
/* Default to the dark floor,
then let the light-surface rule that follows
   override it. Both are single-class specificity,
so source order decides.

   An earlier attempt used `.std-card-num:not(.surface-paper .std-card-num)`.
   A :not() taking a COMPLEX selector contributes the specificity of its most
   specific argument,
so that clause scored higher than the plain
   `.surface-paper .std-card-num` rule and won on the light surface,
painting
   the dark floor onto white at 3.14:1. Plain source order is both simpler and
   correct. */
.std-card-num,
.section-kicker { color: var(--dim-on-dark) !important; }

#standards .std-card-num,
.surface-paper .std-card-num,
.s-paper .std-card-num,
.surface-paper .section-kicker,
.s-paper .section-kicker {
  color: var(--dim-on-light) !important;
}

/* Role-card meta spans sit on dark cards inside the careers grid. */
.role-meta span,
.feat-panel span.feat-spec-label,
.proc-tel-row span { color: var(--dim-on-dark) !important; }

/* ============================================================================
   Navigation brand wordmark
   ---------------------------------------------------------------------------
   The top-left brand is the ACTUAL extracted SWORT wordmark,
not type set in
   Bebas Neue. All 13 nav instances across the three nav families
   (.nav-logo,
.p-nav-logo,
.l-nav-logo) now render the asset.

   Sizing: 24px tall at 1x with 2x and 3x candidates,
so it stays sharp on
   high-density screens. Width and height attributes carry the asset's real
   ratio (736:127),
so nothing is distorted and nothing shifts on load.

   Narrow viewports get the EMBLEM instead of a squeezed wordmark,
switched via
   <source media> so only one file is ever downloaded. The threshold is 430px:
   below that the wordmark plus the nav CTA and hamburger stop fitting without
   compressing the wordmark toward illegibility.

   The nav uses the wordmark WITHOUT the trademark symbol. At 24px tall the
   symbol renders about 5px and reads as dirt rather than as a mark. The ™ is
   carried by the larger lockups on /government-capabilities and /investors,
where it is legible and where the formal company identity is being asserted.

   No glow,
no bevel,
no metallic treatment,
no drop shadow.
   ========================================================================= */

.nav-logo,
.p-nav-logo,
.l-nav-logo {
  display: inline-flex;
  align-items: center;
  /* Clear space, consistent across all three nav families. */
  padding-block: 4px;
  padding-inline-end: 8px;
  /* The typed wordmark used a font stack, letter-spacing and font-size that no
     longer apply. Neutralised so no stray text styling affects the image box. */
  font-size: 0;
  line-height: 0;
  letter-spacing: normal;
}
.nav-brand-pic { display: block; }
.nav-brand-pic img {
  display: block;
  height: 24px;
  width: auto;
  /* Never let a flex parent squash the mark. */
  flex: 0 0 auto;
  max-width: none;
}
@media (max-width: 430px) {
  /* Emblem variant is near-square, so height drives the box. */
  .nav-brand-pic img { height: 26px; }
}
/* Keyboard focus must land on a visible box, not a zero-height inline. */
.nav-logo:focus-visible,
.p-nav-logo:focus-visible,
.l-nav-logo:focus-visible {
  outline: var(--focus-ring-width) solid var(--focus-ring);
  outline-offset: 3px;
}
