/* Successor Coach Development Plan — app styles.
 *
 * Tokens and base typography come from brand.css. Nothing here introduces a
 * color: the palette is green, ink, cool gray, and the three score flags.
 *
 * Desktop-primary by design — this is sit-down work — but every screen has to
 * hold up on a phone, because people will read the plan on one even if they
 * built it at a desk. The one place that changes behavior rather than layout is
 * the date popover, which becomes a bottom sheet under 560px.
 */

.plan-body {
  background: var(--paper-alt);
}

.app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}

.wrap--wide {
  max-width: 62rem;
}

.main {
  flex: 1;
  padding: 2rem 0 4rem;
}

.screen {
  animation: rise 0.18s ease-out;
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .screen {
    animation: none;
  }
}

.narrow {
  max-width: var(--measure);
}

.wide {
  max-width: 100%;
}

.lede {
  font-size: 1.0625rem;
  color: var(--ink-soft);
  max-width: var(--measure);
}


.eyebrow {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--green-dark);
  margin: 0 0 0.4rem;
}

.stack > * + * {
  margin-top: 1rem;
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: flex-end;
}

.row--two > * {
  flex: 1 1 14rem;
}

.btn--small {
  min-height: 40px;
  padding: 0.4rem 0.9rem;
  font-size: 0.9375rem;
}

.btn--danger {
  background: var(--flag-priority);
}

.btn--danger:hover:not(:disabled) {
  background: #a3332d;
}

.field__label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.field__help {
  display: block;
  font-size: 0.8125rem;
  color: var(--gray);
  margin-top: 0.3rem;
}

/* The "doesn't apply" state: the reason field and the way back out of it. */
.na-state {
  display: grid;
  gap: 0.75rem;
  justify-items: start;
}

.na-state .field {
  width: 100%;
  max-width: 32rem;
}

/* The "doesn't apply" offer: centered on its own row, a step below the
   input it stands in for, so it reads as an alternative to answering rather
   than as an eleventh button on the scale. */
.na-offer {
  margin-top: 1.25rem;
  text-align: center;
}

.pill {
  display: inline-block;
  font-family: var(--display);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.2rem 0.5rem;
  border-radius: 100px;
  background: var(--rule-soft);
  color: var(--ink-soft);
}

.pill--green {
  background: var(--green-tint);
  color: var(--green-dark);
}

.pill--quiet {
  background: var(--rule-soft);
  color: var(--gray);
}

.pill--sample {
  background: var(--flag-develop-tint);
  color: var(--flag-develop);
  max-width: 16rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Says what a sample plan is, once, where somebody starting from a link will
   see it before anything else. */
.sample-note {
  background: var(--flag-develop-tint);
  border: 1px solid #f0e0bd;
  border-radius: var(--radius-lg);
  padding: 0.9rem 1.15rem;
  margin-bottom: 1.5rem;
  max-width: 52rem;
}

.sample-note p {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.5;
}

/* ------------------------------------------------------------- chrome */

.chrome {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
}

/* The header is a WRAPPING row, and that is the whole defence against a phone.

   It used to be a single nowrap row — brandmark on the left, then the sample
   pill, the save indicator and both nav links pushed right by
   `justify-content: space-between`. Nothing in it could shrink and nothing
   could break, so at 375px the right-hand group ran to 543px and took the
   BODY with it: every plan screen scrolled sideways, not just the ones with a
   wide table. The sample pill made it worse but did not cause it — the two
   links and the save text overflow a narrow phone on their own.

   So the three groups wrap instead. The status group (pill + save) drops to a
   second line on a phone and the brandmark keeps the links company on the
   first, which is the split that keeps every control reachable at 320px.
   `npm run widths` measures it — no source-scanning test can, because both
   files were correct on their own and only the pairing overflowed. */
.chrome__inner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.35rem 0.75rem;
  min-height: 58px;
}

.chrome__home {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
  /* Shrinkable, and allowed to shrink below its longest line: the product name
     is four words and wraps rather than pushing the links off the screen. */
  flex: 0 1 auto;
  min-width: 0;
  background: none;
  border: 0;
  padding: 0.4rem 0;
  cursor: pointer;
  text-align: left;
}

.chrome__label {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9375rem;
}

.chrome__meta,
.chrome__save {
  font-size: 0.75rem;
  color: var(--gray);
}

.chrome__save.is-dirty {
  color: var(--flag-develop);
}

.chrome__save.is-error {
  color: var(--flag-priority);
}

/* Sample pill and save indicator.

   `flex: 1 1 0` is doing two jobs. It replaces the `space-between` this row
   used to have — the status group absorbs the slack, so the links still sit
   hard right on a wide header, empty save text or not. And a zero BASIS keeps
   the group off its own line at in-between widths: flex breaks lines on
   hypothetical sizes BEFORE it shrinks anything, so a group measured at its
   natural width pushed the two links onto a second row at around 800px even
   though the pill inside it would gladly have truncated to make room. */
.chrome__status {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex: 1 1 0;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
  min-width: 0;
}

/* `.pill--sample` already truncates at 16rem, which is narrower than the
   header on a desktop and WIDER than the whole of a 320px phone. This bounds
   it by what is actually there. */
.chrome__status .pill {
  max-width: 100%;
}

