/* Cybereum · adaptive-ui.css
   Prevention-first component primitives for resilient commercial and product UI.

   Architecture:
   - site-core.css owns tokens and elemental foundations.
   - this file owns reusable intrinsic/container-adaptive components.
   - page/surface files may theme components, but should not reimplement their geometry.
   - layout-core.js remains opt-in for geometry that genuinely depends on measured text.

   Deliberately not wrapped in @layer yet: legacy sheets are still unlayered and would
   outrank layered rules. Cascade layers become safe once the legacy migration is complete. */

/* --------------------------------------------------------------------------
   Intrinsic layout primitives
   -------------------------------------------------------------------------- */
.cyb-split{
  --cyb-split-min:22rem;
  --cyb-split-gap:var(--s-6);
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(var(--cyb-split-min),1fr));
  gap:var(--cyb-split-gap);
  align-items:start;
  min-width:0;
}
.cyb-adaptive-grid{
  --cyb-grid-min:17rem;
  --cyb-grid-gap:var(--s-4);
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(var(--cyb-grid-min),1fr));
  gap:var(--cyb-grid-gap);
  min-width:0;
}
.cyb-panel{
  width:100%;
  max-width:100%;
  min-width:0;
  padding:clamp(var(--s-4),3cqi,var(--s-6));
  border:1px solid var(--cyb-line);
  border-radius:var(--cyb-radius-md);
  background:var(--cyb-surface);
  container-type:inline-size;
}
.cyb-panel>:first-child{margin-top:0}
.cyb-panel>:last-child{margin-bottom:0}

/* --------------------------------------------------------------------------
   Stable values and metric surfaces
   -------------------------------------------------------------------------- */
.cyb-metric{
  min-width:0;
  container-type:inline-size;
}
.cyb-metric__value{
  display:block;
  max-width:100%;
  font:400 clamp(1.65rem,12cqi,3.4rem)/1 var(--cyb-display);
  letter-spacing:-.035em;
  font-variant-numeric:tabular-nums lining-nums;
  color:var(--cyb-fg);
}
.cyb-metric__label{
  display:block;
  margin-top:var(--s-2);
  font:500 var(--t-xs)/1.45 var(--cyb-mono);
  letter-spacing:.09em;
  text-transform:uppercase;
  color:var(--cyb-fg-3);
  overflow-wrap:anywhere;
}

/* Semantic atoms are the only ordinary text primitive allowed to opt out of
   wrapping. The unit/operator travels with the value because splitting it would
   change meaning, not because a page author happened to prefer one line. */
.cyb-value-atom{
  display:inline-flex;
  align-items:baseline;
  gap:.28em;
  max-width:100%;
  white-space:nowrap;
  font-variant-numeric:tabular-nums lining-nums;
}
/* Legacy page sheets still carry blanket descendant rules for this region —
   .pilots-signals span sets .68rem mono, which outranks a lone .cyb-value-atom
   and silently shrank every proof figure to label size. The value owns its own
   typography; its atoms inherit it. Same strategy as the child-combinator
   selectors below: enough specificity to win while the legacy sheets remain. */
.cyb-proof-stat__value .cyb-value-atom,
.cyb-proof-stat__value .cyb-value-atom>span{
  font:inherit;
  letter-spacing:inherit;
  text-transform:none;
  color:inherit;
}
.cyb-value-line{
  display:grid;
  width:max-content;
  max-width:100%;
  gap:.12em;
  align-items:baseline;
}
.cyb-value-line__row{
  display:inline-flex;
  align-items:baseline;
  gap:.2em;
  max-width:100%;
  white-space:nowrap;
}
.cyb-operator{
  font-size:.44em;
  letter-spacing:.06em;
  line-height:1;
  color:var(--cyb-fg-3);
  font-weight:500;
}

/* --------------------------------------------------------------------------
   Proof-stat component
   -------------------------------------------------------------------------- */
/* A grid holding a single stat would otherwise leave its remaining tracks
   empty and the grid's line-coloured background would show through them as a
   slab. A lone stat takes the full width instead. */
.cyb-proof-grid:has(> .cyb-proof-stat:only-child){
  grid-template-columns:1fr;
}
/* A lone stat has the full width to itself, so stacking figure over label
   strands most of the card. Set the figure beside its label instead, and let
   the row wrap the label underneath once there is no longer room for it.

   Flex wrapping, not a container query, does the stacking on purpose. The card
   carries container-name:cyb-proof-stat, so a query on that name may only
   change the card's descendants; restyling the card itself from its own query
   is the invalid pattern the card-local section below warns about. The first
   attempt here did exactly that, and WebKit did not merely ignore it — the
   render process went away mid-measurement, sixty-eight seconds after the
   previous viewport had measured cleanly, while Chromium rendered all four
   viewports without complaint. Wrapping needs no query, so the pattern does
   not arise at any threshold. verify-adaptive-ui.js now rejects it outright. */
