/* ===========================================================================
   The company chooser - Portfolio, Active Accounts and Unmatched.
   Class prefix .cc-*, because this is ONE component on three pages.

   IT IS SHARED ON PURPOSE. The dark lead band existed as five private copies
   (227 rules) before base.css took it, and this file records that five copies
   of anything drift. The Portfolio owned the only chooser; rather than write a
   second and a third, the rules live here once and each page supplies content.

   TWO COLUMNS, NOT FOUR. Four side by side gave each card ~350px at 1600 and
   251px of content at 1366, which is why its source line had to take a row of
   its own to stop the affordance wrapping on the narrowest card. At two across
   a card gets ~700px, which is what lets it carry a headline figure, three
   supporting ones and a meter instead of two numbers.
   =========================================================================== */

.cc-ask { max-width: 62ch; }
.cc-eyebrow {
  display: inline-block; font-size: var(--fs-2xs); font-weight: var(--fw-bold);
  letter-spacing: .14em; text-transform: uppercase; color: var(--text-soft);
  padding-bottom: .35rem; border-bottom: 2px solid var(--accent); margin-bottom: .9rem;
}
.cc-ask h2 { font-size: var(--fs-3xl); font-weight: var(--fw-bold); margin: 0 0 .5rem; color: var(--text); }
.cc-ask p { font-size: var(--fs-md); color: var(--text-soft); margin: 0; }

/* THE GRID IS TWO COLUMNS AND SAYS SO. `auto-fit` would put four across on a
   wide monitor, which is the layout this replaces, and would drop to one
   awkwardly. Two is the decision; below 980px a single column is the only
   honest answer, because half of 980 is already under the 420px a lockup plus
   four figures needs. */
.cc-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.3rem; margin-top: 1.6rem; }
@media (max-width: 979.98px) { .cc-grid { grid-template-columns: minmax(0, 1fr); } }

.cc-card {
  position: relative; display: block; width: 100%; text-align: left;
  min-height: 300px; padding: 0; border: 1px solid var(--border);
  border-radius: 16px; background: var(--surface); box-shadow: var(--shadow);
  cursor: pointer; overflow: hidden; color: inherit;
  /* 160ms on the lift, which is the house figure for a hover: the card has to
     answer the pointer, not travel. The ::before / ::after washes keep their
     own .28s where they are declared - a colour settling slower than the box
     moves is what stops the two reading as one lurch. */
  transition: transform .16s var(--ease), box-shadow .16s var(--ease),
              border-color .28s var(--ease-out);
  /* Entrances animate FROM transparent with `backwards` fill, so the resting
     state is visible. An animation that never gets a frame must not blank a
     card - the rule motion.css carries and that `.rise` breaks. */
  animation: ccIn .42s var(--ease-out) both; animation-delay: var(--d, 0ms);
}
@keyframes ccIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
/* THE OPT-OUT COVERS EVERY MOVEMENT, not just the entrance. Written against
   `animation` alone it left the hover lift and the arrow nudge running, which is
   most of the motion a reader actually sees on this component. The COLOUR
   feedback stays - reduced motion asks for less movement, not less affordance. */
@media (prefers-reduced-motion: reduce) {
  .cc-card { animation: none; transition: box-shadow .01ms, border-color .01ms; }
  .cc-card:hover, .cc-card:focus-visible, .cc-card:active { transform: none; }
  .cc-card::before { transition: none; }
  .cc-go .bi, .cc-card:hover .cc-go .bi, .cc-card:focus-visible .cc-go .bi { transition: none; transform: none; }
}

/* The default is written first, which is the tidy order - and the comment that
   used to sit here claimed it was load-bearing: that written last it "would beat
   all of them - equal specificity (0,1,0) - and every card would draw gold."
   THAT IS FALSE, and being written down is what would have kept it. `.cc-card`
   is (0,1,0); `.cc-card.c-messenger` is TWO classes, (0,2,0), so every brand rule
   outranks the default wherever it sits. The layout.css faults this cited
   (`.sidebar-tmc`, `.acct-btn > .bi`) were redeclarations at EQUAL specificity,
   which is the case order decides; this is not that case. Order here is style,
   not protection - and a rule added later at (0,2,0) would still need to come
   after the brand rules to win. */