.chrome__right {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

/* Phone: the status group takes a line of its own beneath the brandmark and
   the links, which are what somebody actually presses. */
@media (max-width: 600px) {
  /* Same zero-basis trick as the status group, for the same reason: measured
     at its natural width the brandmark alone fills a 375px row and puts the
     links on a line of their own. Basis 0 lets it take what is left instead —
     two lines of product name beside the links, rather than a third row of
     sticky header. */
  .chrome__home {
    flex: 1 1 0;
    /* A floor, because basis 0 alone let the links squeeze this column to 43px
       at 320 — narrower than the word "Development" (95px at this size) — so
       the name overflowed its box and printed UNDER "The questions". Nothing
       scrolled, so `npm run widths` was green; only a screenshot showed it.
       8.5rem is the measured width of the name's two-line form ("Successor
       Coach" is 128px, "Development Plan" 131px), so the name sets in two
       lines rather than four and the sticky header loses ~60px on a phone. */
    min-width: 8.5rem;
  }

  /* The links give way instead: three of them are 225px, which no longer fits
     beside the brand floor at 320 or 375, so they wrap to a second line within
     their own group, still hard right. A group that cannot wrap cannot fail
     politely — the same shape as every overflow found in this header. */
  .chrome__right {
    /* Basis 0, like the brand — in a WRAPPING row an item is placed by its
       basis, so a natural-width group that does not fit beside the brand floor
       hops to a row of its own (a 133px header at 320, three rows deep) rather
       than shrinking. Grow 3 against the brand's 1 so the links are made whole
       first, capped at their one-line width so the leftover then goes back to
       the brand: at 414 the links sit on one line beside a two-line name, at
       600 the name is back on one line. At 320 and 375 the group is 132/187px
       and wraps to two rows, which is the failing-politely this needs. */
    flex: 3 1 0;
    max-width: max-content;
    flex-wrap: wrap;
    justify-content: flex-end;
    min-width: 0;
    row-gap: 0;
  }

  .chrome__status {
    order: 3;
    flex: 1 1 100%;
    justify-content: flex-start;
  }
}

.chrome__link {
  white-space: nowrap;
  background: none;
  border: 0;
  padding: 0.35rem 0;
  font-family: var(--display);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}

.chrome__link:hover {
  color: var(--green-dark);
}

.progress {
  height: 3px;
  background: var(--rule-soft);
}

.progress__bar {
  height: 100%;
  background: var(--green);
  transition: width 0.3s ease;
}

/* --------------------------------------------------------------- areas */

.areas {
  list-style: none;
  margin: 1.5rem 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
}

/* A COLUMN of full height, so the seven cards in the grid match.
   Two of them carry a blurb and five do not, and as content-height blocks in
   stretched grid cells that left every row ragged — the two tall cards sat
   beside short ones with a gap under them, which reads as a broken grid rather
   than as two cards with more to say. Full height plus the auto margin below
   puts every progress bar and status line on the same baseline across a row,
   which is what somebody scanning the hub is comparing. */
.area-card {
  width: 100%;
  display: flex;
  flex-direction: column;
  height: 100%;
  text-align: left;
  background: var(--paper);
  border: 1.5px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: 1rem 1.1rem;
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.area-card:hover {
  border-color: var(--green);
  box-shadow: var(--shadow);
}

.area-card.is-complete {
  background: var(--green-tint-2);
  border-color: var(--green-tint);
}

.area-card__top {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.6rem;
}

.area-card__name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.0625rem;
}

.area-card__score {
  margin-left: auto;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.125rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

.area-card__meta {
  display: block;
  font-size: 0.8125rem;
  color: var(--gray);
  margin-top: 0.5rem;
}

/* Tells Relationships and People apart, above the progress bar so it reads as
   part of the label rather than part of the status. --ink-soft, not --gray:
   this is the sentence that answers the reader's question, and --gray is
   2.96:1 on white, which fails WCAG AA for normal text. */
.area-card__blurb {
  display: block;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--ink-soft);
  margin-top: 0.3rem;
}

/* The bar and the status below it sit at the FOOT of the card, whether or not
   there is a blurb pushing them down. See .area-card. */
.area-card > .bar {
  margin-top: auto;
}

.bar {
  display: block;
  height: 5px;
  background: var(--rule-soft);
  border-radius: 3px;
  overflow: hidden;
}

.bar__fill {
  display: block;
  height: 100%;
  background: var(--green);
  border-radius: 3px;
}

.hub-links {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 1.5rem;
}

.cta-block {
  background: var(--paper);
  border: 1.5px solid var(--green);
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.4rem;
  margin: 1.5rem 0;
}

/* ------------------------------------------------------------ question */

.q {
  max-width: 44rem;
}

/* An items question is a TABLE, and 44rem is a reading measure.
   Every name and every "how we know them" note in a nine-row list was clipped
   mid-word — "Ridgeway Commercial Bu…", "Sutter & Vine Developme…" — at every
   viewport width, because the column was 186px whether the window was 764px or
   1440px wide. The demo made that obvious (the walkthrough spotlights exactly
   this question), but it clipped a real buyer's own answers just as hard.

   So the INPUT block alone leaves the measure and the prose stays inside it:
   without the second rule the 42-word question stem would set itself in one
   sixty-rem line. Below 721px the row is a stack of full-width fields already,
   which is the layout that never truncates, so this does not apply there. */
@media (min-width: 721px) {
  .q--wide {
    max-width: min(60rem, 100%);
  }

  .q--wide > *:not(.q__input) {
    max-width: 44rem;
  }
}

.q__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

/* The question strip: a map of the area, on its OWN row.
 *
 * Never inside .q__head — that is a non-wrapping space-between row, the header
 * shape that has taken the plan sideways at 375px before. This one wraps, which
 * it has to: fourteen 28px targets plus gaps do not fit 280px of usable width
 * inside .wrap on a 320px phone. */
.q__strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin: -0.75rem 0 1.25rem;
}

/* 28px minimum, because a pill is a tap target and a dot is not. */
.qpill {
  min-width: 28px;
  height: 28px;
  padding: 0 0.35rem;
  border: 1.5px solid var(--rule);
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink-soft);
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

/* Answered. The number is still the carrier — every pill also states its
 * status in its own aria-label and title, the same rule the calendar's five
 * day states follow, because colour must never be the only signal. */
.qpill.is-answered {
  border-color: var(--green);
  background: var(--green-tint);
  color: var(--green-dark);
}

/* The one you are on. Declared last so it wins over .is-answered, exactly as
 * .cg__day.is-open is re-asserted against each calendar state. */
.qpill.is-current {
  border-color: var(--ink);
  background: var(--ink);
  color: #fff;
}

/* The area review's list of what is still outstanding. */
.gaps {
  margin: 0 0 1.5rem;
  padding: 0.85rem 1rem;
  border-left: 3px solid var(--flag-develop);
  background: var(--flag-develop-tint);
  border-radius: var(--radius);
}

.gaps__title {
  margin: 0 0 0.5rem;
  font-family: var(--display);
  font-size: 0.9375rem;
  font-weight: 700;
}

