/* ============================================================
   The Content Audit - page scoped styles

   Everything here uses the tokens already in site.css. No new colours, no new
   fonts. On the move to the live site this whole file appends to site.css, or
   stays a second stylesheet loaded only by this page. Nothing below touches an
   existing selector.
   ============================================================ */

/* ============================================================
   Light sections
   ============================================================
   The page runs dark hero, light premise, light scoring, dark result, light
   how we work, dark call to action. The scoring is where someone actually
   works, so it is the easiest to read; the result is dark so the number lands.

   .lt does it by redefining the palette tokens rather than restating fifty
   rules. Custom properties inherit, so every child picks the new values up
   automatically. Read --ink as "page" and --bone as "text" inside here: the
   roles flip, the names do not. --ember never changes, it is the one accent
   either way.

   Colours are the site's own: --bone and --sand already exist as the light end
   of the palette. Nothing new is introduced. */

.lt{
  --ink:        #F2EFEA;   /* page */
  --ink-raised: #FBFAF8;   /* raised card */
  --ink-line:   #DFD8CE;   /* rules and borders */
  --bone:       #141414;   /* body text */
  --sand:       #35322E;   /* secondary text */
  --muted:      #6E685F;   /* quiet text, and it still clears 4.5:1 on --ink */

  background:var(--ink);
  color:var(--bone);
}

/* Components that hardcode a light value for a dark page, and so need the
   opposite here. Every one of these was found by auditing the light sections
   rather than guessed at. */