.cyb-proof-grid:has(> .cyb-proof-stat:only-child) > .cyb-proof-stat{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  /* Centred, like the CTA row directly beneath it. A single figure left-aligned
     in a full-bleed card strands the right two-fifths of the panel. */
  justify-content:center;
  column-gap:clamp(1.75rem,5cqi,3.5rem);
  row-gap:clamp(.7rem,3cqi,1rem);
}
/* The icon stays at its authored size and leads the row. It cannot take a line
   of its own here: an inline SVG given a full-width flex basis scales its
   drawing to that width and centres it, which left a 12px glyph stranded in the
   middle of the card. At the card's own scale it reads as an instrument mark
   beside the figure instead. */
.cyb-proof-grid:has(> .cyb-proof-stat:only-child) > .cyb-proof-stat > .cyb-semantic-icon{
  flex:0 0 auto;
  inline-size:clamp(1.15rem,3.6cqi,1.8rem);
  block-size:clamp(1.15rem,3.6cqi,1.8rem);
}
.cyb-proof-grid:has(> .cyb-proof-stat:only-child) > .cyb-proof-stat > .cyb-proof-stat__value{
  flex:0 0 auto;
}
/* 22rem is the narrowest the label reads well beside the figure; below that it
   takes the next line and the full width of the card. */
.cyb-proof-grid:has(> .cyb-proof-stat:only-child) > .cyb-proof-stat > .cyb-proof-stat__label{
  flex:1 1 22rem;
  align-self:center;
  max-width:46ch;
}
.cyb-proof-grid{
  display:grid;
  /* Explicit tracks, not auto-fit. This grid has to stay an inline-size
     container so `@container cyb-proof-grid` below can restyle its cards, and
     WebKit 256047 collapses auto-fit tracks to zero under exactly that
     containment on every stable Safari from 16.0 to 18.6. The counts below
     reproduce what auto-fit resolved to at the same widths — one stat per row
     on a phone, the full row from 641px up — so nothing moves, and the card
     count drives the track count rather than an intrinsic minimum. */
  grid-template-columns:1fr;
  gap:1px;
  min-width:0;
  overflow:hidden;
  border:1px solid var(--cyb-line);
  border-radius:var(--cyb-radius-sm);
  background:var(--cyb-line);
  container-type:inline-size;
  container-name:cyb-proof-grid;
}
@media (min-width:40.0625rem){
  .cyb-proof-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .cyb-proof-grid:has(> .cyb-proof-stat:nth-child(2):last-child){grid-template-columns:repeat(2,minmax(0,1fr))}
  .cyb-proof-grid:has(> .cyb-proof-stat:nth-child(4)){grid-template-columns:repeat(4,minmax(0,1fr))}
}
/* The child-combinator selectors deliberately give the component enough
   specificity to own its geometry while legacy page sheets are still present. */
.cyb-proof-grid>.cyb-proof-stat{
  display:grid;
  grid-template-rows:auto auto 1fr;
  align-content:start;
  gap:clamp(.7rem,3cqi,1rem);
  min-width:0;
  padding:clamp(1.65rem,4cqi,3rem) clamp(1.35rem,3cqi,2.5rem) clamp(1.7rem,3.5cqi,2.8rem);
  background:var(--cyb-bg-2);
  container-type:inline-size;
  container-name:cyb-proof-stat;
}
.cyb-proof-grid>.cyb-proof-stat>.cyb-semantic-icon{
  grid-row:1;
  align-self:start;
  margin:0;
}
.cyb-proof-stat>.cyb-proof-stat__value{
  grid-row:2;
  display:flex;
  align-items:baseline;
  flex-wrap:wrap;
  gap:.08em .18em;
  min-width:0;
  max-width:100%;
  margin:0;
  font:400 clamp(2.25rem,14cqi,4.55rem)/.98 var(--cyb-display);
  letter-spacing:-.045em;
  font-variant-numeric:tabular-nums lining-nums;
  color:var(--cyb-fg);
  text-wrap:balance;
}
.cyb-proof-stat>.cyb-proof-stat__label{
  grid-row:3;
  align-self:end;
  max-width:34ch;
  min-width:0;
  font:500 clamp(.76rem,3.7cqi,.9rem)/1.55 var(--cyb-mono);
  letter-spacing:.105em;
  text-transform:uppercase;
  color:var(--cyb-fg-3);
  overflow-wrap:anywhere;
  text-wrap:pretty;
}
.cyb-proof-stat[data-proof-layout="trajectory"]>.cyb-proof-stat__value{
  display:grid;
  width:max-content;
  max-width:100%;
  gap:.08em;
  font-size:clamp(2.05rem,12cqi,3.85rem);
  line-height:1.03;
}
.cyb-proof-stat[data-proof-layout="trajectory"] .cyb-value-line__row{
  width:max-content;
}