.gaps__list {
  margin: 0;
  padding-left: 1.1rem;
}

.gaps__go {
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  text-align: left;
  text-decoration: underline;
  cursor: pointer;
}

.q__area,
.q__count {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gray);
}

.q__area {
  color: var(--ink);
}

.q__mode {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green-dark);
  margin: 0 0 0.4rem;
}

.q__text {
  font-size: clamp(1.4rem, 1.1rem + 1.2vw, 1.9rem);
  margin-bottom: 0.6rem;
}

.q__help,
.q__modehelp {
  font-size: 0.9375rem;
  color: var(--ink-soft);
  max-width: var(--measure);
}

.q__modehelp {
  color: var(--gray);
}

.q__input {
  margin: 1.5rem 0;
}

/* A read-only answer still has to be readable — greyed, not hidden. */
.q__input.is-locked .scale__btn.is-on,
.q__input.is-locked .yesno__btn.is-on,
.q__input.is-locked .mini.is-on {
  background: var(--ink-soft);
  border-color: var(--ink-soft);
}

.q__input.is-locked button:disabled,
.q__input.is-locked input:disabled,
.q__input.is-locked select:disabled {
  opacity: 1;
  color: var(--ink-soft);
  background: var(--paper);
  cursor: default;
}

.q__input.is-locked textarea {
  background: var(--paper);
  color: var(--ink);
}

.q__nav {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rule);
}

.q__nav .btn--primary {
  margin-left: auto;
}

.coachnote {
  font-size: 0.9375rem;
  color: var(--ink-soft);
  font-style: italic;
  border-left: 3px solid var(--rule);
  padding-left: 0.9rem;
  margin: 1.25rem 0;
  max-width: var(--measure);
}

.compare-hint {
  background: var(--green-tint-2);
  border: 1px solid var(--green-tint);
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  margin: 1.25rem 0;
  max-width: var(--measure);
}

.compare-hint__label {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--green-dark);
  margin: 0 0 0.3rem;
}

.compare-hint p:last-child {
  margin: 0;
  font-size: 0.9375rem;
}

/* ------------------------------------------------- carry-forward chips */

/*
 * Deliberately quieter than .compare-hint: this is a reference the reader
 * consults, not an instruction, and it sits directly above the answer it feeds.
 * Neutral rather than tinted, so the green blocks on the same screen keep
 * meaning "the coach is saying something".
 */
.carry {
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 0.8rem 1rem;
  margin: 1.1rem 0;
  max-width: var(--measure);
}

.carry__label {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gray);
  margin: 0 0 0.5rem;
}

.carry__items {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.carry__chip {
  display: inline-block;
  font-size: 0.875rem;
  line-height: 1.3;
  padding: 0.32rem 0.62rem;
  border-radius: 100px;
  border: 1px solid var(--rule);
  background: #fff;
  color: var(--ink);
  text-align: left;
}

button.carry__chip {
  cursor: pointer;
  font-family: inherit;
}

button.carry__chip:hover:not(:disabled) {
  border-color: var(--green);
  color: var(--green-dark);
}

/*
 * A used value stays legible rather than greying into nothing — the list is
 * still the reference it was before anything was picked. Struck through as well
 * as dimmed, so "already added" is not carried by colour alone.
 */
.carry__chip.is-used {
  color: var(--gray);
  background: var(--paper-alt);
  text-decoration: line-through;
  cursor: default;
}

.carry__hint {
  font-size: 0.8125rem;
  color: var(--gray);
  margin: 0.55rem 0 0;
}

/* --------------------------------------------------------------- scale */

.scale {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.scale__end {
  font-size: 0.8125rem;
  color: var(--gray);
  flex: 0 0 auto;
}

.scale__btns {
  display: flex;
  gap: 0.35rem;
  flex: 1 1 auto;
}

.scale__btn {
  flex: 1 1 0;
  min-width: 2.25rem;
  min-height: 52px;
  border: 1.5px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
}

.scale__btn:hover {
  border-color: var(--green);
}

.scale__btn.is-on {
  background: var(--green);
  border-color: var(--green);
  color: #fff;
}

.yesno {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.yesno__btn {
  min-height: 52px;
  min-width: 7rem;
  padding: 0 1.25rem;
  border: 1.5px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  font-family: var(--display);
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
}

.yesno__btn.is-on {
  background: var(--green);
  border-color: var(--green);
  color: #fff;
}

.yesno__btn--quiet {
  font-family: var(--body);
  font-weight: 500;
  color: var(--ink-soft);
}

.yesno__btn--quiet.is-on {
  background: var(--flag-develop);
  border-color: var(--flag-develop);
  color: #fff;
}

/*
 * A choice that changes what the question does — not an aside.
 *
 * "I don't know", "This doesn't apply to us" and "It does apply — answer it
 * instead" are all real buttons that were wearing btn--quiet: transparent
 * background, transparent border, soft ink. They read as prose, and a tester
 * reported seven times over two days that she had not realised any of them
 * could be clicked. The cost is not cosmetic — "I don't know" GENERATES AN
 * ACTION STEP, so somebody who types those words into the box instead gets a
 * thinner plan and is never told.
 *
 * Bordered and in body ink, the same register as .yesno__btn--quiet, which is
 * the control they sit beside and are a peer of.
 */
.btn--choice {
  border-color: var(--rule);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-weight: 500;
}

.btn--choice:hover:not(:disabled) {
  border-color: var(--ink-soft);
  background: var(--paper-alt);
}

/* btn--quiet had no is-on rule at all, so choosing "I don't know" changed
   nothing on screen — the second half of the same complaint, unreported. */
.btn--choice.is-on {
  background: var(--flag-develop);
  border-color: var(--flag-develop);
  color: #fff;
}

.text {
  width: 100%;
  margin-top: 0.75rem;
  font-family: var(--body);
  resize: vertical;
  overflow: hidden;
}

/* ------------------------------------------------------------- choices */

.choices {
  border: 0;
  padding: 0;
  margin: 0 0 1.25rem;
}

.choices legend {
  font-family: var(--display);
  font-size: 0.9375rem;
  font-weight: 700;
  padding: 0;
  margin-bottom: 0.5rem;
}

.choices__count {
  font-family: var(--body);
  font-weight: 400;
  font-size: 0.8125rem;
  color: var(--gray);
}

.choice {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.15rem 0.7rem;
  align-items: start;
  padding: 0.6rem 0.8rem;
  border: 1.5px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  margin-bottom: 0.4rem;
  cursor: pointer;
}

.choice.is-on {
  border-color: var(--green);
  background: var(--green-tint-2);
}

.choice input {
  grid-row: span 2;
  margin: 0.25rem 0 0;
  accent-color: var(--green);
}

.choice__name {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9375rem;
}

.choice__desc {
  font-size: 0.875rem;
  color: var(--ink-soft);
}

/* --------------------------------------------------------------- items */

.items {
  display: block;
}

/* Columns come from the field types — see itemRow() in plan.js. */
.item {
  display: grid;
  gap: 0.5rem 0.6rem;
  align-items: end;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  margin-bottom: 0.4rem;
}

.item__field {
  display: block;
  margin: 0;
  min-width: 0;
}

.item__label {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 0.25rem;
}

/* Repeating every column label down a nine-row list triples its height and
   tells the reader nothing after the first row. Kept in the DOM for screen
   readers; hidden visually once the columns are aligned. */
@media (min-width: 721px) {
  .item + .item .item__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

.item input[type='text'],
.item input[type='number'],
.item select,
.item textarea {
  width: 100%;
  min-height: 44px;
  padding: 0.45rem 0.6rem;
  border: 1.5px solid var(--rule);
  border-radius: var(--radius);
  font-family: var(--body);
  font-size: 0.9375rem;
}

/* The `long` item field (P-Pr2): two lines of sentence, grows with the text
   rather than scrolling inside a 44px box. Same border and type as its
   single-line siblings so a row reads as one form, not two. */
.item textarea {
  resize: vertical;
  line-height: 1.4;
  field-sizing: content;
}

.mini-yesno {
  display: flex;
  gap: 0.25rem;
}

.mini {
  flex: 1;
  min-height: 44px;
  border: 1.5px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  font-family: var(--display);
  font-size: 0.875rem;
  font-weight: 700;
  cursor: pointer;
}

.mini.is-on {
  background: var(--green);
  border-color: var(--green);
  color: #fff;
}

.item__gap {
  font-family: var(--display);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--gray);
  text-align: right;
  padding-bottom: 0.75rem;
  white-space: nowrap;
}

.item__gap.is-wide {
  color: var(--flag-priority);
}

.item__remove {
  width: 28px;
  height: 28px;
  margin-bottom: 0.5rem;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--gray);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
}

.item__remove:hover {
  background: var(--flag-priority-tint);
  color: var(--flag-priority);
}

.items__count {
  font-size: 0.8125rem;
  color: var(--gray);
  margin: 0.5rem 0 0;
}

.items__count.is-short {
  color: var(--flag-develop);
}

.gaps {
  margin-top: 1.25rem;
  border-top: 1px solid var(--rule);
  padding-top: 0.75rem;
}

.gaps__label {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gray);
  margin: 0 0 0.4rem;
}

.gaps__row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.3rem 0;
  border-bottom: 1px solid var(--rule-soft);
  font-size: 0.9375rem;
}

