/* ==========================================================================
   Campaign 03 — Design Retainer

   A comparison. The buyer is already weighing hire vs freelance vs
   subscription, so the hero is that arithmetic with their own figures in it
   rather than an assertion about which one wins.

   Shared components live in nayfla.css, which loads first.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.n-hero,
main > section.n-hero:first-of-type {
  padding-block: var(--space-l) var(--section-space-s);

  @media (min-width: 1024px) { padding-block: var(--space-xl) var(--section-space-s); }
}

/* Centred and shared with the other two campaigns — see section 4 of
   nayfla.css. The two-column split this hero used is gone. */

/* --------------------------------------------------------------------------
   The calculator
   -------------------------------------------------------------------------- */

.n-calc {
  border: 1px solid var(--hairline);
  border-radius: var(--radius-xxl);
  background: var(--white);
  box-shadow: 0 14px 44px color-mix(in oklch, var(--base) 12%, transparent);
  overflow: hidden;
}

.n-calc__inputs {
  display: grid; grid-template-columns: var(--grid-1); gap: var(--space-m);
  padding: var(--space-m);
  border-block-end: 1px solid var(--hairline);

  /* Two number fields; the slider and the scope select span the full row.
     The wider column gap is what the rule between the two cost assumptions
     sits in — at var(--space-m) the divider was closer to the freelancer
     slider than that slider's own label. */
  @media (min-width: 700px) {
    grid-template-columns: var(--grid-2);
    column-gap: var(--space-xl);
  }
}

/* Every question stacks on a phone, so each one gets the rule the volume
   question already carries — without it the four run together as one wall.
   Above the breakpoint salary and freelancer sit side by side in one row and
   a rule between them would be drawing a line down the middle of a pair. */
@media (max-width: 699px) {
  .n-calc__inputs > .n-field:not(:last-child) {
    padding-block-end: var(--space-m);
    border-block-end: 1px solid var(--hairline);
  }
}

/* The form controls (.n-field and friends) moved to section 7b of
   nayfla.css when Campaign 01's planner picked them up. */
/* The radio-group controls (.n-pills, .n-pill, .n-choice) moved to section
   7b of nayfla.css when Campaign 01's planner picked up .n-choice. */

/* Results. --pct is set by JS to scale each bar against the dearest option. */
.n-calc__out { display: grid; grid-template-columns: var(--grid-1); gap: 1px; background: var(--hairline); }
@media (min-width: 700px) { .n-calc__out { grid-template-columns: var(--grid-3); } }

.n-opt {
  padding: var(--space-m); background: var(--white);
  display: flex; flex-direction: column; gap: 0.5em;
}

/* The winner is the recommendation, so it is a solid primary panel. Every
   child colour has to be overridden — the defaults are all muted-on-white. */
.n-opt--win { background: var(--primary); }
.n-opt--win .n-opt__label,
.n-opt--win .n-opt__cost,
.n-opt--win .n-opt__per,
.n-opt--win .n-opt__note { color: var(--white); }
.n-opt__label { font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dark-muted); }
.n-opt__cost { font-family: var(--heading-font-family); font-size: clamp(1.6rem, 1.1rem + 1.8vw, 2.25rem); font-weight: 700; line-height: 1; letter-spacing: -0.02em; color: var(--heading-color); }
.n-opt__per { font-size: var(--prose-s); color: var(--text-dark-muted); }
.n-opt__bar { block-size: 6px; border-radius: 99px; background: var(--hairline); overflow: hidden; }
.n-opt__bar i { display: block; block-size: 100%; inline-size: calc(var(--pct, 0) * 1%); background: var(--primary); border-radius: 99px; transition: inline-size 0.3s var(--ease-smooth, ease); }
.n-opt--win .n-opt__bar { background: color-mix(in oklch, var(--white) 30%, transparent); }
.n-opt--win .n-opt__bar i { background: var(--white); }
.n-opt__note { font-size: var(--prose-s); color: var(--text-dark-muted); line-height: 1.45; }

/* The closing block: the verdict, its two CTAs, and the email ask. One panel,
   because they are one thought — the number, what to do about it, and what to
   do about it if you are not ready today. Half the width and centred: the
   calculator above it is full-bleed tables of figures, and the conclusion
   reads as a conclusion only if it stops being one.

   The verdict and the form keep their own elements (the JS owns the first and
   the form has to stay a <form>), so this strips the padding and rules they
   carry when they stand alone. */