.lt .btn{ color:#141414; }
.lt .btn:hover{ color:#F2EFEA; }
.lt .btn-ghost{ color:var(--bone); border-color:var(--ink-line); }
.lt .job-cost{ background:#F2EFEA; }
.lt .sc-btn{ color:var(--bone); border-color:#CFC6BA; }
.lt .sc-btn[aria-pressed="true"]{ color:#141414; }
.lt .job{ box-shadow:0 1px 2px rgba(20,20,20,.04); }

/* ---------- hero ---------- */

.audit-hero{ min-height:72svh; }
.audit-hero .hero-media img{ object-position:center 40%; }
.audit-hero .eyebrow{ color:rgba(242,239,234,.8); }
/* 18ch, not the 16ch the other heroes use. The authored break is after "your",
   and anything tighter wraps "content has to do" again and leaves "do" on a
   line by itself. */
/* No max-width. The authored break in content.py does the work and the column
   does the rest. A ch based cap is unreliable here: ch measures the "0" glyph,
   which ignores the 112% font-stretch on .display, so every ch value came out
   narrower than the real text and pushed a word onto its own line. */
.audit-hero h1{ font-size:var(--t-xl); }
.audit-hero .page-sub{ color:rgba(242,239,234,.86); margin-top:1.5rem; max-width:50ch; }
.audit-hero .hero-note{ color:rgba(242,239,234,.66); font-size:.875rem; margin-top:1rem; }

/* The hero stacks from the bottom, so on a short or narrow screen the content
   grows upward and the eyebrow ends up under the fixed nav, on top of the menu
   button. This keeps it clear of the bar at every size. */
.audit-hero{ padding-top:7rem; }

/* ---------- the scoring key ---------- */

.scale{
  border:1px solid var(--ink-line); background:var(--ink-raised);
  padding:clamp(1.75rem,3vw,2.5rem);
}
.scale-list{ list-style:none; margin:1.5rem 0 0; padding:0; }
.scale-list li{
  display:flex; gap:1.25rem; align-items:baseline;
  padding:.9rem 0; border-top:1px solid var(--ink-line); color:var(--sand);
}
.scale-list li:first-child{ border-top:0; padding-top:0; }
.scale-n{
  font-family:var(--display); font-size:var(--t-lg); line-height:1;
  color:var(--ember); flex:none; width:1.25em;
}
.scale-note{ color:var(--muted); font-size:.9375rem; margin-top:1.5rem; }

/* ---------- the six jobs ---------- */

/* Sized to the longer authored line, "eighteen on the board", so the only
   breaks are the ones in the copy. */
.audit-h2{ font-size:var(--t-xl); max-width:22ch; }

/* One card at a time. The stage is a readable column rather than the full
   1560px wrap, because a single card stretched across a desktop is unreadable.
   With JavaScript off every card shows and they simply stack, which is also
   what a crawler gets. */
.stage{ max-width:760px; margin-top:clamp(2.5rem,5vw,4rem); }

.jobs{ display:grid; gap:1.25rem; grid-template-columns:1fr; }

.js .jobs .job{ display:none; }
.js .jobs .job.current{ display:flex; }

/* ---------- the stepper ---------- */

html:not(.js) .stepper{ display:none; }

.stepper{
  display:grid; grid-template-columns:auto 1fr; align-items:center;
  gap:1.25rem; margin-bottom:1.5rem;
}
.step-back{
  display:inline-flex; align-items:center; gap:.5rem;
  background:none; border:0; cursor:pointer; padding:.5rem 0;
  font-family:var(--display); font-size:var(--t-meta); font-weight:600;
  letter-spacing:.14em; text-transform:uppercase; color:var(--muted);
  transition:color 200ms var(--ease);
}
.step-back:hover{ color:var(--ember); }
.step-back:disabled{ opacity:.3; cursor:default; }
.step-back:focus-visible{ outline:2px solid var(--ember); outline-offset:3px; }
.arw-l{ transition:transform 320ms var(--ease); }
.step-back:hover:not(:disabled) .arw-l{ transform:translateX(-4px); }

.step-count{
  font-family:var(--display); font-size:var(--t-meta); font-weight:600;
  letter-spacing:.14em; text-transform:uppercase; color:var(--muted);
  justify-self:end;
}
.step-count b{ color:var(--ember); font-weight:600; }

.step-bar{ grid-column:1 / -1; height:2px; background:var(--ink-line); }
.step-bar span{
  display:block; height:100%; width:0; background:var(--ember);
  transition:width 420ms var(--ease);
}

.job{
  border:1px solid var(--ink-line); background:var(--ink-raised);
  padding:clamp(1.75rem,2.6vw,2.25rem);
  display:flex; flex-direction:column;
  transition:border-color 320ms var(--ease);
}
.job[data-answered]{ border-color:var(--ember); }

.job-head{ display:flex; gap:1.25rem; align-items:flex-start; }
.job-n{
  font-family:var(--display); font-size:var(--t-xl); line-height:.85;
  color:var(--ember); flex:none;
}
.job-kicker{
  font-size:var(--t-meta); letter-spacing:.14em; text-transform:uppercase;
  color:var(--muted); font-weight:500; margin-bottom:.4rem;
}
.job-name{ font-size:var(--t-lg); }

.job-moment{
  color:var(--bone); font-size:var(--t-md); font-style:italic;
  margin-top:1.75rem;
}
.job-block{ margin-top:1.5rem; }
.job-block .meta{ display:block; margin-bottom:.5rem; }
.job-block p{ color:var(--muted); }

.job-symptoms{ list-style:none; margin:0; padding:0; }
.job-symptoms li{
  color:var(--muted); position:relative; padding-left:1.25rem; margin-top:.5rem;
}
.job-symptoms li::before{
  content:''; position:absolute; left:0; top:.7em;
  width:.5rem; height:1px; background:var(--ember);
}

.job-cost{
  margin-top:1.5rem; padding:1.125rem 1.25rem;
  background:var(--ink); border-left:2px solid var(--ember);
  color:var(--sand); font-size:.9375rem;
}
.job-cost .meta{ display:block; margin-bottom:.4rem; }

/* score row */
.job-score{ margin-top:2rem; padding-top:1.5rem; border-top:1px solid var(--ink-line); }
.sc-btns{ display:flex; gap:.5rem; margin-top:.75rem; }
.sc-btn{
  flex:1 1 0; min-height:3rem; cursor:pointer;
  font-family:var(--display); font-size:var(--t-md); font-weight:600;
  background:transparent; color:var(--bone);
  border:1px solid var(--ink-line);
  transition:background 200ms var(--ease), border-color 200ms var(--ease), color 200ms var(--ease);
}
.sc-btn:hover{ border-color:var(--ember); color:var(--ember); }
.sc-btn:focus-visible{ outline:2px solid var(--ember); outline-offset:2px; }
.sc-btn[aria-pressed="true"]{
  background:var(--ember); border-color:var(--ember); color:var(--ink);
}
.sc-hint{ color:var(--muted); font-size:.8125rem; margin-top:.75rem; }

/* Without JS the buttons do nothing, so do not dress them up as controls. */
html:not(.js) .job-score{ display:none; }

/* ---------- the detail, folded away ---------- */

.job-more{ margin-top:1.75rem; border-top:1px solid var(--ink-line); }
.job-more summary{
  cursor:pointer; list-style:none; padding:1.125rem 0 0;
  font-size:var(--t-meta); letter-spacing:.14em; text-transform:uppercase;
  color:var(--muted); font-weight:500;
  transition:color 200ms var(--ease);
}
.job-more summary::-webkit-details-marker{ display:none; }
.job-more summary:hover{ color:var(--ember); }
.job-more summary:focus-visible{ outline:2px solid var(--ember); outline-offset:3px; }
.job-more summary::after{ content:' +'; color:var(--ember); }
.job-more[open] summary::after{ content:' \2013'; }
.job-more-in{ padding-bottom:.5rem; }
.job-more .job-block:first-child{ margin-top:1.25rem; }

/* ---------- the result ---------- */

.result-band{ background:var(--ink-raised); }

.tally{
  display:flex; gap:clamp(1.5rem,4vw,3.5rem); align-items:center; flex-wrap:wrap;
  padding-bottom:clamp(2rem,4vw,3rem); border-bottom:1px solid var(--ink-line);
}
.tally-score{ display:flex; align-items:baseline; gap:.5rem; flex:none; }
.tally-n{ font-family:var(--display); font-size:var(--t-hero); line-height:.8; color:var(--ember); }
.tally-of{ font-family:var(--display); font-size:var(--t-lg); color:var(--muted); }
.tally-copy h3{ font-size:var(--t-lg); }
.tally-copy p{ color:var(--sand); margin-top:.625rem; max-width:44ch; }
.tally-empty{ color:var(--muted); max-width:44ch; }

.fix{
  margin-top:clamp(2rem,4vw,3rem); padding:clamp(1.75rem,3vw,2.5rem);
  border:1px solid var(--ember); background:var(--ink);
}
.fix h3{ font-size:var(--t-lg); margin:.625rem 0 1rem; }
.fix p{ color:var(--sand); max-width:62ch; }
.fix-note{ color:var(--muted); font-size:.875rem; margin-top:1.25rem; }

.bands{ list-style:none; margin:clamp(2.5rem,5vw,4rem) 0 0; padding:0; }
.bands li{
  display:grid; grid-template-columns:7rem 1fr; gap:1.5rem; align-items:baseline;
  padding:1.375rem 0; border-top:1px solid var(--ink-line);
  transition:opacity 320ms var(--ease);
}
.bands li[data-dim]{ opacity:.38; }
.band-range{ font-family:var(--display); font-size:var(--t-lg); color:var(--ember); }
.band-copy strong{
  display:block; font-family:var(--display); font-weight:500; font-size:var(--t-md);
  text-transform:uppercase; letter-spacing:-.01em; margin-bottom:.35rem;
}
.band-copy{ color:var(--muted); }
@media (max-width:560px){
  .bands li{ grid-template-columns:1fr; gap:.5rem; }
}

.next-copy p{ color:var(--muted); max-width:46ch; }
.next-copy p + p{ margin-top:1.25rem; }

/* ---------- email capture ---------- */

.capture{
  margin-top:clamp(3rem,6vw,5rem); padding:clamp(2rem,3.4vw,3rem);
  border:1px solid var(--ink-line); border-left:3px solid var(--ember);
  background:var(--ink);
}
.capture h3{ font-size:var(--t-lg); }
.capture-sub{ color:var(--muted); margin-top:.875rem; max-width:56ch; }
.capture-row{
  display:flex; gap:1.25rem; align-items:flex-end; flex-wrap:wrap;
  margin-top:1.75rem;
}
.capture-row .field{ flex:1 1 18rem; margin:0; }
.capture-row .btn{ flex:none; }
.capture-done{ color:var(--ember); margin-top:1.25rem; }

/* ---------- what it looks like ---------- */

.steps{ list-style:none; margin:clamp(2.5rem,5vw,4rem) 0 0; padding:0; }
.steps li{
  display:grid; grid-template-columns:5rem 1fr; gap:1.5rem;
  padding:1.75rem 0; border-top:1px solid var(--ink-line);
}
.step-n{ font-family:var(--display); font-size:var(--t-lg); color:var(--ember); line-height:1; }
.steps h4{ font-family:var(--display); font-size:var(--t-md); text-transform:uppercase; letter-spacing:-.01em; }
.steps p{ color:var(--muted); margin-top:.625rem; max-width:62ch; }
@media (max-width:560px){
  .steps li{ grid-template-columns:1fr; gap:.75rem; }
}

.facts{
  list-style:none; margin:clamp(2.5rem,4vw,3.5rem) 0 0; padding:0;
  display:grid; gap:1.5rem; grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
}
.facts li{ border-top:1px solid var(--ink-line); padding-top:1rem; }
.facts .meta{ display:block; margin-bottom:.5rem; }
.facts p{ color:var(--sand); }

/* ---------- final call to action ---------- */

.cta-steps{ list-style:none; margin:0; padding:0; }
.cta-steps li{ padding:1.375rem 0; border-top:1px solid var(--ink-line); }
.cta-steps li:first-child{ border-top:0; padding-top:0; }
.cta-steps .meta{ display:block; margin-bottom:.5rem; }
.cta-steps p{ color:var(--muted); max-width:52ch; }

.cta-band .booking-alt{ color:var(--muted); font-size:.875rem; margin-top:1rem; }
.cta-band .booking-alt a{ color:var(--ember); }

/* ---------- hidden ----------
   The browser's own [hidden] rule sits at element specificity, so any class
   above that sets display wins and the element stays on screen while the
   script thinks it is hidden. That shipped the "see your result" button at
   three of six. Restate it for every class here that sets a display. */

.tally[hidden]{ display:none; }

/* ============================================================
   Motion
   ============================================================
   Transform and opacity only, so none of it touches layout and all of it stays
   on the compositor. Every rule here is switched off by the reduced motion
   block at the foot of this file.

   The card movement is directional on purpose: forward comes in from the right,
   back comes in from the left. It is the difference between "a new card" and
   "the card I just left". */

.js .job.current{ animation:card-in 420ms var(--ease) both; }
.js .job.current.from-back{ animation-name:card-in-back; }

@keyframes card-in{
  from{ opacity:0; transform:translate3d(18px,0,0); }
  to  { opacity:1; transform:none; }
}
@keyframes card-in-back{
  from{ opacity:0; transform:translate3d(-18px,0,0); }
  to  { opacity:1; transform:none; }
}

/* The score buttons stagger in behind the card so the eye lands on the question
   before the controls. Short, and it only runs once per card. */
.js .job.current .sc-btn{ animation:sc-in 300ms var(--ease) both; }
.js .job.current .sc-btn:nth-child(1){ animation-delay:160ms; }
.js .job.current .sc-btn:nth-child(2){ animation-delay:205ms; }
.js .job.current .sc-btn:nth-child(3){ animation-delay:250ms; }
.js .job.current .sc-btn:nth-child(4){ animation-delay:295ms; }

@keyframes sc-in{
  from{ opacity:0; transform:translate3d(0,8px,0); }
  to  { opacity:1; transform:none; }
}

/* A chosen score gets one pulse. Confirmation that the tap registered, which
   matters because the card is about to change under them.

   The selector has to out-rank the stagger rule above, which is .js .job.current
   .sc-btn at three classes. At two this never fired and the tap felt dead. */
.js .job.current .sc-btn[aria-pressed="true"]{ animation:sc-pop 260ms var(--ease); }
@keyframes sc-pop{
  0%  { transform:scale(1); }
  40% { transform:scale(1.06); }
  100%{ transform:scale(1); }
}

/* The result. The number counts up in the script; this is the panel arriving
   under it. */
.tally{ animation:rise 520ms var(--ease) both; }
.fix[data-in]{ animation:rise 520ms var(--ease) 140ms both; }
.bands li{ animation:rise 460ms var(--ease) both; }
.bands li:nth-child(1){ animation-delay:220ms; }
.bands li:nth-child(2){ animation-delay:280ms; }
.bands li:nth-child(3){ animation-delay:340ms; }

@keyframes rise{
  from{ opacity:0; transform:translate3d(0,16px,0); }
  to  { opacity:1; transform:none; }
}

/* The tally number itself, so the count up has something to land on. */
.tally-n{ font-variant-numeric:tabular-nums; }

/* The fold out. A height animation would cost layout on every frame, so the
   inner block slides and fades inside the box the browser is already sizing. */
.job-more[open] .job-more-in{ animation:more-in 340ms var(--ease) both; }
@keyframes more-in{
  from{ opacity:0; transform:translate3d(0,-6px,0); }
  to  { opacity:1; transform:none; }
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion:reduce){
  .step-bar span{ transition:none; }
  .job{ transition:none; }
  .js .job.current,
  .js .job.current.from-back,
  .js .job.current .sc-btn,
  .js .job.current .sc-btn[aria-pressed="true"],
  .tally,
  .fix[data-in],
  .bands li,
  .job-more[open] .job-more-in{ animation:none; }
}