.gaps__row b {
  font-family: var(--display);
  font-variant-numeric: tabular-nums;
}

.gaps__row.is-wide b {
  color: var(--flag-priority);
}

.confidence {
  margin-top: 1.25rem;
}

/* --------------------------------------------------------- action step */

/* The action step. The container is invisible; each commitment group is its
   own green-edged card, because one big panel with hairlines between groups
   made three relationships read as a single undifferentiated stack — which
   action belonged to whom took real effort to see. */
.branch {
  margin: 1.5rem 0;
}

/* The single-purpose variants keep a box of their own: they hold one thing,
   so the container IS the group. */
.branch--optional,
.branch--locked {
  background: var(--paper);
  border: 1.5px solid var(--rule);
  border-left: 3px solid var(--gray);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  padding: 1rem 1.2rem;
}

.commit {
  background: var(--paper);
  border: 1.5px solid var(--green-tint);
  border-left: 3px solid var(--green);
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  padding: 1rem 1.2rem;
}

.commit + .commit {
  margin-top: 1rem;
}

.commit__subject {
  font-family: var(--display);
  font-size: 1.0625rem;
  font-weight: 700;
  margin: 0 0 0.1rem;
}

.commit__why {
  font-size: 0.875rem;
  color: var(--ink-soft);
  margin: 0 0 0.6rem;
}

/* Shown only when Next is pressed with an action written but never added.
   Amber rather than red: nothing has gone wrong yet, and the whole point is
   that the fix is the button sitting immediately above it. */
/* Both are the same thing — a save that stopped to say why — so they share one
   appearance rather than inventing a second amber. `.commit__warn` is both
   refusals, the empty box and the unfilled blank: one node, whose text is
   re-assigned, so a second press cannot leave the first message standing over
   the second problem. */
.commit__unsaved,
.commit__warn {
  margin: 0.75rem 0 0;
  padding: 0.7rem 0.85rem;
  border-left: 3px solid var(--flag-develop);
  background: var(--flag-develop-tint);
  border-radius: var(--radius);
  font-size: 0.9375rem;
}

.commit__add summary {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1rem;
  cursor: pointer;
  margin-bottom: 0.5rem;
}