.cc-card               { --cc-c: var(--accent); }
.cc-card.c-messenger   { --cc-c: var(--brand-messenger); }
.cc-card.c-eff         { --cc-c: var(--brand-eff); }
.cc-card.c-thumbies    { --cc-c: var(--brand-thumbies); }
/* CemSites is a green-to-blue GRADIENT rather than one hue, taken from its new
   logo, so its rule and its meter carry the gradient and its ring falls back to
   the solid stop (box-shadow cannot take an image). */
.cc-card.c-cemsites    { --cc-c: var(--brand-cemsites); --cc-grad: var(--brand-cemsites-grad); }
.cc-card.c-justdigital { --cc-c: var(--brand-justdigital); }

/* The company's own colour, as a rule that grows on hover. Colour never carries
   identity here - the lockup does - so this is reinforcement, not encoding. */
.cc-card::before {
  content: ''; position: absolute; inset: 0 0 auto; height: 4px;
  background: var(--cc-grad, var(--cc-c)); transform: scaleX(.34); transform-origin: left;
  transition: transform .34s var(--ease-out);
}
.cc-card::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  box-shadow: inset 0 0 0 2px var(--cc-c); opacity: 0; transition: opacity .28s var(--ease-out);
}
/* --lift-* live in motion.css, which loads LAST, so every other stylesheet here
   names them with a fallback. Same pattern. */
/* 2px, NOT 4. Four was enough to shift a 300px card under someone reading the
   figures on it, and this project's own note on the house hover is "enough to
   feel alive, not enough to shift the layout". THE KEYBOARD GETS THE SAME CUE:
   the ring alone says "this is where you are" and says nothing about the card
   being a thing you can open, which is what the lift is for. */
.cc-card:hover,
.cc-card:focus-visible { transform: translateY(-2px); box-shadow: var(--lift-2, 0 6px 20px rgba(0, 0, 0, .16)); }
.cc-card:hover::before, .cc-card:focus-visible::before { transform: scaleX(1); }
.cc-card:hover::after, .cc-card:focus-visible::after { opacity: .5; }
.cc-card:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
/* Under the hover, so the press still registers as a press. */
.cc-card:active { transform: translateY(-1px) scale(.995); }
.cc-card.is-empty { cursor: pointer; }
.cc-card.is-empty .cc-logo { opacity: .62; }

.cc-in { position: relative; z-index: 1; display: flex; flex-direction: column; min-height: 100%; padding: 1.55rem 1.5rem 1.15rem; gap: 0; }

.cc-logo { display: flex; align-items: center; height: 68px; min-width: 0; }
.cc-logo .bchip, .cc-logo .bchip img { max-width: 100%; }
.cc-logo .bchip.lg img { height: 60px; }
.cc-name { font-size: var(--fs-2xl); font-weight: var(--fw-bold); color: var(--text); }
.cc-sells { margin-top: .3rem; font-size: var(--fs-sm); color: var(--text-soft); }

/* The headline is the one figure this surface is about, and its LABEL comes
   from the database - "Gross advanced" on EFF, "Revenue collected" on CemSites -
   so a reader is never shown a number whose basis is somewhere else. */
.cc-head { margin-top: 1.15rem; display: flex; align-items: baseline; gap: .55rem; flex-wrap: wrap; min-width: 0; }
.cc-head-v { font-size: var(--fs-4xl); font-weight: var(--fw-bold); color: var(--text); letter-spacing: -.02em; line-height: 1.05; }
.cc-head-l { font-size: var(--fs-sm); color: var(--text-soft); }
.cc-head.is-na .cc-head-v { font-size: var(--fs-lg); font-weight: var(--fw-medium); color: var(--text-soft); letter-spacing: 0; }

.cc-note { margin-top: .4rem; font-size: var(--fs-xs); color: var(--text-soft); }

