/* Hallmark · component: comparison table + scope chip + allowance meter
 * genre: editorial · theme: Bloom (tokens.css) — rethemed in BLOOM_REVAMP_SPEC
 * §6 (slice S6). The token FALLBACK CHAIN is why this file needed so little:
 * every value already read the Bloom token names first, so the palette arrived
 * with tokens.css. What changed here is SHAPE — the comparison becomes a panel
 * instead of a bare ruled grid, and the radii join the system.
 *
 * (An earlier draft of this paragraph wrote the two token prefixes as a glob
 * pair. The slash-star sequence in it CLOSED THIS COMMENT four lines early,
 * which fed the rest of the header to the parser as declarations and took the
 * .plan-table token block down with it: every --pt-* resolved to empty, so the
 * scope chips lost their fill and the panel lost its ground. Never write a
 * star-slash inside a CSS comment.)
 * states: default · hover · focus · low · zero · failed
 * contrast: pass
 *
 * REDESIGNED at the owner's visual gate, 2026-08-11 ("hard to read and badly
 * spaced"). Component scope: no macrostructure, no nav/footer, no enrichment -
 * the tokens are the app's own and nothing new was invented.
 *
 * The diagnosis was structural, not decorative: the grid was doing two
 * unrelated jobs, comparing two plans AND reporting where this reader stands,
 * and the second can only ever fill the reader's own column. Measured at 390px
 * before / after:
 *
 *     row heights   83.5-148.2px (spread 64.7)  ->  86.4-133.7px (spread 47.3)
 *     scope chips   6                           ->  0 (one rule per column)
 *     weight >=700  23 elements                 ->  0 (values carry 600)
 *     grid height   815.9px                     ->  675.7px
 *
 * The residual spread is one long sentence in the packs row rather than a
 * structural asymmetry, which is a different kind of problem and a smaller one.
 *
 * Hallmark · pre-emit critique: P4 H5 E4 S5 R5 V4
 * Responsive floor verified at 320 / 375 / 390 / 414 / 768 / 1200: no
 * horizontal scroll, no grid overflow, no clipped text.
 *
 * FREE_VS_PAID_COMMS_PLAN.md §3. Loaded by three pages that do not share a
 * stylesheet: the SPA shell, the revamped landing template, and the flag-0
 * static landing. Every token is read with a fallback chain so one file works
 * in all three - the revamped token names first, the legacy style.css names
 * second, a literal last. Nothing here introduces a new visual language; it
 * borrows the app's own rules, ink and accent.
 */