.commit__nav {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* ------------------------------------------------- which view should I use */

/* Quiet by design: it sits under the three tabs on every plan view and is
   answering a question most readers will only ask once. Bordered rather than
   tinted, so the green blocks elsewhere keep meaning "the coach is speaking". */
.viewguide {
  margin: 0 0 1.25rem;
  max-width: 52rem;
}

.viewguide summary {
  font-family: var(--display);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 0.35rem 0;
}

.viewguide summary:hover {
  color: var(--green-dark);
}

.viewguide__list {
  list-style: none;
  margin: 0.35rem 0 0;
  padding: 0.9rem 1.05rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  display: grid;
  gap: 0.6rem;
}

.viewguide__list li {
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

/*
 * The line telling "Add to my plan" and "Put it in the backlog" apart.
 *
 * It borrows .field__help for type and colour, but that class is built to sit
 * under an input: its 0.3rem left this 4.8px under a row of buttons, close
 * enough to read as attached to the second one.
 */
.commit__help {
  margin-top: 0.75rem;
  max-width: 60ch;
}

.suggests {
  display: grid;
  gap: 0.4rem;
  margin: 0.5rem 0 1rem;
}

.suggest {
  text-align: left;
  padding: 0.6rem 0.8rem;
  border: 1.5px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  font-family: var(--body);
  font-size: 0.9375rem;
  color: var(--ink);
  cursor: pointer;
}

.suggest:hover {
  border-color: var(--green);
  background: var(--green-tint-2);
}

.suggest.is-on {
  border-color: var(--green);
  background: var(--green-tint);
}

.picker {
  width: 100%;
  min-height: 50px;
  padding: 0.7rem 0.85rem;
  border: 1.5px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  font-family: var(--body);
  font-size: 1rem;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}

.picker:hover {
  border-color: var(--green);
}

.span {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--ink-soft);
}

.span--warn {
  color: var(--flag-develop);
}

.import,
.disclose,
.acct {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: 1.1rem 1.25rem;
  margin: 1.5rem 0;
}

.disclose h2,
.acct h2 {
  font-size: 1.0625rem;
  margin-bottom: 0.4rem;
}

.disclose p:last-child,
.acct p:last-child {
  margin-bottom: 0;
}

/* The prompt to go and take the diagnostic. It used to be a paragraph saying
   they had not taken it, with no way to go and do so. */
.import--empty {
  border-color: var(--green-tint);
  background: var(--green-tint-2);
}

.import__do {
  margin: 0.9rem 0 0.6rem;
}

.acct--danger {
  border-color: var(--flag-priority-tint);
}

/* --------------------------------------------------------- action rows */

.act-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.65rem 0.75rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  margin-bottom: 0.4rem;
}

.act-row.is-done {
  background: var(--paper-alt);
}

/* Late, and not done.
 *
 * The SAME tint and border as `.cg__day.is-overdue` on the calendar, on purpose
 * — one state should not have two appearances in one product. Nothing else here
 * is shaded red, so this marks the exception rather than becoming the default:
 * "upcoming" is deliberately left plain white, because on the calendar green
 * means "something is on this day" against mostly-empty days, and in a LIST
 * every row has an action already. Shading those would tint the whole plan.
 *
 * `isOverdue()` excludes done, so this and `.is-done` never co-occur — but this
 * is declared after it anyway, so a future change that let both apply would
 * fail loudly red rather than quietly neutral.
 */
.act-row.is-overdue {
  background: var(--flag-priority-tint);
  border-color: #f0c9c6;
}

/* The word, which is the actual carrier — the tint reinforces it. */
.act-row__overdue {
  font-family: var(--display);
  font-weight: 700;
  color: var(--flag-priority);
}

/* Read-only: the same shape, minus anything that invites a click. */
.act-row.is-locked .act-row__check {
  cursor: default;
}

.act-row__date {
  color: var(--ink-soft);
}

.branch--locked {
  border-left-color: var(--gray);
  background: var(--paper-alt);
  border-color: var(--rule);
}

.act-row__check {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  margin-top: 0.1rem;
  border: 1.5px solid var(--rule);
  border-radius: 50%;
  background: var(--paper);
  color: #fff;
  font-size: 0.8125rem;
  line-height: 1;
  cursor: pointer;
}

.act-row.is-done .act-row__check {
  background: var(--green);
  border-color: var(--green);
}

.act-row__body {
  flex: 1 1 auto;
  min-width: 0;
}

.act-row__text {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.35;
}

.act-row__text:focus-visible {
  outline-offset: 4px;
}

.act-row.is-done .act-row__text {
  text-decoration: line-through;
  color: var(--gray);
}

.act-row__meta {
  margin: 0.25rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  font-size: 0.8125rem;
  color: var(--ink-soft);
}

.act-row__status {
  color: var(--gray);
}

/* "Remove this from your plan?" and its two buttons, inside the row.
 *
 * In the BODY rather than beside the × so it has the row's full width to wrap
 * into: three items at 320px do not fit on one line beside a 26px control, and
 * a header-shaped row that cannot wrap is this project's most repeated
 * overflow. Amber like the commit warnings — the same "something stopped to
 * ask" appearance, not the red of an overdue row, which is a state rather than
 * a question. */
.act-row__confirm {
  margin: 0.45rem 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.5rem;
  padding: 0.4rem 0.55rem;
  border-left: 3px solid var(--flag-develop);
  background: var(--flag-develop-tint);
  border-radius: var(--radius);
  font-size: 0.875rem;
}

.act-row__remove {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--gray);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
}

.act-row__remove:hover {
  background: var(--flag-priority-tint);
  color: var(--flag-priority);
}

.linky {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--green-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.review-item {
  margin-bottom: 1rem;
}

/* Was 0.8125rem in --gray: 2.96:1 on white, which fails WCAG AA for normal
   text outright. A tester called it "pretty faint... that context is useful",
   and it is the line naming WHICH question produced the action. --ink-soft is
   6.76:1. */
.review-item__q {
  font-size: 0.875rem;
  color: var(--ink-soft);
  margin: 0 0 0.35rem;
}

/* A question that produced several actions: printed once, with its actions
   indented under it. The rule down the left is what carries the grouping —
   indentation alone reads as an accident at mobile width, and the group must not
   depend on colour. */
.review-item--group {
  margin-bottom: 1.5rem;
}

.review-item--group > .review-item__q {
  margin-bottom: 0.5rem;
}

.review-item__one {
  border-left: 2px solid var(--rule);
  padding-left: 0.85rem;
  margin-bottom: 0.6rem;
}

.review-item__one:last-child {
  margin-bottom: 0;
}

/* The same chip as .review-item__score, leading its action rather than
   trailing the question — this is now the line that tells the group's rows
   apart, so it reads first. */
.review-item__src {
  display: inline-block;
  margin: 0 0 0.3rem;
  padding: 0.05rem 0.4rem;
  border-radius: 3px;
  background: var(--rule-soft);
  color: var(--ink-soft);
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
}

/* What they answered, beside the question that produced the action. Two actions
   from one question are otherwise indistinguishable. */
.review-item__score {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.05rem 0.4rem;
  border-radius: 3px;
  background: var(--rule-soft);
  color: var(--ink-soft);
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  white-space: nowrap;
}

/* ------------------------------------------------------------ the plan */

.plan__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
}

