/* cpa-public.css -- the public scale overlay.
 *
 * WHAT THIS IS. The marketing surfaces and the app share one palette, one accent and one
 * component layer, and differ only in DENSITY: a marketing hero wants 54px type and 96px of
 * vertical air where a dense portal table wants neither. This file carries that difference and
 * nothing else.
 *
 * THE RULE, and it is enforced rather than asked for. This overlay may change SCALE only --
 * spacing, type, radius, elevation. It may NOT declare a colour role and it may NOT write to
 * `:root`. `tools/public_scale_overlay_contract_check.py` fails the build on either. That rule
 * is what keeps this one design system instead of two.
 *
 * WHY NOT JUST SHIP mockups/tokens-public.css. That file was the design source, and its own
 * header makes the right argument -- but it is a standalone token block: 26 colour-role
 * declarations in `:root`. Measured against the shipped system on 2026-08-06, every one of
 * those colour values is byte-identical to the `--cpa-*` token it shadows, contrast comments
 * included. So re-declaring them buys nothing today and costs correctness tomorrow: the plain
 * roles (`--bg`, `--accent`) are `var(--cpa-*)` indirections precisely so that
 * `[data-theme]` and `[data-color-mode]` can retarget them in one place. A literal in `:root`
 * would win, and the public pages would quietly stop following the theme -- identical pixels
 * on the day it landed, a fork on the first day either side moved. Same values are not the
 * same system.
 *
 * WHY THE ALIASES BELOW. The shipped `--cpa-*` vocabulary already owns radius, control height,
 * font stack and card shadow. Copying the mockup's `--radius-md: 14px` verbatim would create a
 * SECOND name for a concept the system already has -- a fork by renaming rather than by colour,
 * and one no colour-role check would catch. So where the system owns the concept we alias it,
 * and only genuinely public-only scale is introduced new.
 *
 * SCOPE. Attribute-scoped to `[data-cpa-surface="public"]`, never `:root`, because the design
 * source is explicit that everything behind sign-in keeps the app scale unchanged. `/` does not
 * carry the marker yet: it is still both the signed-out landing and the signed-in dashboard, so
 * it takes the marker when Phase 2.2 splits `/dashboard` out and `/` becomes public-only.
 */

[data-cpa-surface="public"] {
  /* ---- aliases: the app already owns these; do not fork them ---- */
  --radius-xs: var(--cpa-radius-xs);
  --radius-sm: var(--cpa-radius-sm);
  --radius-md: var(--cpa-radius-md);
  --radius-lg: var(--cpa-radius-lg);
  --radius-pill: 999px;
  --shadow-card: var(--cpa-shadow-card);
  --control-h: var(--cpa-control-height);

  /* ---- type scale: public-only sizes the app has no use for ---- */
  --fs-micro: 12px;
  --fs-small: 14px;
  --fs-body: 16px;
  --fs-h4: 17px;
  --fs-h3: 20px;
  --fs-h2: 26px;
  --fs-h1: 34px;
  --fs-hero: 54px;
  --fs-lede: 20px;
  --fs-stat: 38px;

  --lh-body: 1.6;
  --lh-h1: 1.2;
  --lh-h2: 1.25;
  --lh-h3: 1.35;
  --lh-h4: 1.4;
  --lh-hero: 1.1;
  --lh-lede: 1.55;

  --fw-heading: 680;
  --fw-stat: 700;
  --track-heading: -0.02em;

  /* ---- spacing: --space-7 is the marketing section rhythm ---- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 56px;

  /* ---- layout: hero and section geometry, public surfaces only ---- */
  --control-h-lg: 54px;
  --measure: 66ch;
  --measure-wide: 1180px;
  --stat-min: 190px;
  --feature-min: 280px;
  --feature-pad: 24px;
  --hero-pad: 96px;
  --section-pad: 72px;
  --hero-align: center;
  --hero-text-align: center;
  --step-dot: 28px;
  --row-pad-y: 14px;
}

/* The hero condenses before it wraps: 54px over a 375px viewport is four words a line. */
@media (max-width: 720px) {
  [data-cpa-surface="public"] {
    --fs-hero: 34px;
    --fs-lede: 17px;
    --fs-stat: 30px;
    --hero-pad: 48px;
    --section-pad: 40px;
    --space-7: 36px;
  }
}

/* Honour a reduced-motion preference for the one place this overlay implies movement. */
@media (prefers-reduced-motion: reduce) {
  [data-cpa-surface="public"] * {
    scroll-behavior: auto;
  }
}