.n-calc__final {
  padding: var(--space-l) var(--space-m);
  border-block-start: 1px solid var(--hairline);
  background: color-mix(in oklch, var(--base-ultra-light) 70%, transparent);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-m);
  text-align: center;

  & > * { inline-size: 100%; }
  /* 50% of the panel. Below the breakpoint that would be four words a line. */
  @media (min-width: 700px) { & > * { max-inline-size: 50%; } }
}

/* The savings panel. Two comparisons, and either can be a loss — data-dir
   carries which, so the colour and the word agree without the JS setting
   styles inline. */
.n-calc__save {
  padding: var(--space-m);
  border-block-start: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.n-calc__savetitle { margin: 0; font-size: var(--text-m); }

.n-calc__saverow {
  display: grid;
  grid-template-columns: var(--grid-1);
  gap: var(--space-s);

  @media (min-width: 560px) { grid-template-columns: var(--grid-2); }
}

.n-save {
  display: flex; flex-direction: column; gap: 0.2em;
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-l);
  border: 1px solid var(--hairline);
}

.n-save__label { font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-dark-muted); }
.n-save__amt { font-family: var(--heading-font-family); font-size: var(--text-xl); font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; }
.n-save__per { font-size: var(--prose-s); color: var(--text-dark-muted); }

.n-save[data-dir="save"] { border-color: color-mix(in oklch, var(--success) 35%, transparent); background: color-mix(in oklch, var(--success) 7%, transparent); }
.n-save[data-dir="save"] .n-save__amt { color: var(--success-readable); }
.n-save[data-dir="cost"] { border-color: color-mix(in oklch, var(--danger) 30%, transparent); background: color-mix(in oklch, var(--danger) 6%, transparent); }
.n-save[data-dir="cost"] .n-save__amt { color: var(--danger-readable); }

.n-calc__verdict { display: flex; flex-direction: column; align-items: center; gap: var(--space-s); }

.n-calc__title { margin: 0; }
.n-calc__verdict p { font-size: var(--prose); color: var(--text-dark-muted); line-height: 1.6; }
/* The JS renders the pair inside .n-row, which is left-aligned everywhere else. */
.n-calc__verdict .n-row { justify-content: center; }

/* --------------------------------------------------------------------------
   Work grid — quality is the whole sell for this offer
   -------------------------------------------------------------------------- */

.n-work {
  display: grid; grid-template-columns: var(--grid-1); gap: var(--grid-gap);

  @media (min-width: 768px) { grid-template-columns: var(--grid-2); }
}

/* One card per client — image, project, quote. The quote used to sit in its
   own grid below, which left the reader pairing quotes to projects by
   guesswork and put them four cards apart on mobile. */
.n-work__item {
  margin: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--white);
  display: flex;
  flex-direction: column;
}

.n-work img { inline-size: 100%; block-size: auto; aspect-ratio: 16/9; object-fit: cover; display: block; border-radius: 0; }

.n-work__body {
  padding: var(--space-m);
  font-size: var(--prose-s);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  /* Cards in a row keep their quotes on the same line as each other. */
  flex: 1;
}

.n-work__body h3 { margin: 0; }
.n-work__desc { color: var(--text-dark-muted); font-size: var(--prose); line-height: 1.55; }

/* The rule, rather than a second border, keeps the quote inside the card as
   one piece of evidence instead of a box bolted underneath it. */
