/* ============================================================================
   src/cortex/cortex.css — the /cortex page frame (cortex.html, cortex.js)
   ----------------------------------------------------------------------------
   The approved mockup (the design notes (cortex-mockup/index.html))
   transcribed onto the site: the site's own header (topnav.css via
   shell.css), the proof modules (proof.css: motion, panel, timeframe), and
   the parts below. Every colour resolves through src/shared/tokens.css and
   tokens-dark.css; there is no literal colour in this file.

   WHAT LIVES HERE (Agent A)
     · the page frame (.cx-main) and a scoped reset
     · the shared title row that never moves: eyebrow, h1, lead, and the
       About / Skills switch — timeframe.js's sliding pill (.pf-tabs)
     · the view stage: the direction-aware two-phase swap (Meridian #75)
     · the section rise: `.cx-rise` (rise-14) and `.cx-rise8` (rise-8), armed
       by cortex.js through reveal.js's `.is-inview`, with a +0.06s ladder for
       what is on screen after a swap. Either view may use both classes.
     · the page vocabulary BOTH views wear, so neither view sheet restates
       it: sections (.cx-sect, .cx-sect-head, .cx-label, .cx-h2, .cx-note,
       .cx-k), the panel (.cx-panel), buttons (.cx-btn + --primary / --sm /
       --block / --danger, .cx-nudge), the maturity chip (.cx-chip), the
       "not yet measured" badge (.cx-badge), the text input (.cx-input), the
       14px glyph (.cx-ic) and the page's icon sprite (.cx-defs).
   ========================================================================== */

/* ══ page base ════════════════════════════════════════════════════════════ */
html{ scrollbar-gutter:stable; }
body{ overflow-x:clip; }

/* a scoped reset, at zero specificity so every class rule below (and the
   proof modules') wins over it */
:where(.cx-main) :where(h1,h2,h3,h4,h5,p,ul,ol,dl,dd,figure,pre){ margin:0; }
:where(.cx-main) :where(ul,ol){ padding:0; list-style:none; }
:where(.cx-main) :where(a){ color:inherit; }

/* the icon sprite cortex.html carries (#i-check, #i-arrow, #i-close …) */
.cx-defs{ position:absolute; width:0; height:0; overflow:hidden; }
.cx-ic{ width:14px; height:14px; flex:none; display:block; }

/* without scripts: the page is a document. Controls that need JS go, and the
   rise never arms (cx-js is set by the <head> script) */
html:not(.cx-js) .cx-needs-js{ display:none !important; }
.cx-noscript{ margin-top:var(--sp-18); padding:var(--sp-13) var(--sp-15); border:1px dashed var(--border); border-radius:var(--r-9); color:var(--graphite); font-size:var(--fs-base-p); line-height:var(--lh-relaxed); }

/* ══ the frame ════════════════════════════════════════════════════════════
   .pf-main (panel.css) gives the 1180px column and its 16/18px gutters; the
   page runs a deeper floor (96px) and the mockup's 14px / 1.5 body. */
.pf-main.cx-main{ padding-bottom:96px; font-size:var(--fs-xl); line-height:var(--lh-relaxed); }

/* ══ the shared title row: it never moves; only the stage below swaps ═════ */
.cx-titlerow{
  display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:end; gap:var(--sp-15) var(--sp-18);
  padding-bottom:var(--sp-17); border-bottom:1px solid var(--border);
}
.cx-titlerow > *{ min-width:0; }
/* .pf-herocopy (panel.css) carries the rise-16 0 / .06 / .12s ladder; the
   switch lands last, at .18s */
.cx-switchwrap{ animation:rise-16 var(--dur-400) var(--mrd-ease-out-cubic) .18s both; }
.cx-titlerow h1{
  font-family:var(--font-display); font-size:clamp(31px, 4.2vw, 43px); font-weight:var(--fw-medium);
  line-height:1.08; letter-spacing:-.035em; color:var(--ink);
}
.cx-titlerow .pf-lead{ max-width:76ch; text-wrap:balance; }
@media (max-width:720px){ .cx-titlerow{ grid-template-columns:1fr; } }

/* ══ the About / Skills switch — timeframe.js's pill (Meridian PiTabs) ═════
   The trough, the raised chip and its 0.24s out-quint slide are
   timeframe.css; the page only widens the two buttons and, on a phone,
   gives them the full row. */
