/* ===========================================================================
   Pricing cards — the shared Launch / Pro comparison.

   Lifted verbatim out of ui_concept/pages/upgrade.html's <style> block so any
   page rendering the pricing partial shares one component instead of a copy
   that drifts. Every rule below is the upgrade page's original; the only
   edits are mechanical:

     1. Selectors are scoped under `.pricing-cards` (the wrapper the partial
        renders). Everything is prefixed equally, so relative specificity —
        and therefore the cascade order these rules were written against — is
        unchanged.
     2. Design tokens are read through `--pc-*` aliases declared on the wrapper
        below. Each alias is `var(--<app token>, <ui_concept light value>)`, so
        inside the dashboard shell the live theme tokens win (light AND dark),
        and on a page without that shell the light values fall through. A
        token change in ui_concept.css still flows here.

   The aliases exist because a custom property cannot reference itself on the
   element that declares it (`--ink: var(--ink, ...)` is a cycle and computes
   to invalid), so re-declaring the app's own token names here is not an
   option.

   Consumed by:
     templates/ui_concept/partials/_pricing_cards.html   (the markup)
     templates/ui_concept/pages/upgrade.html             (dashboard variant)
   =========================================================================== */

.pricing-cards{
  /* --- surfaces & ink --- */
  --pc-ink:          var(--ink, #0F172A);
  --pc-ink-soft:     var(--ink-soft, #475569);
  --pc-paper:        var(--paper, #FFFFFF);
  --pc-well:         var(--well, #F1F3F6);
  --pc-hairline:     var(--hairline, rgba(15,23,42,0.10));

  /* --- accent / brand --- */
  --pc-accent:       var(--accent, #2D64BC);
  --pc-accent-wash:  var(--accent-wash, #EAF0FA);
  --pc-accent-ink:   var(--accent-ink, #2D64BC);
  --pc-brand:        var(--brand, #2D64BC);
  --pc-brand-hover:  var(--brand-hover, #27579F);
  --pc-on-brand:     var(--on-brand, #FFFFFF);
  --pc-gold-ink:     var(--gold-ink, #8F6108);
  --pc-success-wash: var(--success-wash, #E7F5EF);
  --pc-success-ink:  var(--success-ink, #0B6E4F);

  /* --- shape & depth --- */
  --pc-radius-lg:    var(--radius-lg, 12px);
  --pc-radius-ctl:   var(--radius-ctl, 8px);
  --pc-shadow-sm:    var(--shadow-sm, 0 1px 2px rgba(15,23,42,.05));
  --pc-shadow-md:    var(--shadow-md, 0 6px 20px rgba(15,23,42,.07));

  /* --- type --- */
  --pc-font-display: var(--font-display, 'Fraunces', Georgia, 'Iowan Old Style', ui-serif, serif);
  --pc-fs-3xs:       var(--fs-3xs, 10.5px);
  --pc-fs-2xs:       var(--fs-2xs, 11.5px);
  --pc-fs-xs:        var(--fs-xs, 12.5px);
  --pc-fs-sm:        var(--fs-sm, 13px);
  --pc-fs-panel:     var(--fs-panel, clamp(15.5px, 1.9vw, 17px));
  --pc-fs-value-xl:  var(--fs-value-xl, clamp(32px, 8.0vw, 50px));

  /* --- component type scale ---------------------------------------------
     These four do NOT track the app's --fs-* ramp, deliberately.

     The cards used to read straight off --fs-panel (17px) and --fs-value-xl
     (50px), which set the feature list LARGER than the body copy on both
     surfaces that host it (15px on the landing page, 15px in the dashboard).
     A scannable checklist sitting above reading copy in the scale is
     backwards, and at a 461px card width 17px put the longest Launch line at
     ~45 characters, so it wrapped and the card ran tall.

     The price stays clearly dominant inside the card but no longer outshouts
     the 48px section headline it sits under on the landing page. The group
     label comes up slightly so the jump from label to row is not 6.5px. */
  --pc-fs-feature:   clamp(14px, 1.5vw, 15px);   /* feature rows + plan tagline */
  --pc-fs-price:     clamp(30px, 6.0vw, 40px);   /* the plan price */
  --pc-fs-plan-name: clamp(23px, 3.0vw, 27px);   /* "Launch" / "Pro" */
  --pc-fs-group:     11px;                        /* BOOKINGS & CRM etc. */

  /* --- spacing ramp --- */
  --pc-space-2:      var(--space-2,  clamp(6px,  .7vw,  8px));
  --pc-space-3:      var(--space-3,  clamp(8px,  .9vw, 10px));
  --pc-space-4:      var(--space-4,  clamp(8px,  1.0vw, 12px));
  --pc-space-6:      var(--space-6,  clamp(12px, 1.4vw, 16px));
  --pc-space-7:      var(--space-7,  clamp(14px, 1.7vw, 20px));
  --pc-space-8:      var(--space-8,  clamp(16px, 2.0vw, 24px));
  --pc-space-9:      var(--space-9,  clamp(20px, 2.6vw, 32px));
  --pc-space-10:     var(--space-10, clamp(22px, 3.0vw, 36px));
}

/* The partial ships its own two-symbol sprite rather than depending on
   core/_icon_sprite.html: that file is 172 KB of 293 symbols, and the landing
   page — the first thing a prospective vendor ever loads — needs exactly two
   of them. Ids are namespaced (#pc-icon-*) so including this alongside the
   full app sprite cannot collide. */
.pricing-cards .pc-sprite{ position:absolute; width:0; height:0; overflow:hidden; }
.pricing-cards .icon{ display:inline-block; vertical-align:middle; fill:none; }

/* ===== Billing period toggle ===============================================
   Swaps only the Pro price (Launch is free either way). Segmented control in
   the concept button language. */
.pricing-cards .up-billing{
  display:flex; justify-content:center;
  margin-top:var(--pc-space-7);
}
/* Segmented control with a thumb that slides between the two periods instead
   of the fill jumping from one button to the other.

   The thumb is one absolutely-positioned element whose x and width are
   measured from the active button, so the two labels keep their natural
   (unequal) widths. --up-seg-dur is shared by the slide and by the label
   colour fade so the two read as a single movement rather than the text
   flipping white before the thumb arrives. */
.pricing-cards .up-billing-seg{
  position:relative;
  display:inline-flex; gap:2px; padding:3px;
  background:var(--pc-well); border:1px solid var(--pc-hairline); border-radius:99px;
  --up-seg-dur:.26s;
  --up-seg-ease:cubic-bezier(.4,0,.2,1);
}
.pricing-cards .up-billing-thumb{
  position:absolute; top:3px; left:0;
  /* Falls back to 100% of the container before JS has measured once (see
     the .is-ready note below) — correct at that moment because the savings
     badge, .up-billing-seg's only other child, only ever wraps onto its own
     row via a later layout pass, never on first paint. */
  height:var(--up-seg-h, calc(100% - 6px)); width:var(--up-seg-w, 0px);
  transform:translateX(var(--up-seg-x, 0px));
  /* The selected period is a solid brand fill, not a raised white pill. The
     pill relied on --paper lifting off --well plus a drop shadow, and in dark
     those are #151515 on #171717 with shadows that read as nothing, so the
     control looked like two plain labels and you could not tell which period
     you were buying. --brand/--on-brand is the contrast-checked pair for a
     solid fill and is restated per theme, so this reads the same in both. */
  background:var(--pc-brand);
  border-radius:99px; pointer-events:none;
  transition:transform var(--up-seg-dur) var(--up-seg-ease),
             width var(--up-seg-dur) var(--up-seg-ease);
}
/* Until JS has measured once, the thumb has no width and sits at x=0.
   Animating out of that state would show it growing from the left edge on
   every page load, so the transition is only armed after the first measure. */
.pricing-cards .up-billing-seg:not(.is-ready) .up-billing-thumb{ transition:none; }
.pricing-cards .up-billing-seg button{
  position:relative; z-index:1;
  border:none; background:none; cursor:pointer;
  padding:7px var(--pc-space-6); border-radius:99px;
  font-family:inherit;
  font-size:var(--pc-fs-sm); font-weight:600; color:var(--pc-ink-soft);
  transition:color var(--up-seg-dur) var(--up-seg-ease);
}
.pricing-cards .up-billing-seg button:hover:not(.active){ color:var(--pc-ink); }
.pricing-cards .up-billing-seg button:focus-visible{ outline:2px solid var(--pc-accent); outline-offset:2px; }
.pricing-cards .up-billing-seg button.active{ color:var(--pc-on-brand); }
@media (prefers-reduced-motion: reduce){
  .pricing-cards .up-billing-thumb{ transition:none; }
  .pricing-cards .up-billing-seg button{ transition:none; }
}
/* Anchored to the segmented control's own right edge, not centered beside it
   in the same flex row — .up-billing centers on .up-billing-seg alone, so a
   badge sharing that row shifts the whole group's centre of mass and visibly
   offsets the toggle itself off-centre from the heading above it. Popping the
   badge out of flow (the corner-badge treatment Linear/Vercel-style pricing
   toggles use for exactly this) keeps the toggle's own centre true regardless
   of the badge's width. Money-saved gets the success colour so it never
   competes with the accent-blue selection state of the toggle it hangs off. */
.pricing-cards .up-billing-save-badge{
  position:absolute; left:100%; top:50%;
  transform:translateY(-50%);
  margin-left:10px;
  display:inline-flex; align-items:center;
  padding:5px 10px;
  border-radius:99px;
  font-size:var(--pc-fs-2xs); font-weight:700;
  white-space:nowrap;
  background:var(--pc-success-wash); color:var(--pc-success-ink);
}
/* Off to the side there's no room for it past ~480px of card width, so it
   re-anchors below the toggle instead of spilling off-screen — but it stays
   `position:absolute` in both layouts rather than falling into normal flow.
   An in-flow badge would sit INSIDE .up-billing-seg's own box, stretching
   that element's pill-shaped background/border to wrap around both the
   toggle row and the badge as one misshapen shared card. Staying absolute
   keeps the badge purely a floating label the toggle's own box never knows
   about, at every width. */
@media (max-width: 480px){
  .pricing-cards .up-billing-save-badge{
    left:50%; top:100%;
    transform:translateX(-50%);
    margin-left:0; margin-top:8px;
  }
  /* The badge is absolute, so it contributes nothing to .up-billing's own
     box height — without reserved space below, its ~40px footprint would
     sit on top of (or collapse into) .price-grid's own top margin instead
     of clearing it. */
  .pricing-cards .up-billing{ margin-bottom:44px; }
}
/* ===== The grid and the two cards ========================================= */
.pricing-cards .price-grid{
  display:grid; grid-template-columns:1fr 1.1fr; gap:var(--pc-space-7);
  max-width:900px; align-items:start;
  /* Extra clearance vs. the billing toggle above: the "Recommended" badge
     hangs off the Pro card's top edge (half its own height), which eats most
     of a normal top margin and left the two crowding each other. */
  margin:var(--pc-space-10) auto 0;
}
.pricing-cards .price-card{
  background:var(--pc-paper);
  border:1px solid var(--pc-hairline);
  border-radius:var(--pc-radius-lg);
  padding:var(--pc-space-9) var(--pc-space-9);
  display:flex; flex-direction:column;
  box-shadow:var(--pc-shadow-sm);
}
/* Wraps the featured card so the "Recommended" badge can sit above the card's
   own overflow:hidden (needed to crop the ::before glow below) and hang off
   its top-right corner instead of being clipped by it. */
.pricing-cards .price-card-wrap{
  position:relative;
  /* Pro is first in the DOM (so it stacks on top on mobile); on the desktop
     two-column grid, push it back to the right column. */
  order:2;
}
@media (max-width: 720px){
  .pricing-cards .price-card-wrap{ order:0; }
}
.pricing-cards .price-card.featured{
  position:relative; overflow:hidden;
  border-color:var(--pc-accent);
  box-shadow:var(--pc-shadow-md);
  background:linear-gradient(165deg, var(--pc-accent-wash), var(--pc-paper) 62%);
}
/* Soft accent glow, same idea as the landing card's ::before bloom. */
.pricing-cards .price-card.featured::before{
  content:""; position:absolute; top:-42%; right:-24%;
  width:70%; padding:38% 0; border-radius:50%;
  filter:blur(60px); opacity:.30; pointer-events:none;
  background:radial-gradient(circle, var(--pc-accent) 0%, transparent 65%);
}
.pricing-cards .price-card.featured > *{ position:relative; }

/* Hangs off the featured card's top-right corner, half in/half out —
   positioned against .price-card-wrap (not the card, which clips its own
   glow) so nothing crops it. */
.pricing-cards .plan-badge{
  position:absolute; top:0; right:var(--pc-space-7); z-index:2;
  transform:translateY(-50%);
  font-size:var(--pc-fs-3xs); letter-spacing:.1em; text-transform:uppercase;
  background:var(--pc-brand);
  color:var(--pc-on-brand); padding:6px var(--pc-space-4); border-radius:99px;
  box-shadow:var(--pc-shadow-sm);
}
.pricing-cards .plan-name{
  /* Display font, matching .plan-price below it in the same card — the two are
     the numbers that matter on this card, so they share one register instead
     of the name reading as a smaller, plainer label above it. */
  font-family:var(--pc-font-display);
  font-size:var(--pc-fs-plan-name); font-weight:600; letter-spacing:-.01em; color:var(--pc-ink);
}
/* Pro's own title: the same confetti mark every other Pro CTA in the app uses
   (core/img/dark-icon-gold.svg, gold gradient baked into the file) sitting beside
   the word itself, which carries that same gold rather than the card's plain
   --ink. Falls back to --gold-ink first so an engine without
   background-clip:text still renders a legible (if flat) gold word instead of
   invisible text. The icon is sized off the title's own font-size (1em), so
   both grow together rather than needing a second number kept in sync. */
.pricing-cards .plan-name-pro{ display:flex; align-items:center; gap:.28em; }
.pricing-cards .plan-name-pro img{ display:block; width:auto; height:.92em; flex-shrink:0; }
.pricing-cards .plan-name-pro-word{ color:var(--pc-gold-ink); }
@supports ((background-clip: text) or (-webkit-background-clip: text)){
  .pricing-cards .plan-name-pro-word{
    background:linear-gradient(135deg, #F7CB60 0%, #E8AC2C 38%, #CE8B12 72%, #A2680B 100%);
    -webkit-background-clip:text; background-clip:text;
    color:transparent;
  }
}
.pricing-cards .plan-for{ font-size:var(--pc-fs-feature); color:var(--pc-ink); margin:5px 0 var(--pc-space-7); }
.pricing-cards .plan-price{
  font-family:var(--pc-font-display);
  font-size:var(--pc-fs-price); font-weight:600; letter-spacing:-.03em; line-height:1; color:var(--pc-ink);
  /* CTA sits directly below the price now (not the feature list), so the price
     carries its own gap down to it instead of relying on .plan-list's margin. */
  margin-bottom:var(--pc-space-7);
}
.pricing-cards .plan-price small{
  font-size:var(--pc-fs-sm); font-weight:500; color:var(--pc-ink-soft); letter-spacing:0;
}

/* ===== Feature list ======================================================= */
.pricing-cards .plan-list{
  /* No bottom margin: flex:1 already grows this to fill the card down to
     whatever follows (fine print, or the card's own bottom padding when
     there's none), and a fixed margin here would just stack on top of that. */
  margin:var(--pc-space-8) 0 0;
  display:flex; flex-direction:column; gap:var(--pc-space-3); flex:1;
}
/* Not `.pl` — that class is the skeleton-loader block in ui_concept.css
   (gray --well bg + shimmer), which would bleed onto every feature row. */
.pricing-cards .up-feat{
  display:flex; gap:var(--pc-space-3); align-items:flex-start;
  font-size:var(--pc-fs-feature); color:var(--pc-ink);
}
.pricing-cards .up-feat .tick{
  width:19px; height:19px; border-radius:50%;
  /* --accent-ink, not --accent: the kit's rule is that anything read AS ink
     takes the -ink token, which dark lifts to #8FB6EF so the check stays
     legible on the --accent-wash disc instead of sinking into it. */
  background:var(--pc-accent-wash); color:var(--pc-accent-ink);
  display:flex; align-items:center; justify-content:center;
  flex-shrink:0; margin-top:2px;
}
.pricing-cards .featured .up-feat .tick{ background:var(--pc-brand); color:var(--pc-on-brand); }
.pricing-cards .up-feat .tick svg{ width:11px; height:11px; }

/* Category labels + per-feature descriptions inside .plan-list. */
.pricing-cards .up-feat-group{
  font-size:var(--pc-fs-group); font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--pc-ink-soft); opacity:.75; margin:var(--pc-space-2) 0 0;
}
.pricing-cards .up-feat-group:first-child{ margin-top:0; }
.pricing-cards .up-feat-body{ display:flex; flex-direction:column; gap:2px; min-width:0; }

/* The headline Pro feature, lit. Gradient text with a slow shine so the one
   line that matters most is the one the eye lands on first.

   Built defensively in three ways:

   1. `color` is set to a real token FIRST and only replaced with transparent
      inside @supports. Without that, any engine missing background-clip:text
      renders the most important line in the table as invisible text.
   2. The bright peak is bracketed by deep shoulders (--hero-dip) so the glint
      reads against the base gold in both themes. The peak itself is allowed
      above text-contrast thresholds because it is a moving band a few
      characters wide, never the resting colour; the resting colour is always
      --gold-ink.
   3. The animation is motion, so it stops under prefers-reduced-motion and
      leaves the static gradient behind. */
.pricing-cards .up-feat.is-hero .up-feat-title{
  color:var(--pc-gold-ink);
  font-weight:600;
}
/* Both sweep tokens live on the row: the title and the tick share them, and
   declaring them here (light) means the dark rule below only overrides. */
.pricing-cards .up-feat.is-hero{ --hero-peak:#EDB93B; --hero-dip:#5C3D05; --hero-tick-ink:#FFF6E3; }
[data-theme="dark"] .pricing-cards .up-feat.is-hero{ --hero-peak:#FFFBEC; --hero-dip:#A87614; --hero-tick-ink:#3B2A06; }
/* The tick matches the line it belongs to. Left blue it read as a stray piece
   of the old palette sitting against gold text. Its glyph ink flips per theme
   because the disc does: dark's gold disc is light and needs a dark check,
   light's bronze disc is dark and needs a cream one.
   The tick does NOT animate: two side-by-side sweeps read as two separate
   effects, so only the text carries the shine and the disc holds a static
   peak→base gold gradient that ties it to the same palette. */
.pricing-cards .up-feat.is-hero .tick{
  background:linear-gradient(135deg, var(--hero-peak), var(--pc-gold-ink));
  color:var(--hero-tick-ink);
}
@supports ((background-clip: text) or (-webkit-background-clip: text)){
  .pricing-cards .up-feat.is-hero .up-feat-title{
    background:linear-gradient(100deg,
      var(--pc-gold-ink) 0%, var(--pc-gold-ink) 34%,
      var(--hero-dip) 43%,
      var(--hero-peak) 50%,
      var(--hero-dip) 57%,
      var(--pc-gold-ink) 66%, var(--pc-gold-ink) 100%);
    background-size:300% 100%;
    -webkit-background-clip:text; background-clip:text;
    color:transparent;
    animation:pc-hero-shine 5.5s linear infinite;
  }
}
@keyframes pc-hero-shine{
  from{ background-position:150% 0; }
  to  { background-position:-150% 0; }
}
@media (prefers-reduced-motion: reduce){
  .pricing-cards .up-feat.is-hero .up-feat-title{ animation:none; }
}

/* Per-feature explanations, revealed on demand.

   Deliberately a disclosure, not a floating tooltip. .price-card.featured sets
   overflow:hidden to clip its own ::before glow, so a popover anchored inside
   it would be cut off; escaping that would mean position:fixed plus
   scroll/resize tracking. Expanding in flow costs none of that, and it is the
   only form that works identically under a mouse, a finger and a keyboard.
   Click rather than hover for the same reason: on hover the row would grow
   under the pointer and shove the rest of the list down.

   Normal inline flow, NOT a flex row: the button has to travel with the last
   word of the title. As a flex item it wrapped onto a line of its own as soon
   as the title needed two lines, which at 390px left the question mark
   stranded under "Autopilot: proposal -> contract -> invoice -> paid". */
.pricing-cards .up-feat-head{ display:block; }
.pricing-cards .up-feat-info{
  display:inline-flex; align-items:center; justify-content:center;
  width:19px; height:19px; padding:0;
  /* vertical-align:middle centres the button on the baseline plus half the
     X-HEIGHT. These titles are mixed case, so the eye centres them on the CAP
     height instead, and middle alone leaves the button sitting 1.75px low
     (measured). The margin-box centre is what vertical-align aligns, so bottom
     margin lifts the border box by half of it: one (cap - x) of margin is
     exactly the half-gap between the two centres.
     font-size:inherit is load-bearing, not tidiness. A <button> does not
     inherit font by default, so without it 1cap/1ex would resolve against the
     browser's default button font rather than the title's 15px. */
  font-size:inherit; font-family:inherit;
  margin-left:5px; vertical-align:middle;
  margin-bottom:calc(1cap - 1ex);
  border:none; background:none; cursor:pointer;
  color:var(--pc-ink-soft); border-radius:50%;
  transition:color .12s ease, background .12s ease;
}
.pricing-cards .up-feat-info svg{ width:14px; height:14px; }
.pricing-cards .up-feat-info:hover{ color:var(--pc-accent-ink); background:var(--pc-accent-wash); }
.pricing-cards .up-feat-info:focus-visible{ outline:2px solid var(--pc-accent); outline-offset:2px; }
.pricing-cards .up-feat.is-open .up-feat-info{ color:var(--pc-accent-ink); background:var(--pc-accent-wash); }
/* 0fr -> 1fr animates the row's real height with no JS measurement and no
   max-height guess that would clamp a long description or ease against dead
   space. The inner element carries the overflow clip the trick requires. */
.pricing-cards .up-feat-tip{
  display:grid; grid-template-rows:0fr; visibility:hidden;
  transition:grid-template-rows .22s cubic-bezier(.4,0,.2,1), visibility .22s;
}
.pricing-cards .up-feat.is-open .up-feat-tip{ grid-template-rows:1fr; visibility:visible; }
.pricing-cards .up-feat-tip-in{
  overflow:hidden;
  font-size:var(--pc-fs-xs); color:var(--pc-ink-soft); line-height:1.45;
}
@media (prefers-reduced-motion: reduce){
  .pricing-cards .up-feat-tip{ transition:none; }
}

/* ===== Card CTAs ========================================================== */
.pricing-cards .plan-cta{
  display:flex; align-items:center; justify-content:center;
  width:100%; padding:var(--pc-space-4) var(--pc-space-6);
  border-radius:var(--pc-radius-ctl); font-size:15px; font-weight:600;
  font-family:inherit;
  /* Explicit: a <button> defaults to line-height:normal instead of inheriting,
     so without this the Pro CTA (a button, since it POSTs) sits 3px shorter
     than the sibling plan's anchor. */
  line-height:1.5;
  text-decoration:none; cursor:pointer;
  border:1px solid var(--pc-hairline); background:var(--pc-paper); color:var(--pc-ink);
  transition:background .12s ease, border-color .12s ease, color .12s ease, transform .12s ease;
}
/* The Pro CTA POSTs, so it's a button in a form. Zero the form's own margin so
   it contributes nothing and the button still lands exactly where the anchor
   (the marketing/current-plan variants) does — .plan-price's margin-bottom is
   what actually spaces it from the price above. */
.pricing-cards .plan-cta-form{ margin:0; }
.pricing-cards .plan-cta:hover{ background:var(--pc-well); border-color:var(--pc-ink-soft); }
.pricing-cards .plan-cta.primary{
  border-color:var(--pc-brand); color:var(--pc-on-brand); background:var(--pc-brand);
}
.pricing-cards .plan-cta.primary:hover{ transform:translateY(-1px); background:var(--pc-brand-hover); border-color:var(--pc-brand-hover); }
.pricing-cards .plan-cta.current{ cursor:default; color:var(--pc-ink-soft); }
.pricing-cards .plan-cta.current:hover{ background:var(--pc-paper); border-color:var(--pc-hairline); transform:none; }
/* Launch's marketing CTA: a light wash, not the solid brand fill — that stays
   reserved for Pro's `.primary` so Launch reads as inviting without competing
   with the "Recommended" card for attention. */
.pricing-cards .plan-cta.plan-cta-glow{
  background:linear-gradient(135deg, var(--pc-paper) 0%, var(--pc-accent-wash) 130%);
  border-color:var(--pc-accent-wash); color:var(--pc-accent-ink);
}
.pricing-cards .plan-cta.plan-cta-glow:hover{
  background:linear-gradient(135deg, var(--pc-accent-wash) 0%, var(--pc-paper) 130%);
  border-color:var(--pc-accent); transform:translateY(-1px);
}

/* Sits directly under the CTA, qualifying the button it follows. The margin is
   its own now: it used to follow `.plan-list`, whose flex:1 grew to carry the
   gap, so --pc-space-6 there was only a top-up on a much larger space. Against
   the button that full value reads as a detached line, hence the tighter step.
   The longer `.plan-cta-note` is still the card's footer. */
.pricing-cards .plan-cta-nocard{
  display:flex; align-items:center; justify-content:center; gap:6px;
  margin:var(--pc-space-3) 0 0;
  font-size:var(--pc-fs-sm); font-weight:700; color:var(--pc-accent-ink);
}
.pricing-cards .plan-cta-nocard svg{ flex-shrink:0; }
.pricing-cards .plan-cta-note{
  /* space-2 was a tight pairing with the nocard line that used to sit directly
     above it. That line is up by the button now, so this follows `.plan-list`
     and takes the step that slot wants. */
  margin:var(--pc-space-6) 0 0;
  font-size:var(--pc-fs-2xs); line-height:1.5; color:var(--pc-ink-soft);
  text-align:center;
  /* Balance the two lines rather than clamping the width. At full card width
     this broke as a long line plus a stranded "made."; a max-width tight
     enough to fix that pushed it to three lines instead. text-wrap:balance
     evens them with no magic number, and degrades to normal wrapping where it
     is unsupported. */
  text-wrap:balance;
}
/* Compound selector on purpose. This element carries BOTH classes, and
   `.plan-cta-form{ margin:0 }` is declared further up the sheet at the same
   specificity, so a lone `.plan-cta-form-secondary` rule lost the cascade and
   the gap silently collapsed to 0. */
.pricing-cards .plan-cta-form.plan-cta-form-secondary{ margin-top:var(--pc-space-6); }
/* Inside .featured the card background is an accent gradient, so the secondary
   CTA's default --paper fill would read as a second primary button. Drop it to
   a ghost. */
.pricing-cards .featured .plan-cta-form-secondary .plan-cta{
  background:transparent; border-color:var(--pc-hairline); color:var(--pc-ink-soft);
}
.pricing-cards .featured .plan-cta-form-secondary .plan-cta:hover{
  background:var(--pc-paper); color:var(--pc-ink); border-color:var(--pc-ink-soft);
}

@media (max-width: 720px){
  .pricing-cards .price-grid{ grid-template-columns:1fr; }
  .pricing-cards .price-card{ padding:var(--pc-space-8) var(--pc-space-7); }
}

/* ===========================================================================
   Dark Pro card — every variant (.pc-dark-pro, always set by the partial), so
   the Upgrade page and the landing page show the same design.

   On a light ground the inversion reads as "this is the paid tier" without
   spending a word on it. In the dashboard's dark theme a dark card would sit
   on a dark page and lose that distinction, so the [data-theme="dark"] rule at
   the end of this block gives it back its accent border there.

   Implemented by re-pointing the --pc-* aliases on .price-card-wrap rather
   than by overriding rules one at a time: every descendant rule already reads
   these, so the whole card flips with no duplicated selectors and nothing left
   behind when a rule above changes. Values are ui_concept.css's own dark-theme
   literals, so this tracks the app's dark palette rather than inventing one.
   =========================================================================== */
.pc-dark-pro .price-card-wrap{
  --pc-ink:#E6E9F0;
  --pc-ink-soft:#9AA4B5;
  --pc-paper:#151515;            /* app --paper, dark */
  --pc-well:#171717;             /* app --well, dark */
  --pc-hairline:rgba(255,255,255,.09);
  --pc-accent:#6B9FE8;           /* app --accent, dark */
  --pc-accent-wash:#182131;      /* app --accent-wash, dark */
  --pc-accent-ink:#8FB6EF;       /* app --accent-ink, dark */
  --pc-brand:#2F6BC9;            /* app --brand, dark */
  --pc-brand-hover:#3B74CC;
  --pc-on-brand:#FFFFFF;
  --pc-gold-ink:#EAC06B;         /* app --gold-ink, dark */
}

/* The gold sweep's dark values are otherwise keyed to [data-theme="dark"],
   which the landing page never sets — without this the card would run the
   light-ground golds (a dark #5C3D05 shoulder) against a dark card and the
   shine would read as a smudge rather than a glint. */
.pc-dark-pro .up-feat.is-hero{ --hero-peak:#FFFBEC; --hero-dip:#A87614; --hero-tick-ink:#3B2A06; }

/* The card carries its own border now: on a light page the dark fill already
   separates it, so the accent border would double up as a ring. */
.pc-dark-pro .price-card.featured{
  border-color:#26303F;
  /* Same resting depth as the Launch card beside it: the dark fill already
     marks Pro as the paid tier, so the deeper lift was saying it twice. The
     wrap no longer re-points --pc-shadow-sm, so this resolves to Launch's value. */
  box-shadow:var(--pc-shadow-sm);
}
/* Dashboard dark theme: the dark fill no longer separates Pro from the page,
   so the accent border carries that job instead. */
[data-theme="dark"] .pc-dark-pro .price-card.featured{ border-color:#6B9FE8; }