.n-work__quote {
  /* ACSS ships a blockquote component — grey panel, left bar, own padding —
     driven entirely by these tokens behind a :where() selector. Blanking the
     tokens is the supported way out; overriding the properties one at a time
     leaves whichever one gets added to that component next. */
  --blockquote-background: none;
  --blockquote-padding: 0;
  --blockquote-border-width: 0;
  --blockquote-border-radius: 0;
  --blockquote-box-shadow: none;
  /* ACSS lays the footer out as a flex row, which makes the <cite> a flex
     item: on a phone "Ashley Tan" wrapped into a two-line column with the
     role beside it. One line of running text is what a byline is. */
  --blockquote-footer-display: block;

  margin: 0;
  margin-block-start: auto;
  padding-block-start: var(--space-s);
  border-block-start: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.n-work__quote p { font-size: var(--text-m); }
.n-work__quote footer { font-size: var(--prose-s); color: var(--text-dark-muted); }
.n-work__quote footer cite { color: var(--text-dark); font-style: normal; font-family: var(--heading-font-family); font-weight: 700; }

/* --------------------------------------------------------------------------
   Request table
   -------------------------------------------------------------------------- */

/* The table is 34rem wide minimum and scrolls sideways on a phone, where
   Complexity and Turnaround — the two columns anyone came for — start off
   screen with nothing to say so. The two `local` gradients ride with the
   content and cover the two `scroll` shadows at whichever edge is reached, so
   a shadow shows only on a side that still has table behind it. */
.n-table__scroll {
  inline-size: 100%;
  overflow-x: auto;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-xl);
  background:
    linear-gradient(to right, var(--white), transparent) 0 0 / 2.5rem 100% no-repeat local,
    linear-gradient(to left, var(--white), transparent) 100% 0 / 2.5rem 100% no-repeat local,
    linear-gradient(to right, color-mix(in oklch, var(--base) 20%, transparent), transparent) 0 0 / 1rem 100% no-repeat scroll,
    linear-gradient(to left, color-mix(in oklch, var(--base) 20%, transparent), transparent) 100% 0 / 1rem 100% no-repeat scroll,
    var(--white);
}

/* The prompt above each table. design-retainer.js hides it wherever the table
   already fits, so it only ever appears on a screen that really does need the
   sideways scroll. */
.n-table__wrap { display: flex; flex-direction: column; gap: var(--space-xs); }
.n-table__hint { font-size: var(--prose-s); color: var(--text-dark-muted); }
.n-table__hint::after { content: " \2192"; }

/* 34rem squeezed "What that looks like" to two words a line on a phone, so the
   table was both scrolling sideways and eight rows taller than it needed to be.
   Giving it the width it actually wants makes the sideways scroll the honest
   interaction rather than a consolation for a cramped one. */
.n-table { inline-size: 100%; border-collapse: collapse; font-size: var(--prose-s); text-align: start; min-inline-size: 44rem; }

.n-table caption {
  caption-side: bottom;
  padding: var(--space-s) var(--space-m);
  font-size: var(--prose-s);
  color: var(--text-dark-muted);
  text-align: start;

  /* Only while the table is genuinely wider than the screen. Pinning the
     caption to the viewport is what keeps it readable during a sideways
     scroll, but 100vw is wider than the container on a desktop, so above this
     width it was creating the very scrollbar it exists to compensate for —
     204px of overflow at 1728, on a table that fits with room to spare. */
  @media (max-width: 52rem) {
    position: sticky;
    inset-inline-start: 0;
    inline-size: calc(100vw - 2 * var(--gutter));
    max-inline-size: 100%;
  }
}
/* text-align on .n-table inherits into td but not into th: the user agent has
   its own `th { text-align: center }`, and a direct rule beats an inherited
   value. Without this the four column headers and the whole first column sit
   centred against left-aligned body cells. */
.n-table th, .n-table td { padding: var(--space-s) var(--space-m); border-block-end: 1px solid var(--hairline); vertical-align: top; text-align: start; }
.n-table thead th { font-family: var(--heading-font-family); font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dark); }
.n-table tbody th { font-weight: 500; color: var(--text-dark); }
.n-table tbody tr:last-child th, .n-table tbody tr:last-child td { border-block-end: 0; }
.n-table td:last-child { white-space: nowrap; font-family: var(--heading-font-family); color: var(--primary-dark); }

/* The throughput table has four short columns, so it does not need the 44rem
   the request table needs and should not scroll sideways on a phone. */
.n-table__title { margin: 0; font-size: var(--text-m); }
.n-table--compact { min-inline-size: 30rem; }
.n-table--compact td { white-space: nowrap; }

/* Four stacked step cards ran to about a screenful on a phone, so the board
   they change was always off screen and the section became scroll up, scroll
   down, guess what moved. One card at a time in a snap row puts the step and
   the board it describes on screen together. The board auto-advances (see
   design-retainer.js), so this is for correcting it, not for driving it. */
@media (max-width: 699px) {
  #how .n-choice--4 {
    display: flex;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    gap: var(--space-s);
  }

  #how .n-choice--4 > .n-choice__opt {
    flex: 0 0 88%;
    scroll-snap-align: start;
  }
}

/* --------------------------------------------------------------------------
   The kanban board

   A flex row that scrolls rather than a grid that reflows: on a phone four
   columns cannot be shown at once, and stacking them vertically stops it
   reading as a board at all. Above roughly 1000px all four fit and nothing
   scrolls. The min height is the tallest state (step one, four cards queued),
   so stepping through does not shift the page under the buttons that do it.
   -------------------------------------------------------------------------- */