.cx-switch{ overflow:visible; }
.cx-switch .pf-tabs__btn{ padding-inline:var(--sp-17); }
@media (max-width:720px){
  .cx-switch{ display:flex; width:100%; }
  .cx-switch .pf-tabs__btn{ flex:1 1 0; padding-inline:var(--sp-5); text-align:center; }
}

/* ══ the view stage — the direction-aware two-phase swap (Meridian §1.4.6)
   Leave: the outgoing view fades (0.14s) and drifts 10px toward the travel
   direction (0.18s in-out). At 180ms the DOM swaps; the incoming view is
   placed 10px on the OTHER side with no transition, then (double rAF) it
   transitions home. Reduced motion: an instant swap. */
/* each view is its own block formatting context, so its sections' margins
   stay inside it (the same layout: nothing outside it has a margin to
   collapse with) and a collapsed view below takes exactly 0px */
.cx-stage > .cx-view{ display:flow-root; transition:opacity 0.14s ease, transform 0.18s var(--mrd-ease-in-out); }
/* the incoming view during the leave: laid out, but 0px tall, clipped and
   unseen (cortex.js prelayout); the same display, so showing it at the swap
   keeps that layout instead of rebuilding it. It beats shell.css's
   [hidden]{display:none !important} on specificity. */
.cx-stage > .cx-view[hidden].is-prelayout{ display:flow-root !important; max-height:0; overflow:clip; visibility:hidden; pointer-events:none; }
.cx-stage.is-leaving > .cx-view,
.cx-stage.is-entering > .cx-view{ opacity:0; }
.cx-stage[data-direction="forward"].is-leaving > .cx-view,
.cx-stage[data-direction="back"].is-entering > .cx-view{ transform:translateX(-0.625rem); }
.cx-stage[data-direction="forward"].is-entering > .cx-view,
.cx-stage[data-direction="back"].is-leaving > .cx-view{ transform:translateX(0.625rem); }
.cx-stage.is-entering > .cx-view{ transition:none; }

/* ══ the rise — reveal.js's `.is-inview`, the page's own two keyframes ═════
   After a swap the sections on screen rise on a +0.06s ladder (`--d`, set by
   cortex.js); below the fold they wait for the scroll reveal. */
.cx-js .cx-rise:not(.is-inview),
.cx-js .cx-rise8:not(.is-inview){ opacity:0; }
.cx-rise.is-inview{ animation:rise-14 var(--dur-400) var(--mrd-ease-out-cubic) var(--d, 0s) both; }
.cx-rise8.is-inview{ animation:rise-8 var(--dur-350) var(--mrd-ease-out-cubic) var(--d, 0s) both; }

/* ══ sections ═════════════════════════════════════════════════════════════ */
.cx-sect{ margin-top:56px; padding-top:var(--sp-17); border-top:1px solid var(--border); }
.cx-sect:first-child{ margin-top:var(--sp-21); padding-top:0; border-top:0; }
.cx-sect-head{ display:flex; align-items:flex-end; justify-content:space-between; gap:var(--sp-15); flex-wrap:wrap; margin-bottom:var(--sp-18); }
.cx-label{ font:var(--fw-bold) var(--fs-sm) var(--font-mono); letter-spacing:var(--ls-10); text-transform:uppercase; color:var(--acc); margin-bottom:var(--sp-9); }
.cx-sect h2, .cx-h2{ font-family:var(--font-display); font-size:var(--fs-21); font-weight:var(--fw-medium); letter-spacing:-.03em; line-height:1.2; color:var(--ink); }
.cx-note{ color:var(--graphite); font-size:var(--fs-base-p); line-height:var(--lh-relaxed); margin-top:var(--sp-5); max-width:68ch; }
.cx-k{ font:var(--fw-medium) var(--fs-md)/16px var(--font-mono); letter-spacing:var(--ls-10); text-transform:uppercase; color:var(--graphite); }
.cx-panel{ padding:var(--sp-17); border:1px solid var(--border); border-radius:var(--r-9); background:var(--paper); }
@media (max-width:680px){ .cx-panel{ padding:var(--sp-15); } }

/* ══ buttons ══════════════════════════════════════════════════════════════
   Primary is brand fill with an ink label (--on-brand in dark), the docs
   `.action.primary` precedent, for AA contrast. A disabled primary drops the
   fill AND the on-brand label (in dark --on-brand is the paper colour). */
