/* =========================================================================
   Troutwood financial advisors page
   Same field, same tokens, same rhythm as the homepage. Everything here is
   additive: tokens, primitives, nav, footer, hero, the product-shot mount,
   the trust panel and the close all come from tw-system.css. Organised by
   section, in page order.

   Several components below carry the same names and the same values as their
   counterparts in tw-employers.css — the steps, the two panels, the fit grid
   and the titled trust panel are the same components doing the same job for a
   different buyer. They are duplicated rather than shared because the two
   stylesheets are never loaded together and neither page should have to read
   the other's file to be understood. If a third page needs them they should be
   promoted into tw-system.css as a single move; the values are identical on
   purpose so that move stays a move rather than a merge.
   ========================================================================= */

/* -------------------------------------------------------------------------
   01. The gap
   The problem half, carried by the one number on the page. 361 is arithmetic
   rather than a statistic — four meetings out of a calendar year — which is
   why it can stand alone with three qualitative consequences beside it and no
   supporting figures propping it up.

   Two columns rather than a row of four cards: the number is the argument and
   the list is what it costs, so they are not peers and are not drawn as peers.
   ------------------------------------------------------------------------- */

.gap__body {
  margin-top: 1.75rem;
  font-size: var(--step-lead);
  line-height: 1.55;
  color: var(--text-secondary);
}

/* 20rem for the figure column, not a fraction: the number is set in vw-scaled
   type and a fractional column lets it collide with the list a long way before
   the layout is narrow enough to want stacking. */
.gap__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
  gap: clamp(2rem, 5vw, 4rem);
  margin-top: clamp(2.5rem, 5vw, 4rem);
  align-items: start;
}