.seg {
  display: flex;
  border: 1.5px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--paper);
}

.seg__btn {
  border: 0;
  background: transparent;
  padding: 0.6rem 1rem;
  font-family: var(--display);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
}

.seg__btn + .seg__btn {
  border-left: 1px solid var(--rule);
}

.seg__btn.is-on {
  background: var(--green);
  color: #fff;
}

.plan__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: 0.6rem;
  margin: 1.25rem 0;
}

.tile {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--green);
  border-radius: var(--radius);
  padding: 0.7rem 0.8rem;
  text-align: center;
}

.tile b {
  display: block;
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.tile span {
  display: block;
  font-size: 0.75rem;
  color: var(--gray);
  margin-top: 0.25rem;
}

.tile--warn {
  border-top-color: var(--flag-priority);
}

.tile--warn b {
  color: var(--flag-priority);
}

.balance {
  background: var(--flag-develop-tint);
  border: 1px solid #f0e0bd;
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  margin-bottom: 1.5rem;
}

.balance p {
  margin: 0 0 0.5rem;
  font-size: 0.9375rem;
}

.pmonth {
  margin-bottom: 1.25rem;
}

.pmonth__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  font-size: 1.0625rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 0.5rem;
}

.pmonth__count {
  font-family: var(--display);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gray);
}

.pmonth.is-heavy .pmonth__count {
  color: var(--flag-priority);
}

.pmonth.is-empty .pmonth__head {
  border-color: var(--rule-soft);
  color: var(--gray);
}

.parea h2 {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  border-bottom: 2px solid var(--ink);
  padding-bottom: 0.35rem;
}

.parea h2 em {
  font-style: normal;
  margin-left: auto;
  font-size: 0.8125rem;
  color: var(--gray);
}

.backlog {
  margin-top: 2rem;
  padding: 1.1rem 1.25rem;
  border: 1px dashed var(--rule);
  border-radius: var(--radius-lg);
  background: var(--paper);
}

.plan__downloads {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  align-items: center;
  margin: 2rem 0;
}

/* ----------------------------------------------------- calendar view */

.cal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1rem;
}

.cg {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 0.75rem;
}

.cg h3 {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-size: 0.9375rem;
  margin-bottom: 0.5rem;
}

.cg h3 em {
  font-style: normal;
  margin-left: auto;
  font-size: 0.75rem;
  color: var(--gray);
}

.cg__week,
.cg__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.cg__week span {
  text-align: center;
  font-family: var(--display);
  font-size: 0.625rem;
  font-weight: 700;
  color: var(--gray);
  padding-bottom: 2px;
}

.cg__day {
  aspect-ratio: 1;
  border: 1px solid var(--rule-soft);
  border-radius: 3px;
  background: var(--paper);
  padding: 2px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  cursor: default;
}

.cg__day.has {
  background: var(--green-tint-2);
  border-color: var(--green-tint);
  cursor: pointer;
}

.cg__day.is-today {
  outline: 2px solid var(--green);
  outline-offset: -2px;
}

.cg__pad {
  aspect-ratio: 1;
}

.cg__n {
  font-family: var(--display);
  font-size: 0.625rem;
  color: var(--ink-soft);
}

.cg__dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--green);
}

.cg__dot.is-done {
  background: var(--gray);
}

/* ------------------------------------------------------ compare notes */

.cnote {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--green);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 1rem 1.2rem;
  margin-bottom: 1rem;
}

.cnote__area {
  font-family: var(--display);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gray);
  margin: 0 0 0.25rem;
}

.cnote h2 {
  font-size: 1.0625rem;
  margin-bottom: 0.5rem;
}

/* ----------------------------------------------------------- upgrade */

.upgrade {
  background: var(--paper);
  border: 1.5px solid var(--green);
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.4rem;
  margin: 2.5rem 0 0;
  max-width: 40rem;
}

.upgrade__price {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.125rem;
  color: var(--green-dark);
  margin: 0 0 0.3rem;
}

.upgrade__price span {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink-soft);
}

.upgrade h2 {
  font-size: 1.1875rem;
}

.upgrade__flagged {
  font-weight: 600;
  margin-bottom: 0.4rem;
}

.upgrade__list {
  margin: 0 0 1rem;
  padding-left: 1.1rem;
  font-size: 0.9375rem;
  color: var(--ink-soft);
}

.upgrade__list li {
  margin-bottom: 0.25rem;
}

/* -------------------------------------------------------------- footer */

.foot {
  border-top: 1px solid var(--rule);
  background: var(--paper);
  padding: 1.5rem 0 2rem;
  font-size: 0.8125rem;
  color: var(--gray);
}

.foot p {
  margin: 0 0 0.5rem;
}

.foot__links {
  list-style: none;
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
}

.foot__links a {
  color: var(--ink-soft);
}

/* ------------------------------------------------------ date popover */

.dp {
  position: absolute;
  z-index: 60;
  width: 19rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 0.75rem;
}

.dp--sheet {
  position: fixed;
  inset: auto 0 0 0;
  width: 100%;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 1rem 1rem 1.5rem;
}

.dp__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.dp__month {
  font-family: var(--display);
  font-weight: 700;
  font-size: 0.9375rem;
}

.dp__nav {
  width: 34px;
  height: 34px;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  font-size: 1.1rem;
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
}

.dp__nav:disabled {
  color: var(--rule);
  cursor: not-allowed;
}

.dp__week,
.dp__grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}

.dp__week span {
  text-align: center;
  font-family: var(--display);
  font-size: 0.6875rem;
  font-weight: 700;
  color: var(--gray);
  padding-bottom: 2px;
}

.dp__day {
  aspect-ratio: 1;
  min-height: 36px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  font-family: var(--display);
  font-size: 0.875rem;
  color: var(--ink);
  cursor: pointer;
}