.plan-table {
  --pt-ink: var(--color-ink, var(--ink, #221f24));
  --pt-ink-2: var(--color-ink-2, var(--ink, #3a3640));
  --pt-muted: var(--color-muted, var(--muted, #6a6470));
  --pt-rule: var(--color-rule, var(--rule, #d9d4cd));
  --pt-paper-2: var(--color-paper-2, #f8f6f3);
  --pt-accent: var(--color-accent, var(--accent, #c8342b));
  --pt-accent-deep: var(--color-accent-deep, var(--accent-deep, #9c2822));
  /* Mixed against the PANEL, not the page. The comparison sits on paper-2 now
     (see .plan-grid), and a fill mixed into the page's own paper landed within
     a percent of the surface behind it - the "every month" chip effectively
     lost its fill the moment the table gained a surface. */
  --pt-accent-bg: color-mix(in oklch, var(--pt-accent) 18%, var(--pt-paper-2));
  color: var(--pt-ink);
}

/* The standing block. One paragraph, above the table, on all three mounts. */
.plan-standing {
  color: var(--pt-muted);
  font-size: var(--text-base, 1rem);
  line-height: 1.62;
  max-width: 52ch;
  margin: 0 0 var(--sp-5, 1.5rem);
}

/* Three columns: what it is, free, Stylist. Not a <table>: the mobile shape is
   a stack of per-row cards, and role="table" on a grid keeps the semantics
   without fighting the layout. */
/* The comparison sits ON a surface now. It used to be an unbounded ruled grid
   floating on the page, which under Bloom's washes read as loose rows rather
   than as one table you are meant to compare across. */
.plan-grid {
  display: grid;
  overflow-x: auto;
  border: 1px solid var(--color-rule-soft, var(--pt-rule));
  border-radius: var(--r-panel, 22px);
  background: var(--pt-paper-2);
  padding: 0 var(--sp-5, 1.5rem);
  box-shadow: var(--shadow-panel, none);
}
.plan-row {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-3, .75rem);
  align-items: start;
  padding: var(--sp-4, 1rem) 0;
  border-bottom: 1px solid var(--color-rule-soft, var(--pt-rule));
}
/* The last row closes on the panel's own edge rather than drawing a second
   line just inside it. */
.plan-row:last-child { border-bottom: 0; }
/* ---- HIERARCHY: ONE BOLD THING PER ROW ----
   Owner visual gate, 2026-08-11: "everything is bold, so nothing leads."
   Measured at 390px before this: 23 elements inside the grid at weight >= 700 -
   the head row, every row name and every value, all shouting at once, which is
   the same as none of them shouting.
   The value is the answer the reader came for, so the value is the only thing
   that carries weight. The row name is what they scan down, so it stays plain
   ink at reading weight. The column head names the plan once and then gets out
   of the way. */
.plan-head {
  padding-top: var(--space-xs, .5rem);
  padding-bottom: var(--space-xs, .5rem);
  font-family: var(--font-body, inherit);
  font-size: var(--text-sm, .86rem);
  letter-spacing: .01em;
  align-items: baseline;
}
.plan-colname {
  display: block;
  font-weight: 600;
  color: var(--pt-ink);
}
/* The refill rule, stated ONCE per column instead of on every row. Lower case
   and quiet on purpose - it is a footnote to the column, not a badge. */
.plan-colrule {
  display: block;
  font-weight: 400;
  font-size: var(--text-xs, .74rem);
  color: var(--pt-muted);
  letter-spacing: 0;
  margin-top: .1rem;
}
.plan-rowname {
  font-weight: 400;
  font-size: var(--text-sm, .86rem);
  color: var(--pt-ink-2);
}
.plan-rowsub {
  display: block;
  color: var(--pt-muted);
  font-size: var(--text-xs, .74rem);
  line-height: 1.4;
  margin-top: .1rem;
}

/* ---- "WHERE YOU ARE NOW" ----
   The reader's own standing, lifted out of the comparison grid (see
   standingNowHTML for why). Four short lines, each a label and its meter, in
   the reader's reading order rather than squeezed into one column of a table
   about plans. It sits ABOVE the comparison because it is the question a
   logged-in member came to the page with; the comparison is the follow-up. */
.plan-now {
  margin: 0 0 var(--sp-5, 1.5rem);
  padding: var(--sp-4, 1rem) var(--sp-5, 1.5rem);
  border: 1px solid var(--color-rule-soft, var(--pt-rule));
  border-radius: var(--r-panel, 22px);
  background: var(--pt-paper-2);
}
.plan-now-h {
  margin: 0 0 var(--sp-3, .75rem);
  font-family: var(--font-body, inherit);
  font-size: var(--text-xs, .74rem);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--pt-muted);
}
.plan-now-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sp-3, .75rem); }
.plan-now-item { display: block; }
/* Inside this block the meter is the whole point, so it needs none of the
   flex-basis gymnastics it used when it was a third element inside a cell. */
.plan-now .plan-meter { margin-top: 0; }
.plan-now .plan-meter-txt { color: var(--pt-ink); font-weight: 500; }
.plan-colcell { min-width: 0; }
.plan-cell {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .35rem;
  min-width: 0;
}
.plan-value {
  font-weight: 600;
  font-size: var(--text-sm, .86rem);
  overflow-wrap: anywhere;
}
/* A row whose two columns say the same thing spans them both. The note is the
   part that stops it reading as a value with a missing neighbour. */
.plan-row-both { grid-template-columns: minmax(0, 1.3fr) minmax(0, 2fr); }
.plan-colcell-both {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .4rem;
}
.plan-both-note {
  font-size: var(--text-xs, .74rem);
  color: var(--pt-muted);
}

/* ---- THE SCOPE CHIP ----
   Three tokens, and they differ in KIND, not in colour alone: outlined versus
   filled. Print the page in greyscale, or read it with any colour vision, and
   "once, ever" is still visibly a different kind of thing from "every month".
   Neither is a warning - no amber, no red, nothing that makes the free plan
   look broken. */
.plan-scope {
  display: inline-block;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  line-height: 1.5;
  padding: .1rem var(--sp-2, .5rem);
  border-radius: var(--r-pill, 999px);
  white-space: nowrap;
}
/* The two chips must not read as equals: the outline is the quiet one and
   keeps a bare edge, so the filled "every month" stays the chip that catches
   the eye. Tinting the outline as well (tried, and measured on the panel)
   flattened the pair into two grey badges. */
.plan-scope-outline {
  border: 1px solid var(--color-rule, var(--pt-rule));
  color: var(--pt-muted);
  background: transparent;
}
.plan-scope-fill {
  border: 1px solid transparent;
  color: var(--pt-accent-deep);
  background: var(--pt-accent-bg);
}

/* ---- THE READER'S OWN METER ----
   Only ever in the reader's own column. Words plus a 3px bar filling with what
   is LEFT - not a percentage, not a ring, not an icon. */
.plan-meter {
  display: block;
  flex: 1 0 100%;
  margin-top: .3rem;
}
.plan-meter-txt {
  display: block;
  font-size: var(--text-xs, .74rem);
  font-weight: 500;
  color: var(--pt-muted);
}
.plan-meter-bar {
  display: block;
  height: 3px;
  margin-top: .25rem;
  border-radius: 2px;
  background: var(--pt-rule);
  overflow: hidden;
}
.plan-meter-bar > i {
  display: block;
  height: 100%;
  background: var(--pt-ink-2);
  transition: width var(--dur-short, 220ms) var(--ease-out, ease-out);
}
.plan-meter.is-low .plan-meter-bar > i { background: var(--pt-accent); }
.plan-meter-pack {
  display: block;
  font-size: var(--text-xs, .74rem);
  color: var(--pt-muted);
  margin-top: .15rem;
}

.plan-resets,
.plan-failed {
  font-size: var(--text-sm, .86rem);
  color: var(--pt-muted);
  margin: var(--space-sm, .75rem) 0 0;
}
.plan-notes {
  list-style: none;
  margin: var(--space-sm, .75rem) 0 0;
  padding: 0;
  display: grid;
  gap: .2rem;
}
.plan-notes li {
  font-size: var(--text-xs, .74rem);
  color: var(--pt-muted);
  line-height: 1.5;
}

/* ---- Mobile: per-row cards, label then two values at 50/50 ----
   No accordion and no Free/Stylist tabs. Tabs would hide the comparison, which
   is the one thing this component exists to show. */
/* The per-cell plan name (see cellHTML). Off by default: above the mobile
   breakpoint the header row is in view and a second label per cell would be the
   same word printed twelve times. */
.plan-cellplan { display: none; }

@media (max-width: 560px) {
  .plan-cellplan {
    display: block;
    flex: 1 0 100%;
    font-size: var(--text-xs, .74rem);
    font-weight: 400;
    color: var(--pt-muted);
    line-height: 1.3;
  }
  .plan-row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    row-gap: .3rem;
  }
  .plan-rowlabel { grid-column: 1 / -1; }
  .plan-head .plan-rowlabel { display: none; }
  .plan-head { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  /* A both-plans row has one cell, so it takes the whole width rather than
     leaving half the row empty. */
  .plan-row-both { grid-template-columns: minmax(0, 1fr); }
  .plan-row-both .plan-colcell-both { grid-column: 1 / -1; }
  .plan-now { padding: var(--sp-4, 1rem); }
}

/* A screen-reader-only label for the empty top-left header cell. */
.plan-table .vh {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* ---- The #plan page ---- */
.plan-page { max-width: 52rem; margin: 0 auto; }
.plan-page-price {
  font-size: var(--text-md, 1.15rem);
  font-weight: 700;
  margin: 0 0 var(--space-2xs, .25rem);
}
.plan-page-acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs, .5rem);
  margin-top: var(--space-lg, 1.5rem);
}
.plan-page-note {
  font-size: var(--text-sm, .86rem);
  color: var(--pt-muted, #6a6470);
  margin-top: var(--space-sm, .75rem);
}

/* ---- The Add tab's allowance strip ----
   Owner visual gate, 2026-08-08: the two facts used to be outlined pills
   floating between the headroom line and the Own/Want control, and they read as
   bolted on. This is the same information wearing the page's own status
   language instead - the 3px companion rule .cap-indicator carries on the
   Closet tab, small muted type, sitting hard against the form it describes. It
   rhymes deliberately with the privacy line under the capture button: one quiet
   marked line above the control, one below.

   Each fact is still its own button to #plan (§2, "Tapping either"). The
   underline is the affordance - a box here would put a third bordered shape
   between the teaching card and the Own/Want control, which is how the pills
   came to look like debris in the first place. */
.allow-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  margin: var(--space-2xs, .25rem) 0 0;
  padding: .1rem 0 .1rem var(--space-xs, .5rem);
  border-left: 3px solid var(--color-companion, #a8c7d2);
  font-size: var(--text-sm, .86rem);
  line-height: 1.5;
  color: var(--color-muted, var(--muted, #6a6470));
}
.allow-fact {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  margin: 0;
  padding: .15rem 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--color-rule, var(--rule, #d9d4cd));
  text-decoration-thickness: 1px;
  text-underline-offset: .22em;
  transition: color var(--dur-micro, 120ms) var(--ease-out, ease-out);
}
.allow-fact:hover,
.allow-fact.is-hover {
  color: var(--color-ink-2, var(--ink, #3a3640));
  text-decoration-color: currentColor;
}
.allow-fact:focus-visible {
  outline: 2px solid var(--color-focus, #2f3a63);
  outline-offset: 3px;
  border-radius: 2px;
}
.allow-fact:active,
.allow-fact.is-active { transform: translateY(1px); }
/* The 90 % tint, inherited from the headroom line this strip replaced. The one
   colour §5 rule 9 allows before zero, and it moves with the count it is about. */
.allow-fact.is-amber { color: var(--warn, #a35f16); font-weight: 600; }
.allow-strip-sep {
  width: 1px;
  height: .95em;
  margin: 0 .6rem;
  background: var(--color-rule, var(--rule, #d9d4cd));
}
/* On a phone the two facts stack rather than wrap around a divider that would
   be left dangling at the end of the first line. */
@media (max-width: 460px) {
  .allow-strip { flex-direction: column; align-items: flex-start; }
  .allow-strip-sep { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .allow-fact { transition: none; }
  .allow-fact:active, .allow-fact.is-active { transform: none; }
}

/* ---- The allowance chip (Looks header) ----
   Always visible, and the whole chip is the link to #plan. */
.allow-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs, .5rem);
  align-items: center;
}
.allow-chip {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .2rem .5rem;
  border: 1px solid var(--color-rule, var(--rule, #d9d4cd));
  border-radius: var(--radius-pill, 999px);
  background: transparent;
  color: var(--color-ink-2, var(--ink, #3a3640));
  font: inherit;
  font-size: var(--text-xs, .74rem);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-micro, 120ms) var(--ease-out, ease-out);
}
.allow-chip:hover,
.allow-chip.is-hover { background: var(--color-paper-2, #f8f6f3); }
.allow-chip:focus-visible {
  outline: 2px solid var(--color-focus, #2f3a63);
  outline-offset: 2px;
}
.allow-chip:active,
.allow-chip.is-active { transform: translateY(1px); }
.allow-chip[disabled] { opacity: .6; cursor: default; }

/* ---- The one at-zero panel ----
   Two buttons maximum, free remedy first, and the free one is never the ghost
   variant. */
.allow-zero {
  border: 1px solid var(--color-rule, var(--rule, #d9d4cd));
  border-radius: var(--radius-sm, .75rem);
  padding: var(--space-sm, .75rem) var(--space-md, 1rem);
  background: var(--color-paper-2, #f8f6f3);
}
.allow-zero-body {
  margin: 0;
  font-size: var(--text-sm, .86rem);
  line-height: 1.55;
  color: var(--color-ink-2, var(--ink, #3a3640));
  max-width: 52ch;
}
.allow-zero-acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs, .5rem);
  margin-top: var(--space-sm, .75rem);
}

/* ---- The first-login card (free members, once, in #add-cap) ---- */
.plan-first-card {
  border: 1px solid var(--color-rule, var(--rule, #d9d4cd));
  border-radius: var(--radius-sm, .75rem);
  padding: var(--space-md, 1rem);
  background: var(--color-paper-2, #f8f6f3);
  position: relative;
}
.plan-first-h {
  margin: 0 0 var(--space-2xs, .25rem);
  font-size: var(--text-md, 1.15rem);
  font-weight: 700;
}
.plan-first-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: .25rem;
}
.plan-first-list li {
  font-size: var(--text-sm, .86rem);
  line-height: 1.5;
  color: var(--color-ink-2, var(--ink, #3a3640));
}
.plan-first-close {
  margin: var(--space-sm, .75rem) 0 0;
  font-size: var(--text-sm, .86rem);
  color: var(--color-muted, var(--muted, #6a6470));
}
.plan-first-acts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md, 1rem);
  margin-top: var(--space-sm, .75rem);
}

/* The reader's own four allowances, one column, no comparison. Used on the
   Stylist welcome, where the plan they left is not information. */
.own-allow-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }
.own-allow-list li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .4rem;
  padding-bottom: .4rem;
  border-bottom: 1px solid var(--color-rule, var(--rule, #d9d4cd));
}
.own-allow-list li:last-child { border-bottom: 0; }
.own-allow-label { flex: 1 1 auto; font-size: var(--text-sm, .86rem); }
.own-allow-value { font-weight: 700; font-size: var(--text-sm, .86rem); }
.allow-chip-pack {
  font-size: var(--text-xs, .74rem);
  color: var(--color-muted, var(--muted, #6a6470));
}
.rv-acct-badge-line { font-weight: 700; margin: 0 0 var(--space-2xs, .25rem); }
.lv-share-reason {
  flex: 1 0 100%;
  font-size: var(--text-xs, .74rem);
  color: var(--color-muted, var(--muted, #6a6470));
  margin: .25rem 0 0;
}