.cx-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-7);
  min-height:40px; padding:0 var(--sp-15); border:1px solid var(--border); border-radius:var(--r-11);
  background:var(--paper); color:var(--ink); font:var(--fw-medium) var(--fs-lg)/1.2 var(--font-body);
  text-decoration:none; white-space:nowrap; cursor:pointer;
  transition:border-color var(--mrd-duration-fast) var(--mrd-ease-in-out), background-color var(--mrd-duration-fast) var(--mrd-ease-in-out), color var(--mrd-duration-fast) var(--mrd-ease-in-out);
}
.cx-btn:hover{ border-color:var(--brand-55); background:var(--brand-06); }
.cx-btn:active{ opacity:.6; }
.cx-btn:focus-visible{ outline:2px solid var(--brand); outline-offset:2px; }
.cx-btn--primary{ background:var(--brand); border-color:var(--brand); color:var(--on-brand, var(--ink)); font-weight:var(--fw-semibold); }
.cx-btn--primary:hover{ background:var(--brand-88); border-color:var(--brand-88); }
.cx-btn--block{ width:100%; }
.cx-btn--sm{ min-height:34px; padding:0 var(--sp-11); font-size:var(--fs-base-p); border-radius:var(--r-9); }
.cx-btn:disabled, .cx-btn[aria-disabled="true"]{ opacity:.5; cursor:not-allowed; border-style:dashed; background:var(--paper); }
.cx-btn:disabled:hover, .cx-btn[aria-disabled="true"]:hover{ border-color:var(--border); background:var(--paper); }
.cx-btn--primary:disabled, .cx-btn--primary[aria-disabled="true"],
.cx-btn--primary:disabled:hover, .cx-btn--primary[aria-disabled="true"]:hover{ color:var(--ink); background:var(--paper); border-color:var(--border); }
.cx-btn svg{ width:14px; height:14px; flex:none; transition:transform var(--mrd-duration-fast) var(--mrd-ease-in-out); }
.cx-btn:hover .cx-nudge{ transform:translateX(2px); }
.cx-btn--danger{ color:var(--danger-text); }
.cx-btn--danger:hover{ border-color:var(--danger-text); background:var(--brand-06); }
@media (pointer:coarse){ .cx-btn, .cx-btn--sm{ min-height:44px; } }

/* ══ chips, badge, input ══════════════════════════════════════════════════
   All five maturity rungs wear the same neutral chip: no colour ladder, so
   nothing reads as a rating. */
.cx-chip{
  display:inline-flex; align-items:center; gap:var(--sp-3); height:22px;
  padding:0 var(--sp-7); border:1px solid var(--border); border-radius:var(--r-full);
  background:var(--brand-06); color:var(--ink);
  font:var(--fw-semibold) var(--fs-sm)/20px var(--font-mono); letter-spacing:var(--ls-10); text-transform:uppercase; white-space:nowrap;
}
.cx-badge{
  display:inline-flex; align-items:center; padding:1px var(--sp-5); border:1px dashed var(--graphite); border-radius:var(--pf-r-4);
  color:var(--graphite); font:var(--fw-bold) var(--fs-sm)/16px var(--font-mono); letter-spacing:var(--ls-10); text-transform:uppercase; white-space:nowrap;
}
.cx-input{
  min-height:44px; padding:0 var(--sp-13); border:1px solid var(--border); border-radius:var(--r-10);
  background:var(--paper); color:var(--ink); font-size:var(--fs-16);
  transition:border-color var(--mrd-duration-fast) var(--mrd-ease-in-out);
}
.cx-input::placeholder{ color:var(--graphite); opacity:.85; }
.cx-input:focus{ outline:none; border-color:var(--brand-55); box-shadow:0 0 0 3px var(--brand-12); }
.cx-input:disabled{ opacity:.6; cursor:not-allowed; }

/* ══ reduced motion — layer 2 (motion.css owns layer 1): every end state ══ */
@media (prefers-reduced-motion: reduce){
  .cx-rise, .cx-rise8, .cx-switchwrap, .pf-herocopy > *{ animation:none !important; opacity:1 !important; transform:none !important; }
  .cx-stage > .cx-view{ transition:none !important; opacity:1 !important; transform:none !important; }
}