.gap__figure {
  padding: clamp(1.75rem, 3vw, 2.5rem);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* Sage rather than sage-bright, which is the one place on the page inversion
   is safe: this is display type well past the 24px large-text threshold, where
   sage clears contrast at 3.8:1 on the glow's brightest. */
.gap__number {
  display: block;
  font-size: clamp(4rem, 2rem + 9vw, 7.5rem);
  font-weight: 800;
  line-height: 0.9;
  letter-spacing: -0.05em;
  color: var(--sage);
}

.gap__unit {
  display: block;
  margin-top: 0.75rem;
  font-size: var(--step-h3);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.015em;
}

.gap__caption {
  margin-top: 1.125rem;
  padding-top: 1.125rem;
  border-top: 1px solid var(--rule);
  font-size: var(--step-small);
  line-height: 1.55;
  color: var(--text-secondary);
}

.gap__items {
  display: grid;
  gap: 1.75rem;
}

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

.gap__item:first-child {
  border-top: 0;
  padding-top: 0;
}

.gap__item p {
  margin-top: 0.5rem;
  font-size: var(--step-small);
  line-height: 1.55;
  color: var(--text-secondary);
}

/* -------------------------------------------------------------------------
   02. The calendar
   This page's showpiece, and the only place the argument is shown rather than
   stated. One client's year, drawn at the pitch a year is actually drawn at:
   53 columns of 7 days. The strip lights the whole year and leaves the four
   review days brightest, because the meetings were never the thing being
   argued against.

   The field is 7.5:1, so the panel runs the full measure. Any narrower and the
   day pitch clamps to nothing and the year reads as one grey smear.

   Drawn as background-images rather than as markup: 371 spans is 371 layout
   boxes for pure decoration, where one tiled radial-gradient costs a single
   paint and scales to whatever width the panel lands at.

   The whole stage is aria-hidden. The caption states the claim in words
   directly underneath, so nothing here is the only carrier of meaning.
   ------------------------------------------------------------------------- */

.calendar__body {
  margin-top: 1.75rem;
  font-size: var(--step-lead);
  line-height: 1.55;
  color: var(--text-secondary);
}

.calendar__stage {
  display: grid;
  gap: 1rem;
  margin-top: clamp(2.5rem, 5vw, 4rem);
}

.calendar__panel {
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

/* 53 by 7 exactly, so every layer inside shares this element's tile size and
   origin. That is what keeps the four lit days sitting precisely on top of the
   dim ones they replace instead of a pixel beside them. */
.calendar__field {
  position: relative;
  aspect-ratio: 53 / 7;
  border-radius: calc(var(--radius) - 8px);
  overflow: hidden;
}

.calendar__field > span {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle at center, currentColor 1.6px, transparent 2.05px);
  background-size: calc(100% / 53) calc(100% / 7);
}

/* The year, unlit. Every day is present in both strips; only the lighting
   changes, because the year was never the variable. */
.calendar__days {
  color: rgba(255, 255, 255, 0.16);
}

/* The four reviews. A fatter dot than the dim layer on the same centres, so
   the lit days sit on top of the ones they replace rather than beside them.

   Selected through the parent rather than on the class alone, and that is
   load-bearing rather than tidiness: `.calendar__field > span` above is
   (0,1,1) and a bare `.calendar__meets` is (0,1,0), so the base radius would
   win the cascade and this layer would differ from the dim one by colour
   only. Matching the parent puts both rules at (0,1,1) and lets source order
   decide, which is what was intended.

   Masked to four cells at the quarter marks. Each radius is quoted against the
   box, so the horizontal one has to stay under a single column's 1.887% or the
   mask bleeds into the neighbouring day; 1.4% clears it with room to spare and
   still covers the dot it is there to reveal. The vertical pair is the same
   arithmetic against a row's 14.29%. */
.calendar__field > .calendar__meets {
  color: var(--sage-bright);
  background-image: radial-gradient(circle at center, currentColor 2.5px, transparent 3px);
  filter: drop-shadow(0 0 6px rgba(103, 188, 124, 0.65));
  -webkit-mask-image: radial-gradient(ellipse 1.4% 10.5% at 8.5% 50%, #000 45%, transparent 100%),
    radial-gradient(ellipse 1.4% 10.5% at 33% 50%, #000 45%, transparent 100%),
    radial-gradient(ellipse 1.4% 10.5% at 57.5% 50%, #000 45%, transparent 100%),
    radial-gradient(ellipse 1.4% 10.5% at 82.1% 50%, #000 45%, transparent 100%);
  mask-image: radial-gradient(ellipse 1.4% 10.5% at 8.5% 50%, #000 45%, transparent 100%),
    radial-gradient(ellipse 1.4% 10.5% at 33% 50%, #000 45%, transparent 100%),
    radial-gradient(ellipse 1.4% 10.5% at 57.5% 50%, #000 45%, transparent 100%),
    radial-gradient(ellipse 1.4% 10.5% at 82.1% 50%, #000 45%, transparent 100%);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* The second strip's steady state. Deliberately dimmer than the four reviews:
   being present every day is not the same claim as sitting down together, and
   drawing them at equal weight would make the section say something the
   product does not. */
.calendar__steady {
  color: rgba(143, 217, 163, 0.46);
}

/* A band of brighter days travelling across the year. It exists to say the
   second strip is live rather than merely more filled in: the difference
   between the two panels is the whole section, and a static contrast reads as
   a colour choice. Switched off under reduced motion at the foot of this file.

   Selected through the parent for the same cascade reason `.calendar__meets`
   is: `.calendar__field > span` is (0,1,1), so a bare `.calendar__sweep` could
   not restate `background-image` and the days under the band would stay the
   base dot size. Every later rule that touches this layer has to match, which
   is why the reduced-motion block at the foot of the file is written the same
   way.

   The days under the band do not merely change colour, they fatten and glow:
   at 1.6px a brightness step alone is a couple of hundred barely-changed
   pixels, which is how this read as a tint rather than as light. 2.2px with a
   halo lands between the unlit year and the four reviews, so the year visibly
   comes on under the band and the meetings stay the brightest thing in it.

   The mask is a crisp leading edge with a long tail behind it, rather than the
   symmetric blur it was: a band with a front reads as something moving, and a
   band without one reads as a soft patch. Travel is left to right, so the
   light runs January to December with the scale underneath rather than
   against it. The 300% mask is what buys the clean entrance and exit: kept
   between the thirds of the image, the band clears the left-hand edge before
   the pass starts and the right-hand edge after it ends, so each pass arrives
   rather than fading up mid-strip. */
.calendar__field > .calendar__sweep {
  color: #eafff2;
  background-image: radial-gradient(circle at center, currentColor 2.2px, transparent 2.7px);
  filter: drop-shadow(0 0 5px rgba(143, 217, 163, 0.7));
  -webkit-mask-image: linear-gradient(
    100deg,
    transparent 44%,
    rgba(0, 0, 0, 0.25) 53%,
    rgba(0, 0, 0, 0.65) 59%,
    #000 62%,
    rgba(0, 0, 0, 0.2) 63.5%,
    transparent 64%
  );
  mask-image: linear-gradient(
    100deg,
    transparent 44%,
    rgba(0, 0, 0, 0.25) 53%,
    rgba(0, 0, 0, 0.65) 59%,
    #000 62%,
    rgba(0, 0, 0, 0.2) 63.5%,
    transparent 64%
  );
  -webkit-mask-size: 300% 100%;
  mask-size: 300% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  /* The delay is held with the animation while the panel is off screen, so it
     is a lead-in on the first pass rather than dead time at page load: the
     reveal is 320ms of stagger and 900ms of travel, and a band crossing under
     a panel still at nothing is a pass spent. */
  animation: calendar-sweep 4.5s linear 0.85s infinite;
}

/* Held until the panel is actually on screen. The pass is the argument, and an
   animation that has been looping since page load hands the reader whatever
   phase it happens to be in when they arrive — often the beat where the band
   is off the edge entirely, which is the version of this that gets missed.
   Gated behind `.reveal-ready` so that without JS, where `.is-in` is never
   set, the sweep simply runs. */
.reveal-ready .calendar__panel:not(.is-in) .calendar__sweep {
  animation-play-state: paused;
}

/* Runs 100% to 0%, and that is the whole of what makes this go left to right.
   A percentage mask-position offsets the image by (area - image) x P, so with
   a 300% image the offset runs 0 at 0% to -2x the strip at 100%. The band sits
   at 62% of the image, which is 1.86 strips out past the right-hand edge at
   0%, and 0.14 short of the left-hand edge at 100%. Counting down from 100 is
   therefore January to December; counting up is the year running backwards. */
@keyframes calendar-sweep {
  from {
    -webkit-mask-position: 100% 0;
    mask-position: 100% 0;
  }

  to {
    -webkit-mask-position: 0% 0;
    mask-position: 0% 0;
  }
}

/* Two words, at the two ends. Month ticks would have to line up with the day
   pitch to avoid reading as sloppy, and January and December carry the same
   information with nothing to misalign. */
.calendar__scale {
  display: flex;
  justify-content: space-between;
  margin-top: 0.75rem;
  font-size: var(--step-eyebrow);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.calendar__caption {
  margin-top: 1.125rem;
}

.calendar__caption h3 {
  font-size: var(--step-body);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.015em;
}

.calendar__caption p {
  margin-top: 0.375rem;
  max-width: 46rem;
  font-size: var(--step-small);
  line-height: 1.55;
  color: var(--text-secondary);
}

/* -------------------------------------------------------------------------
   03. Rollout
   Four steps. The rule and its lit node are drawn per step rather than as one
   rail behind the row: side by side they line up into a single rail, and when
   the grid wraps each step keeps its own marker instead of trailing a line to
   nowhere.

   The node runs sage to sky across the four, which is the same direction the
   platform page gives the round trip: expertise out, signal back.
   ------------------------------------------------------------------------- */

.rollout__body {
  margin-top: 1.5rem;
  font-size: var(--step-lead);
  color: var(--text-secondary);
}

/* The closing sentence is the one the reader needs off the section, so it
   takes white and the weight while the two disclaimers before it stay at
   secondary. Same device as the institutions page's gap items. */
.rollout__body strong {
  font-weight: 700;
  color: var(--text-primary);
}

.rollout__steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: clamp(1.75rem, 3vw, 2.5rem);
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}

.rollout__step {
  position: relative;
  padding-top: 2rem;
}

.rollout__step::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--rule);
}

.rollout__step::after {
  content: '';
  position: absolute;
  top: -3px;
  left: 0;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--node, var(--sage));
  box-shadow: 0 0 12px var(--node, var(--sage));
}

.rollout__step:nth-child(2) {
  --node: #6ab894;
}

.rollout__step:nth-child(3) {
  --node: #63b0c6;
}

.rollout__step:nth-child(4) {
  --node: var(--sky);
}

.rollout__num {
  display: block;
  font-size: var(--step-eyebrow);
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--text-tertiary);
}

.rollout__step h3 {
  margin-top: 0.625rem;
}

.rollout__step p {
  margin-top: 0.5rem;
  font-size: var(--step-small);
  line-height: 1.55;
  color: var(--text-secondary);
}

/* Same device as the section's own lede above: the part of the step the
   reader needs off the page takes white and the weight, and the setup before
   it stays at secondary. */
.rollout__step strong {
  font-weight: 700;
  color: var(--text-primary);
}

/* -------------------------------------------------------------------------
   04. Both chairs
   Two panels of equal weight. Not a comparison table: the same relationship
   seen from the two people sitting in it.
   ------------------------------------------------------------------------- */

.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 21rem), 1fr));
  gap: 1rem;
  margin-top: clamp(2.5rem, 5vw, 4rem);
}

.split__panel {
  /* A token rather than a literal because the cover below has to cancel it
     exactly on three sides, and two clamps that have to agree are one clamp
     waiting to disagree. */
  --panel-pad: clamp(1.5rem, 3vw, 2.5rem);
  position: relative;
  padding: var(--panel-pad);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  overflow: hidden;
}

/* One lit edge per panel. The eyebrow above it names which side this is, so
   the colour reinforces a label rather than carrying one on its own. */
.split__panel::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
}

.split__panel--client::before {
  background: linear-gradient(to right, var(--sage), rgba(103, 188, 124, 0));
}

/* --sky is a 3.5:1 colour at the glow's brightest: it can hold a 2px rule and
   it cannot hold type, so the eyebrow above it stays sage. */
.split__panel--practice::before {
  background: linear-gradient(to right, var(--sky), rgba(90, 167, 248, 0));
}

/* A crop of the real thing across the head of each panel, cut tight enough to
   read at panel width: the five shields as they appear in a hand, and the
   summary card as it appears in the console. Section 05 then shows the console
   at size, so the page runs detail, then object. That order is deliberate. The
   detail is small enough to take in while reading the list beside it, and by
   the time the whole record arrives the reader knows what to look for on it.

   No radius and no negative bottom margin: the panel is already clipped and
   already rounded, so the cover inherits both by being inside it, and the two
   sides only have to agree about one number.

   No mount either, and that is the reason these are the one place on the
   redesigned pages a capture is not framed as a device. A cover bleeds to
   three edges of the panel it is in, which is what makes it read as the head
   of the panel rather than as a picture inside it; a bezel drawn around it
   would be a second frame inside a frame that is already there. */
.split__cover {
  margin: calc(var(--panel-pad) * -1) calc(var(--panel-pad) * -1) calc(var(--panel-pad) + 0.75rem);
  border-bottom: 1px solid var(--rule);
}

.split__cover img {
  display: block;
  width: 100%;
  height: auto;
}

.split__title {
  margin-top: 1rem;
  font-size: var(--step-h2);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.025em;
}

.split__list {
  display: grid;
  gap: 1.5rem;
  margin-top: clamp(1.75rem, 3vw, 2.25rem);
  padding-top: clamp(1.75rem, 3vw, 2.25rem);
  border-top: 1px solid var(--rule);
}

.split__list h4 {
  margin: 0;
  font-size: var(--step-body);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.015em;
}

.split__list p {
  margin-top: 0.375rem;
  font-size: var(--step-small);
  line-height: 1.55;
  color: var(--text-secondary);
}

/* -------------------------------------------------------------------------
   05. Proof
   The section above argues the two chairs in words and the panel covers give
   each one a detail; this shows the surfaces themselves. The mount is `.shot`,
   in tw-system.css. Everything here is the arrangement.

   The lead is one household rather than the whole dashboard, and it is held to
   the crop's own width instead of the full measure. Two reasons, and they
   agree. The console captures are 2x of a 1440px viewport, so a crop shown
   past its native width is an upscale that reads as a blurred export; 47rem is
   753px, which is exactly what the rectangle was cut at. And the household
   record is the shot an advisor is actually here for. The whole-organization
   dashboard is the employers page's lead because that page is selling a
   population; this one is selling the person whose review is on Thursday.

   `shot--detail` rather than `shot--console`, even in the lead slot. The
   window bar in section 20 of tw-system.css claims a whole application, and
   every capture on this page is a crop of one. A bar drawn around a panel
   would be the mount telling a small lie about what the reader is looking at.
   ------------------------------------------------------------------------- */

.proof__body {
  margin-top: 1.5rem;
  font-size: var(--step-lead);
  line-height: 1.55;
  color: var(--text-secondary);
}

/* The two things the section is about, on the two words each that name them.
   Same device the rollout lede and steps use above. */
.proof__body strong {
  font-weight: 700;
  color: var(--text-primary);
}

.proof__lead {
  width: 100%;
  max-width: 47rem;
  margin: clamp(2.5rem, 5vw, 4rem) auto 0;
}

/* Two crops, and the track has to stay near their native width for the same
   reason the lead does. At the full measure each lands around 540px against
   834 and 753 of capture, which is a downscale and safe. */
.proof__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: clamp(2rem, 4vw, 3rem);
  margin-top: clamp(2.75rem, 5vw, 4rem);
}