.cc-stats { display: flex; gap: 1.6rem; margin-top: 1.05rem; flex-wrap: wrap; min-width: 0; }
.cc-stat { display: flex; flex-direction: column; min-width: 0; }
.cc-stat b { font-size: var(--fs-xl); font-weight: var(--fw-bold); color: var(--text); line-height: 1.1; }
.cc-stat em { font-style: normal; font-size: var(--fs-xs); color: var(--text-soft); margin-top: .18rem; }
.cc-stat.t-warn b { color: var(--warn-ink); }
/* A suppressed figure is NOT a zero. It draws an em dash and carries the reason
   on its tooltip, because "cannot be asked" and "none" are different answers. */
.cc-stat.is-na b { color: var(--text-dim); font-weight: var(--fw-medium); }

.cc-meter { display: block; height: 7px; margin-top: 1rem; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.cc-meter i {
  display: block; height: 100%; border-radius: 4px; background: var(--cc-grad, var(--cc-c));
  transform-origin: left;
  /* ---- THE METER FILLS WITH ITS CARD ----
     NO FIRST-PAINT GATE HERE, and that is the difference from every other
     meter in this pass: a chooser is drawn ONCE PER PAGE OPEN (the note at
     the top of company-chooser.js), so every paint of this element IS an
     arrival and there is no repaint to protect against. It rides the
     card's own 70ms stagger and lands just after it.
     BACKWARDS FILL: the resting state is the full meter. */
  animation: cc-grow-x .32s var(--ease-out) backwards;
  animation-delay: calc(var(--d, 0ms) + 220ms);
}
@keyframes cc-grow-x { from { transform: scaleX(0); } }
/* THE OPT-OUT SITS HERE, not in the block at the head of this file. Both
   selectors are (0,1,1), and that block is DECLARED FIRST - so an opt-out
   filed up there lost the cascade and the meter went on filling for a
   reader who had asked for no motion. Measured in headless Chrome with the
   preference set: four cc-grow-x animations still running. */
@media (prefers-reduced-motion: reduce) {
  .cc-meter i { animation: none; }
}
.cc-meter-l { margin-top: .4rem; font-size: var(--fs-xs); color: var(--text-soft); }

.cc-foot { display: flex; align-items: center; justify-content: space-between; gap: .8rem; margin-top: auto; padding-top: 1.05rem; min-width: 0; }
.cc-sys { display: inline-flex; align-items: center; gap: .35rem; font-size: var(--fs-xs); color: var(--text-dim); min-width: 0; }
.cc-sys .bi { font-size: var(--fs-sm); }
.cc-go { display: inline-flex; align-items: center; gap: .35rem; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--accent-ink); white-space: nowrap; }
.cc-go .bi { transition: transform .3s var(--ease-out); }
.cc-card:hover .cc-go .bi, .cc-card:focus-visible .cc-go .bi { transform: translateX(4px); }

/* THE WAIT MIRRORS THE CARD. A blank slab reads as a panel that FAILED, which
   is the rule base.css already states for the four band skeletons - and the
   first cut of this file broke it twice: no shimmer at all (`animation: none`)
   and nothing inside. Holding the card's own shape also stops the 2x2 grid
   jumping when the answer lands.

   The shimmer is `m1BandShimmer`, the one base.css added when four pages had
   each written their own. There is no second keyframe here. */