/* Card-local adaptation. A query changes descendants of the card; the card
   itself is sized intrinsically by the grid. This avoids the invalid pattern of
   trying to restyle a query container from its own container query. */
@container cyb-proof-stat (max-width:22rem){
  .cyb-proof-stat>.cyb-proof-stat__value{
    font-size:clamp(2rem,13cqi,3rem);
  }
  .cyb-proof-stat[data-proof-layout="trajectory"]>.cyb-proof-stat__value{
    font-size:clamp(1.9rem,11cqi,2.65rem);
  }
  .cyb-proof-stat>.cyb-proof-stat__label{
    align-self:start;
    font-size:clamp(.72rem,3.6cqi,.84rem);
  }
}
/* Grid-local queries change child cards, never the query container itself. */
@container cyb-proof-grid (max-width:54rem){
  .cyb-proof-grid>.cyb-proof-stat{
    padding:var(--s-5) var(--s-4);
  }
}

/* --------------------------------------------------------------------------
   Evidence citations
   -------------------------------------------------------------------------- */
/* The proof panel promises granted patents and peer-reviewed research. Until
   now it delivered a statistic and two links to pages that hold them, which is
   a claim that evidence exists rather than the evidence. Each citation here is
   a primary source a reader can retrieve and check against the public record
   instead of a paraphrase.

   Governed by docs/website/CLAIMS-AND-EVIDENCE.md: only artifacts that document
   lists as current public-safe proof belong here, and its blocked-claims list
   tracks the three granted patents now linked. */
/* The panel carries two kinds of evidence and they are not equally checkable.
   Engagement figures come from our own records; the patents and the paper are
   on the public record. Labelling the bands is the difference between a reader
   trusting the whole panel and a reader knowing which half they can verify. */
.pilots-band-label{
  margin:var(--s-4) 0 .55rem;
  font:500 var(--cyb-label-min)/1.4 var(--cyb-mono);
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--cyb-fg-3);
}
/* The citation band uses explicit column counts instead of the
   repeat(auto-fit,minmax(min(...),1fr)) idiom the rest of this file favours.
   Shipping Safari laid this component out as three overlapping, near-zero-width
   cells while the <ol> itself painted at full width — the citations were drawn
   on top of each other and unreadable. The auto-fit idiom, a container query on
   the grid, and cqi units inside it were all in play at once, and the same
   family of constructs is what killed the WebKit render process in #105.
   Stepped breakpoints reproduce the intended layout exactly (one column, two,
   then three, matching what auto-fit resolved to at the same widths) and cannot
   be mis-parsed into a degenerate track list by any engine.

   Separators are real borders rather than a 1px gap painted over the container
   background, so an engine that drops the gap cannot collapse the cells onto
   each other either. */