/* Two handsets, held to 36rem so each track lands on the phone's own width.
   That is what puts the left edge of a caption under the left edge of the
   device it belongs to; run across the full measure the tracks would be twice
   the handset and every caption would start out in space beside it.

   The 3rem gutter is the same one the platform page's phone row uses, doing
   the same job: two mounted devices a rule's width apart read as one object
   split down the middle. */
.proof__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  justify-items: center;
  gap: clamp(2.25rem, 4.5vw, 3.5rem) 3rem;
  max-width: 36rem;
  margin: clamp(2.75rem, 5vw, 4rem) auto 0;
}

.proof__phone {
  width: 100%;
  max-width: 16.5rem;
}

/* Below this the pair is two 200px handsets, which is under what the app's own
   type survives. One column, a little smaller, and the captions come back
   under the middle. */
@media (max-width: 640px) {
  .proof__pair {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(2rem, 6vw, 3rem);
  }

  .proof__phone {
    max-width: 15rem;
  }

  .proof__pair .shot__caption {
    text-align: center;
    justify-self: center;
  }
}

/* -------------------------------------------------------------------------
   06. Fit
   ------------------------------------------------------------------------- */

.fit__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
  gap: clamp(1.75rem, 3vw, 2.5rem);
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}

.fit__rule {
  width: 2rem;
  height: 2px;
  margin-bottom: 1.125rem;
  background: var(--sage);
  box-shadow: 0 0 14px var(--accent-glow);
}