.dp__day:hover {
  background: var(--green-tint-2);
  border-color: var(--green-tint);
}

.dp__day:disabled {
  color: var(--gray);
  opacity: 0.45;
  cursor: default;
}

.dp__day:disabled:hover {
  background: transparent;
  border-color: transparent;
}

.dp__day.is-today {
  border-color: var(--green);
}

.dp__day.is-selected {
  background: var(--green);
  border-color: var(--green);
  color: #fff;
  font-weight: 700;
}

/* A day that already carries an action.
 *
 * The picker knew the MONTH's load and showed it, while hiding the only thing
 * you can act on: which days those actions are on. A tester asked for the
 * calendar's dots here so she could spread them out "without having to leave
 * the question or remember which dates I've already used".
 *
 * ONE dot, not the calendar's three. There a dot is done / due-soon / overdue;
 * in the picker you are choosing a future date, so those states mean nothing
 * and reusing their colours would make the same mark say different things on
 * two screens. Here it means only: something is already here. The count is in
 * the day's aria-label, because otherwise the dot is the sole carrier.
 */
.dp__day.has-load {
  position: relative;
}

.dp__day.has-load::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 4px;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--green);
}

/* On the selected day the ground is already green, so the dot inverts rather
   than disappearing into it. */
.dp__day.has-load.is-selected::after {
  background: #fff;
}

.dp__day.has-load:disabled::after {
  background: var(--rule);
}

.dp__pad {
  aspect-ratio: 1;
}

.dp__load {
  margin: 0.6rem 0 0;
  font-size: 0.8125rem;
  color: var(--ink-soft);
  text-align: center;
}

.dp__load--full {
  color: var(--flag-develop);
}

.dp__load--heavy {
  color: var(--flag-priority);
  font-weight: 600;
}

.dp__foot {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--rule-soft);
}

.dp__link {
  background: none;
  border: 0;
  padding: 0.35rem 0.5rem;
  font-family: var(--display);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--green-dark);
  cursor: pointer;
}

.dp__link--quiet {
  color: var(--gray);
}

.dp__months {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.35rem;
}

.dp__m {
  min-height: 44px;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
  font-family: var(--display);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}

.dp__m:disabled {
  color: var(--rule);
  border-color: var(--rule-soft);
  cursor: not-allowed;
}

.dp__m.is-selected {
  background: var(--green);
  border-color: var(--green);
  color: #fff;
}

/* ----------------------------------------------------------- narrow */

@media (max-width: 720px) {
  /* On a phone a row becomes a stack: labelled fields down the page, which is
     the one layout that never truncates a name or a rating. */
  .item {
    grid-template-columns: 1fr auto !important;
  }

  .item__field {
    grid-column: 1 / -1;
  }

  /* 16px, and it is a threshold rather than a design choice.
     iOS Safari zooms the page whenever a focused control is smaller than that,
     and never zooms back out. In the item table it fired on every field: tap
     the name and the page jumps in, tap the rating beside it and the keyboard
     switches to the number pad while you are still zoomed. A tester reported
     the keyboard switching on the direct-reports question; the zoom underneath
     it is what makes filling in a row feel like a fight. The stacked layout
     above gives each field the full width, so nothing has to shrink to fit.
     Textareas are already 1rem and were never affected. */
  .item input[type='text'],
  .item input[type='number'],
  .item select,
  .item textarea {
    font-size: 16px;
  }

  .plan__head {
    flex-direction: column;
  }

  .scale__btns {
    flex-wrap: wrap;
  }

  .scale__btn {
    flex: 1 1 17%;
  }

  .q__nav .btn--primary {
    margin-left: 0;
    width: 100%;
    order: -1;
  }
}

/* ------------------------------------------- the calendar's day pop-out */

.day-detail {
  margin: 0.5rem 0 1.5rem;
  padding: 0.9rem 1rem 1rem;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--green);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.day-detail[hidden] {
  display: none;
}

.day-detail__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.6rem;
}

.day-detail__head h4 {
  margin: 0;
  font-family: var(--display);
  font-size: 0.9375rem;
}

/* The day you have open. Distinct from .is-today, which can be the same cell. */
.cg__day.is-open {
  background: var(--green);
  border-color: var(--green);
}

.cg__day.is-open .cg__n {
  color: #fff;
  font-weight: 700;
}

.cg__day.is-open .cg__dot {
  background: #fff;
}

/* --------------------------------------- calendar days, by their state */

/* Three tints, deliberately quiet. The calendar is read at a glance across up
   to thirty-six months, so anything saturated turns the page into noise — the
   job is to make one state findable, not to colour-code everything.

   Overdue beats done on a mixed day: see planCalendar. */

.cg__day.is-done {
  background: var(--paper-alt);
  border-color: var(--rule-soft);
}

.cg__day.is-done .cg__n {
  color: var(--gray);
}

.cg__day.is-overdue {
  background: var(--flag-priority-tint);
  border-color: #f0c9c6;
}

.cg__day.is-overdue .cg__n {
  color: var(--flag-priority);
  font-weight: 700;
}

/* Still owed, and inside the next thirty days. Amber is already the middle
   flag in this palette — priority red, develop amber, strength green — so this
   is the existing language rather than a new colour. */
.cg__day.is-soon {
  background: var(--flag-develop-tint);
  border-color: #efdcb8;
}

.cg__day.is-soon .cg__n {
  color: var(--flag-develop);
  font-weight: 700;
}

.cg__dot.is-soon {
  background: var(--flag-develop);
}

/* A dot for something still owed from a date that has passed. */
.cg__dot.is-late {
  background: var(--flag-priority);
}

/* The open day outranks every state tint — it is the one you are looking at.
   Re-asserted here because these rules come later in the file than the
   original .is-open block and would otherwise win on equal specificity. */
.cg__day.is-open,
.cg__day.is-open.is-done,
.cg__day.is-open.is-soon,
.cg__day.is-open.is-overdue {
  background: var(--green);
  border-color: var(--green);
}

.cg__day.is-open .cg__n,
.cg__day.is-open.is-done .cg__n,
.cg__day.is-open.is-soon .cg__n,
.cg__day.is-open.is-overdue .cg__n {
  color: #fff;
  font-weight: 700;
}