.cc-card.cc-sk { min-height: 300px; cursor: default; background: var(--surface); box-shadow: var(--shadow); animation: none; }
.cc-card.cc-sk::before { transform: scaleX(.34); background: var(--surface-3); }
.cc-card.cc-sk::after { display: none; }
.cc-sk-in { display: flex; flex-direction: column; min-height: 100%; padding: 1.55rem 1.5rem 1.15rem; }
.cc-sk-b {
  display: block; border-radius: 7px; background: var(--surface-3);
  background-image: linear-gradient(90deg, rgba(0,0,0,0) 25%, rgba(0,0,0,.05) 50%, rgba(0,0,0,0) 75%);
  background-size: 200% 100%; animation: m1BandShimmer 1.2s ease-in-out infinite;
}
/* EVERY DARK VALUE IS DECLARED TWICE - once inside the media query for a dark-OS
   user who has never touched the toggle, and once on the attribute so the toggle
   beats the OS in both directions. Written as ONE selector list with
   `:root:not([data-theme="light"])` OUTSIDE any media query, as this rule was,
   it is worse than the missing half the checker reports: with no attribute set
   at all - the default - the selector matches in LIGHT mode too, so a light card
   drew the white-on-white shimmer and the skeleton went invisible. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .cc-sk-b {
    background-image: linear-gradient(90deg, rgba(255,255,255,0) 25%, rgba(255,255,255,.07) 50%, rgba(255,255,255,0) 75%);
  }
}
:root[data-theme="dark"] .cc-sk-b {
  background-image: linear-gradient(90deg, rgba(255,255,255,0) 25%, rgba(255,255,255,.07) 50%, rgba(255,255,255,0) 75%);
}
.cc-sk-logo  { width: 176px; height: 44px; margin-top: .5rem; }
.cc-sk-sells { width: 62%; height: 11px; margin-top: 1.05rem; }
.cc-sk-head  { width: 44%; height: 30px; margin-top: 1.5rem; }
.cc-sk-note  { width: 74%; height: 10px; margin-top: .75rem; }
.cc-sk-stats { display: flex; gap: 1.6rem; margin-top: 1.35rem; }
.cc-sk-stat  { width: 84px; height: 34px; }
.cc-sk-meter { height: 7px; margin-top: 1.4rem; }
.cc-sk-foot  { width: 40%; height: 11px; margin-top: 1.35rem; }
@media (prefers-reduced-motion: reduce) { .cc-sk-b { animation: none; } }
.cc-grid .load-failed { grid-column: 1 / -1; }

/* ---- how old the cards are ----
   SPANNING BOTH COLUMNS IS THE WHOLE REASON THIS IS SAFE INSIDE THE GRID. The
   partials carry a warning that a further child of .cc-grid takes another
   card's worth of cell on an implicit row of its own - true of an AUTO-PLACED
   child, which `1 / -1` is not. It is also what keeps render-page.js's grid-wrap
   guard quiet, and correctly so: that guard excludes explicitly placed children
   because they are a decision rather than an overflow. Same move as
   `.cc-grid .load-failed` directly above.

   THE AMBER COMES FROM THE THEME-AWARE WARN TOKENS, so there is no dark VALUE
   here to declare a second time - --warn-ink, --warn-weak and --warn-line are
   each declared twice in base.css, under the media query and under
   [data-theme="dark"], and this rule resolves correctly in both by reading
   them. Writing a literal colour for dark here is the fault check 9 exists to
   catch. It is the pair `.page-age.is-late` already uses for the Executive
   Overview's age chip, so the two freshness surfaces look alike on purpose.

   Colour is never the only signal: the glyph changes shape and the sentence
   itself says what being late means (see _ageHtml in company-chooser.js). */
.cc-age {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: .4rem;
  font-size: var(--fs-xs); color: var(--text-soft);
  /* No padding or border in the quiet state, so the line reads as a footnote
     and not as a control somebody could press. */
  padding: 0; border: 1px solid transparent; border-radius: 999px;
}
.cc-age i { font-size: var(--fs-sm); }
.cc-age.is-late {
  /* justify-self, not align-self: a grid item stretches on BOTH axes, and a
     full-width amber bar across a 1600px grid reads as an outage banner rather
     than as a note about the figures above it. This sizes the plate to its
     sentence; the height is one line either way, so nothing below moves. */
  justify-self: start;
  padding: .18rem .6rem;
  color: var(--warn-ink, var(--warn)); background: var(--warn-weak);
  border-color: var(--warn-line);
}
.cc-age.is-late i { color: var(--warn); }

.cc-foot-note { margin-top: 1.2rem; font-size: var(--fs-sm); color: var(--text-soft); }

/* The flight layer. Fixed, above the page, and pointer-transparent so the card
   underneath is never intercepted mid-transition. */
.cc-fx { position: fixed; inset: 0; pointer-events: none; z-index: 1030; }