/* ------------------------------------------------------------------------------------------
 * THE RULES THAT CONSUME THE TOKENS ABOVE.
 *
 * Tokens alone render nothing. Declaring 52 custom properties that no rule reads is a file
 * that passes its own contract check and changes zero pixels -- which is exactly what this
 * overlay was until these rules were added, so the omission is recorded rather than quietly
 * fixed.
 *
 * Every declaration here is scale. There is not one colour in this block, and the contract
 * check fails the build if that changes.
 *
 * MEASURED BEFORE, on marketing.html at 1440px, because two of these are corrections and not
 * preferences:
 *   - h1 computed 25.92px while h2 computed 32px. The page's type hierarchy was INVERTED: the
 *     section headings outranked the page title. --fs-hero and --fs-h2 put that back.
 *   - the page was capped at 720px on a 1440px viewport, so half the screen was margin. That
 *     is what --measure-wide is for.
 *
 * ON `!important`, WHICH THIS FILE USES SPARINGLY AND ON PURPOSE.
 *
 * The first draft of this block used none, on the theory that loading after cpa-ui.css and
 * matching its specificity would let document order decide. Rendering disproved it: font-weight
 * and line-height applied, and font-size and max-width did not. `cpa-ui.css:2567` sets
 *
 *     .header h1, .user-header h1, .panel-header h1 { font-size: clamp(1.45rem,1.8vw,2rem) !important }
 *
 * and marketing.html's hero is `<header class="user-header lbc-page-hero">`. Across cpa-ui.css
 * and portal_ui/styles.css there are 35 `!important` font-sizes and 12 `!important` max-widths:
 * typography in this codebase is pervasively !important, so a clean rule cannot win and the
 * overlay would have shipped looking like it worked while changing nothing.
 *
 * So `!important` appears here on exactly the two properties measured to need it -- font-size
 * and max-width -- and nowhere else. font-weight, line-height and letter-spacing are left clean
 * because they were verified to apply without it. The right long-term fix is to unwind the
 * !important typography in cpa-ui.css; that file is being edited by another agent right now, so
 * it is deliberately untouched here rather than raced.
 * ------------------------------------------------------------------------------------------ */

/* The measure. This selector is long for a reason worth stating.
 *
 * `body:not(.is-authenticated):not(.auth-pending) .auth-panel` in cpa-ui.css sets
 * `max-width: 720px !important` at specificity (0,3,1). That width is correct for what it was
 * written for -- the signed-out LOGIN CARD -- but marketing.html and pricing.html both use
 * `.auth-panel` as their page shell, so the product overview and the price list inherited a
 * form's measure: 720px of a 1440px viewport, with half the screen as margin. That is why the
 * marketing page reads narrow, and it is a genuine defect rather than a preference.
 *
 * A (0,2,0) selector loses to it even with !important, which is exactly what the first attempt
 * did. This one is (0,4,1) so it wins outright rather than tying at (0,3,1) and depending on
 * stylesheet order -- a tie would work today and break the first time the files are reordered
 * or concatenated by a bundler. */
body[data-cpa-surface="public"] .auth-panel.user-card.portal-width {
  max-width: var(--measure-wide) !important;
}

[data-cpa-surface="public"] .lbc-page-hero h1,
[data-cpa-surface="public"] .lbc-public-hero h1 {
  font-size: var(--fs-hero) !important;
  line-height: var(--lh-hero);
  font-weight: var(--fw-heading);
  letter-spacing: var(--track-heading);
}

[data-cpa-surface="public"] .brand-lede {
  font-size: var(--fs-lede) !important;
  line-height: var(--lh-lede);
  max-width: var(--measure) !important;
}

[data-cpa-surface="public"] .project-kicker {
  font-size: var(--fs-micro) !important;
}

/* h2 below h1, which is the whole point of the correction noted above. */
[data-cpa-surface="public"] h2 {
  font-size: var(--fs-h2) !important;
  line-height: var(--lh-h2);
  font-weight: var(--fw-heading);
  letter-spacing: var(--track-heading);
}

[data-cpa-surface="public"] h3 {
  font-size: var(--fs-h3) !important;
  line-height: var(--lh-h3);
  font-weight: var(--fw-heading);
}

/* Section rhythm: the marketing surfaces breathe where the portal is dense. */
[data-cpa-surface="public"] .lbc-marketing-section,
[data-cpa-surface="public"] .lbc-public-section {
  padding-block: var(--section-pad);
}

[data-cpa-surface="public"] .lbc-page-hero {
  padding-bottom: var(--hero-pad);
}