.cg__day.is-open .cg__dot,
.cg__day.is-open .cg__dot.is-done,
.cg__day.is-open .cg__dot.is-soon,
.cg__day.is-open .cg__dot.is-late {
  background: #fff;
}

/* The scale printed on a numeric item field's label.
   Quiet on desktop, where the label is a column heading over a narrow box and
   the question stem is still on screen. It earns its place on a phone, where
   the row is a stack and the label is the only thing telling you that
   "What they want from their career" wants a number. */
.item__scale {
  font-style: normal;
  font-weight: 400;
  color: var(--gray);
  letter-spacing: 0.02em;
}

/* ------------------------------------------------------- guided walkthrough
   The /demo tour over the sample plan (tour.js). The ring's oversized
   box-shadow doubles as the page dim, so nothing else needs a z-index fight
   with the app. Colors are the palette's own; nothing new. */

.tour-dim {
  position: fixed;
  inset: 0;
  background: rgba(56, 56, 59, 0.45);
  z-index: 2000;
}

.tour-ring {
  position: absolute;
  z-index: 2000;
  pointer-events: none;
  border: 2px solid var(--green);
  border-radius: 10px;
  box-shadow: 0 0 0 200vmax rgba(56, 56, 59, 0.45);
  /* No geometry transition: the follower re-writes these values while the app
     settles, and a restarted transition never converges — the ring crept for
     seconds or stuck entirely. Placement is instant and always right. */
}

.tour-card {
  position: absolute;
  z-index: 2001;
  width: min(24rem, calc(100vw - 2rem));
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 1.1rem 1.25rem 1rem;
  transition: opacity 160ms ease;
}

.tour-card--center {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(28rem, calc(100vw - 2rem));
}

/* Step cards are viewport-fixed: several targets are taller than the screen,
   so document-anchored placement put the card a full page away. */
.tour-card--fixed {
  position: fixed;
}

.tour-card h3 {
  margin: 0 0 0.5rem;
  font-size: 1.125rem;
}

.tour-card p {
  margin: 0 0 0.75rem;
  font-size: 0.9375rem;
  line-height: 1.55;
  color: var(--ink-soft);
}

.tour-card__eyebrow {
  font-family: var(--display);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--green-dark);
  margin: 0 0 0.35rem;
}

.tour-dots {
  display: flex;
  gap: 0.3rem;
  margin: 0 0 0.75rem;
}

.tour-dots i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--rule);
}

.tour-dots i.is-on {
  background: var(--green);
}

.tour-card__nav {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* The end card's two endings. Stacked rather than side by side so neither is
   the small one by accident at a narrow width, and so the primary always sits
   where the eye lands first. */
.tour-card__actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.4rem;
  margin: 0 0 0.85rem;
  text-align: center;
}

/* The card is hidden for the length of a step's scroll instead of sitting at
   the previous step's coordinates while the page travels under it — between
   steps 3 and 4 that left it fully off-screen for about two seconds, which
   reads as a card that disappeared rather than as a transition.

   `transition: none` here and 160ms on the rule above is the asymmetry that
   makes it free: hiding is instant, so pressing Next costs nothing, and only
   the arrival at the new position is animated. Only opacity is ever
   transitioned; geometry is not, for the reason on .tour-ring. */
.tour-card.is-moving {
  opacity: 0;
  pointer-events: none;
  transition: none;
}

.tour-card__nav--intro {
  justify-content: space-between;
  flex-wrap: wrap;
}

.tour-card__spacer {
  flex: 1;
}

/* The way back into the walkthrough after leaving it (or arriving without
   it). Bottom-left; the feedback button owns bottom-right. Green-outlined on
   purpose — with a gray border it disappeared into the page. */
.tour-restart {
  position: fixed;
  bottom: 1rem;
  left: 1rem;
  z-index: 40;
  padding: 0.5rem 0.9rem;
  border: 1.5px solid var(--green);
  border-radius: 100px;
  background: var(--paper);
  box-shadow: var(--shadow);
  font-family: var(--display);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--green-dark);
  cursor: pointer;
}

.tour-restart:hover {
  background: var(--green-tint);
  color: var(--ink);
}

@media (max-width: 560px) {
  /* Small screens: the card becomes a bottom sheet so it never covers the
     spotlit element it is talking about. */
  .tour-card:not(.tour-card--center) {
    position: fixed;
    top: auto !important;
    left: 0.5rem !important;
    right: 0.5rem;
    bottom: 0.5rem;
    width: auto;
  }
}

/* ------------------------------------------- the review, once it is bought

   Same shape as .upgrade, quieter: this is not selling anything, so it does
   not need the green border shouting at somebody who has already paid. */

.rev {
  background: var(--paper-alt);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: 1.25rem 1.4rem;
  margin: 2.5rem 0 0;
  max-width: 40rem;
}

.rev h2 {
  margin: 0 0 0.5rem;
  font-size: 1.125rem;
}

.rev .field {
  margin-top: 1rem;
}

/* The progress bar under the locked state. Decorative — the same numbers are
   in the sentence above it and in the label below, because a bar on its own
   tells somebody using a screen reader nothing. */
.rev__bar {
  height: 6px;
  margin: 1rem 0 0.4rem;
  border-radius: 3px;
  background: var(--rule);
  overflow: hidden;
}

.rev__bar span {
  display: block;
  height: 100%;
  background: var(--green);
}

.rev__do {
  margin: 1.25rem 0 0;
}

/* "Write my own", in the same row as the suggestions.

   Dashed rather than solid so it reads as the open-ended option next to a set
   of concrete ones, without being a different KIND of control — it does the
   same job as its neighbours: it decides what goes in the textarea below. */
.suggest--own {
  border-style: dashed;
  color: var(--ink-soft);
  font-style: italic;
}

.suggest--own.is-on {
  font-style: normal;
}

/* "N of M answered here already". One line, quiet, under the question header —
   it is orientation, not an alert. */
.q__resumed {
  margin: 0.4rem 0 0;
  font-size: 0.875rem;
  color: var(--ink-soft);
}