.n-kan {
  position: relative;
  display: flex;
  gap: 1px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  min-block-size: 22rem;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-xl);
}

.n-kan__col {
  flex: 1 0 15rem;
  min-inline-size: 15rem;
  scroll-snap-align: start;
  padding: var(--space-s);
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  background: var(--base-ultra-light);
  transition: background 0.2s var(--ease-smooth, ease);
}

/* The column the current step is about. Without it the board changes and
   nothing tells you where to look. */
.n-kan__col[data-focus="true"] { background: var(--white); }

.n-kan__coltitle {
  margin: 0;
  display: flex; justify-content: space-between; align-items: center; gap: 0.5em;
  font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-dark-muted);
}

.n-kan__count { font-variant-numeric: tabular-nums; }

.n-kan__cards { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-xs); }

/* `display` on a class beats the user agent's `[hidden] { display: none }`,
   so without this the script hides cards that stay on screen. */
.n-kan__card[hidden] { display: none; }

.n-kan__card {
  display: flex; flex-direction: column; gap: 0.45em;
  padding: var(--space-s);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-l);
  background: var(--white);
  box-shadow: 0 1px 2px color-mix(in oklch, var(--base) 8%, transparent);
}

.n-kan__col[data-focus="true"] .n-kan__card { background: var(--base-ultra-light); }

.n-kan__title { font-family: var(--heading-font-family); font-size: var(--prose-s); font-weight: 700; line-height: 1.3; color: var(--heading-color); }
.n-kan__meta { display: flex; flex-wrap: wrap; gap: 0.4em 0.6em; align-items: center; font-size: var(--text-xs); }

.n-kan__pri {
  padding: 0.15em 0.6em;
  border: 1px solid;
  border-radius: 99px;
  white-space: nowrap;
}

.n-kan__pri[data-pri="high"] { color: var(--danger-readable); border-color: color-mix(in oklch, var(--danger) 35%, transparent); }
.n-kan__pri[data-pri="medium"] { color: var(--accent-readable); border-color: color-mix(in oklch, var(--accent) 35%, transparent); }
.n-kan__pri[data-pri="low"] { color: var(--text-dark-muted); border-color: var(--hairline); }

.n-kan__foot { display: flex; justify-content: space-between; gap: 0.5em; font-size: var(--text-xs); color: var(--text-dark-muted); }

.n-chip { display: inline-flex; align-items: center; gap: 0.4em; white-space: nowrap; }
.n-chip::before { content: ""; inline-size: 0.55em; block-size: 0.55em; border-radius: 50%; background: currentColor; flex-shrink: 0; }
.n-chip--light { color: var(--success-readable); }
.n-chip--medium { color: var(--accent-readable); }
.n-chip--heavy { color: var(--primary); }

/* The pill is fit-content and takes its alignment from its container. Here it
   sits under a centred heading, so it centres too. */
#pricing .n-slots { margin-inline: auto; }

/* --------------------------------------------------------------------------
   Pricing tiers — two of them, so this grid stops at two columns
   -------------------------------------------------------------------------- */

.n-tiers {
  display: grid; grid-template-columns: var(--grid-1); gap: var(--grid-gap); align-items: stretch;
  max-inline-size: 60rem; margin-inline: auto;

  /* Three plans since Design Lite. Two-up first, because three cards at 768px
     leaves each one too narrow for its feature list. */
  @media (min-width: 768px) { grid-template-columns: var(--grid-2); }
  @media (min-width: 1024px) { grid-template-columns: var(--grid-3); max-inline-size: 72rem; }
}

/* --------------------------------------------------------------------------
   Booking
   -------------------------------------------------------------------------- */

/* The shared .n-lead is shaped for Campaign 02, where it sits inside a card
   that already has padding and needs a rule to separate it from what is above.
   Here .n-calc__final does the panel and the centring, and the rule would be
   cutting one thought in half. */
.n-lead--panel {
  margin-block-start: 0;
  padding-block-start: 0;
  border-block-start: 0;
  gap: var(--space-s);
  text-align: center;

  /* Beats the shared 52ch, so the note wraps to the block's own column edge
     rather than to a narrower one of its own. Narrowing left "a list."
     orphaned on its own line; balance evens them. */
  & .n-lead__note { max-inline-size: none; text-wrap: balance; }
}