.cyb-evidence-trail{
  display:grid;
  grid-template-columns:1fr;
  margin:0;
  padding:0;
  min-width:0;
  overflow:hidden;
  list-style:none;
  border:1px solid var(--cyb-line);
  border-radius:var(--cyb-radius-sm);
  background:var(--cyb-bg-2);
}
.cyb-evidence-trail>.cyb-evidence-cite{
  display:grid;
  align-content:start;
  gap:.4rem;
  min-width:0;
  padding:1.3rem 1.15rem;
  list-style:none;
  border-top:1px solid var(--cyb-line);
}
.cyb-evidence-trail>.cyb-evidence-cite:first-child{border-top:0}
@media (min-width:40rem) and (max-width:63.99rem){
  .cyb-evidence-trail{grid-template-columns:repeat(2,1fr)}
  .cyb-evidence-trail>.cyb-evidence-cite{border-top:0;border-left:1px solid var(--cyb-line)}
  .cyb-evidence-trail>.cyb-evidence-cite:nth-child(2n+1){border-left:0}
  .cyb-evidence-trail>.cyb-evidence-cite:nth-child(n+3){border-top:1px solid var(--cyb-line)}
}
@media (min-width:64rem){
  .cyb-evidence-trail{grid-template-columns:repeat(3,1fr)}
  .cyb-evidence-trail>.cyb-evidence-cite{
    padding:1.5rem 1.3rem;
    border-top:0;
    border-left:1px solid var(--cyb-line);
  }
  .cyb-evidence-trail>.cyb-evidence-cite:nth-child(3n+1){border-left:0}
  .cyb-evidence-trail>.cyb-evidence-cite:nth-child(n+4){border-top:1px solid var(--cyb-line)}
}
.cyb-evidence-cite__kind{
  font:500 .67rem/1.4 var(--cyb-mono);
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--cyb-fg-3);
}
/* The identifier is the link, because the identifier is what a reader checks. */
.cyb-evidence-cite__id{
  font:500 .95rem/1.3 var(--cyb-mono);
  letter-spacing:.01em;
  color:var(--cyb-accent);
  text-decoration:none;
  overflow-wrap:anywhere;
}
.cyb-evidence-cite__id:hover,.cyb-evidence-cite__id:focus-visible{text-decoration:underline}
.cyb-evidence-cite__title{
  font-size:.84rem;
  line-height:1.5;
  color:var(--cyb-fg-2);
  text-wrap:pretty;
}
/* The engagement bands and the citation band are one stacked instrument, so the
   band above gives up its bottom edge rather than closing the stack early. */
.cyb-evidence-cite__meta{
  font:500 .68rem/1.45 var(--cyb-mono);
  letter-spacing:.05em;
  color:var(--cyb-fg-3);
  overflow-wrap:anywhere;
}

/* --------------------------------------------------------------------------
   Data and loading states
   -------------------------------------------------------------------------- */
.cyb-data-state,
.cyb-loading-state{
  display:grid;
  place-items:center;
  gap:var(--s-3);
  min-block-size:12rem;
  padding:var(--s-6);
  text-align:center;
  color:var(--cyb-fg-2);
}
.cyb-data-state__title,
.cyb-loading-state__title{
  margin:0;
  font:500 var(--t-lg)/1.2 var(--cyb-display);
  color:var(--cyb-fg);
}
.cyb-data-state__copy,
.cyb-loading-state__copy{
  max-width:52ch;
  margin:0;
  color:var(--cyb-fg-3);
}

/* --------------------------------------------------------------------------
   First migration: homepage Enterprise Validation
   --------------------------------------------------------------------------
   Section-specific hierarchy stays here only while the homepage surface itself
   is being consolidated. The proof geometry above is generic and reusable. */
.pilots .pilots-head{
  align-items:end;
  gap:clamp(2rem,5vw,6rem);
}
.pilots .pilots-head h3{
  max-width:17ch;
  line-height:1.12;
  letter-spacing:-.018em;
  text-wrap:balance;
}
.pilots .pilots-note{
  max-width:47ch;
  text-wrap:pretty;
}
.pilots .pilots-sectors{
  white-space:normal;
  text-align:right;
  line-height:1.55;
}
/* The shared proof-grid primitive owns its track geometry. */
.pilots .pilots-signals.cyb-proof-grid{
  align-items:stretch;
}

@media (max-width:720px){
  .pilots .pilots-head{align-items:start}
  .pilots .pilots-sectors{text-align:left}
}

@media (prefers-reduced-motion:reduce){
  .cyb-data-state *,
  .cyb-loading-state *{scroll-behavior:auto}
}


/* Keep adaptive grids definite before intrinsic track sizing.  WebKit resolves
   percentage minima inside an indefinite auto-fit grid against its min-content
   width; a definite track minimum plus a container-level collapse point keeps
   Blink, WebKit, and Gecko on the same geometry. */
.cyb-panel,.cyb-split,.cyb-adaptive-grid,.cyb-proof-grid{
  width:100%;
  max-width:100%;
  min-width:0;
}
/* These two are auto-fit grids, so they must not also be inline-size
   containers: WebKit 256047 collapses every auto-fit track to zero when
   inline-size containment is applied to the grid box, laying the children out
   at near-zero width while the grid itself paints at full width. It is fixed
   in Safari 26 and broken in every stable Safari from 16.0 to 18.6, which is
   what most visitors are running. Nothing queries either of these as a
   container — the two unnamed queries below have them as their subject, and a
   query resolves against an ancestor container, never the element itself — so
   dropping containment costs nothing and keeps the auto-fit semantics intact.
   verify-adaptive-ui.js now rejects the combination outright. */
@container (max-width:22rem){
  .cyb-split{grid-template-columns:1fr}
}
@container (max-width:17rem){
  .cyb-adaptive-grid{grid-template-columns:1fr}
}