.fit__item p {
  margin-top: 0.625rem;
  font-size: var(--step-small);
  line-height: 1.55;
  color: var(--text-secondary);
}

/* -------------------------------------------------------------------------
   07. Trust
   The panel itself is the homepage's, unchanged. The homepage runs it with a
   visually-hidden heading and nothing above it, so it needs no top margin
   there; here it sits under a visible eyebrow and title, which is what this
   modifier is for.
   ------------------------------------------------------------------------- */

.trust__panel--titled {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
}

/* The four commitments used to open on a 2px accent line; they now open on
   the homepage's icon tile instead. The tile carries --sage-bright by
   default, which is the token every small accent uses on the field. This
   panel is inside the paper band, where --sage is 5.7:1 and passes as a
   foreground on its own, so the glyph keeps the exact green the rule it
   replaced was drawn in rather than shifting a shade off it. */
.trust__icon {
  color: var(--sage);
}

/* -------------------------------------------------------------------------
   08. Reduced motion
   The sweep is the only thing on this page that moves of its own accord. The
   lit year underneath it stays exactly as it is, so the section still makes
   its point with the animation gone.
   ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .calendar__field > .calendar__sweep {
    animation: none;
    -webkit-mask-image: none;
    mask-image: none;
    /* The halo goes with the motion. Unmasked it is on all 371 days at once,
       which is a green haze over the strip rather than light on any part of
       it; the fattened dot alone still reads as the lit year. */
    filter: none;
    opacity: 0.3;
  }
}

/* -------------------------------------------------------------------------
   09. Print
   ------------------------------------------------------------------------- */

@media print {
  .calendar__field {
    display: none;
  }

  .gap__figure,
  .calendar__panel,
  .split__panel {
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}
