/* ==========================================================================
   ASCENIX V7  ·  AGENCY, SET DENSE
   2026-07-29. Loads last and overrides v6.

   Journey: "we don't really need that dashboard anymore because we're an
   agency and we don't build those unless you buy the [answering product]...
   we're back to an agency and not selling anything... make it less clean.
   The footer should always be black. There's a little too much space between
   some things, but I like the overall design."

   So this is a densification pass, not a new skin. The bones, the face and the
   monochrome all survive. Four moves:

   1. LESS CLEAN MEANS DENSER, NOT DIRTIER. The page was a product page: lots
      of air around one big object. An agency page is an index of work. Air
      comes out of every vertical rhythm token at once, and the structure that
      replaces it is hairline rules, which is what a trade index actually looks
      like. Nothing here is a texture filter over the top.

   2. THE GROUND WARMS. `#FBFBFA` is near enough to `#FFFFFF` to read as a
      render surface. `#F7F6F2` is the measured Lattice canvas and it reads as
      paper. Grain comes up with it.

   3. THE FOOTER IS ALWAYS BLACK. It used to inherit a gradient seam whose
      colour depended on whether the last band happened to be dark, which meant
      four of six pages had a light footer. One rule, no exceptions.

   4. ONE ACCENT COMES BACK, AND ONLY ON THE SIGNATURE. V5 removed colour
      entirely and that was right for a product page. The index needs a
      selected state you can see from across the room, so the brand gold
      returns spent on exactly that and nothing else, which is the measured
      ~2%-of-pixels budget rather than a reskin.
   ========================================================================== */

:root{
  /* ---- 2. the ground ---- */
  --paper:#F7F6F2;
  --paper-2:#EFEDE6;
  --canvas:#F7F6F2;
  --white:#FCFBF7;          /* .band--light, so light bands read paper too */
  --surface:#FFFFFF;        /* cards only, where a true white still lifts */

  --line:rgba(17,17,18,.13);   /* rules carry the structure now, so up from .09 */
  --line-2:rgba(17,17,18,.22);

  /* ---- 1. the vertical rhythm, tightened across the board ----
     Every one of these was measured off the live page and cut. The band is the
     big one: it set the gap between every section on every page. */
  --band:clamp(34px, 3.2vw, 58px);

  /* ---- 4. the accent, for the index only ---- */
  --pick:#F0B429;              /* fills and rules only */
  --pick-ink:#8A5D04;          /* small text: gold fails contrast, this passes */
  /* Kept deliberately faint. At 13% three adjacent selected rows merged into
     one manila block and stopped reading as three separate lines in an index.
     The left rule and the tick carry the state, the wash only warms it. */
  --pick-wash:rgba(240,180,41,.06);
}

/* the page is paper, so the true-white cards need a hairline or they float */
.band--light{ background:var(--white); }

/* ==========================================================================
   THE GROUND
   V5 put four soft masses behind a `backdrop-filter: blur(34px)` pane and
   welded them with an SVG goo filter. It was the right object for a page
   selling a product and it is the wrong one for a page that is an index of
   work: liquid glass is an AI-company device, and it was arguing for the
   positioning this rebuild is moving away from. It was also the single most
   expensive thing on the page. Measured on a 4x-throttled phone, scrolling the
   homepage ran at 35-37fps with it and materially better without.

   What replaces it is what an index is printed on: paper, grain, and a tone
   that is not perfectly even. The movement that survives is `.shapes`, which
   is hairline drafting geometry and costs almost nothing, plus the rules that
   draw themselves as sections arrive. Movement now belongs to the content
   rather than to a layer behind it.
   ========================================================================== */
body{ background:var(--paper); }

/* Dead flat colour reads as a render. This is one static gradient, no blur and
   no animation, just enough tonal drift that the paper is not one value. */
body::before{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(70% 55% at 18% 0%,   rgba(17,17,18,.045), transparent 60%),
    radial-gradient(60% 50% at 92% 18%,  rgba(17,17,18,.032), transparent 62%),
    radial-gradient(80% 60% at 50% 100%, rgba(17,17,18,.038), transparent 58%);
}
/* Every page-level sibling has to sit explicitly above a fixed z-index:0 layer,
   including anything outside <main>. This is the footer-painted-blank bug from
   the 2026-07-26 audit, and it is why .foot already carries z-index:1.

   Split in two on purpose: `.nav`, `.dock` and `.callbar` are position:fixed,
   and rewriting them to relative drops them out of the viewport and stretches
   the dock to full width. Give those z-index only. */
main, .foot, .hero{ position:relative; z-index:1; }
.nav, .menu, .dock, .callbar{ z-index:var(--z-nav, 40); }
.shapes{ z-index:0; }

/* Grain rises with the warmer ground. Still nowhere near visible as texture,
   it just stops large flat areas reading as flat colour. */
.grain{ opacity:.055; }
@media (prefers-reduced-motion:reduce){ .grain{ opacity:.04; } }

/* ==========================================================================
   1. DENSITY
   The complaint was "a little too much space between some things", so this is
   deliberately a trim rather than a crush: roughly a third out of the vertical
   gaps, nothing taken out of line-height or the reading measure.
   ========================================================================== */

/* The hero was a full viewport with 168px of padding on top of that, which is
   most of a screen of nothing before the first word. It keeps its presence
   through type size, not through emptiness. */
.hero{
  min-height:auto;
  padding:clamp(104px,13vh,132px) 0 clamp(30px,4.4vh,52px);
}
.hero__center .lede{ margin-top:var(--s3); }
.hero__center .hero__cta{ margin-top:var(--s5); margin-bottom:0; }

/* ==========================================================================
   THE MANIFESTO HERO
   Ledger C-0008 makes centered-hero-plus-two-buttons a hard fail. The fix is
   not to re-centre it slightly differently: the whole archetype changes. The
   argument is now the hero, set left on an asymmetric grid, and it lands on
   the line Journey liked instead of announcing it.

   Type is set at the MANIFESTO size, not the declaration size. Mobbin measures
   tech heroes at 48-96px because those are three-word statements. A paragraph
   set at 71px is unreadable, so this runs 25px to 40px at weight 400, which is
   the corpus median weight and the right register for running text.
   ========================================================================== */
.hero__grid{ display:block; }
/* the measure belongs on the element that carries the large font-size. `ch`
   resolves against the element's OWN font-size, so 34ch on this wrapper (16px)
   was about 280px and set the paragraph as a narrow column of five-word lines. */
.hero__manifesto{ max-width:min(100%, 54rem); }

/* `.hero h1` (0,1,1) sets the 2.6rem-to-5.4rem declaration size and a 15ch
   measure, so a bare `.manifesto` (0,1,0) loses to it and the paragraph
   rendered at poster size. Matched here rather than fought with !important. */
.hero h1.manifesto{
  font-size:clamp(1.5rem, 1.08rem + 1.75vw, 2.3rem);   /* 24px to 37px, caps ~1280 */
  font-weight:400; font-variation-settings:"wght" 400;
  letter-spacing:-.021em; line-height:1.3;
  max-width:38ch; margin-bottom:0;                     /* 38ch at the DISPLAY size */
  text-wrap:pretty; margin-top:var(--s4);
}
/* the one phrase the paragraph is built to arrive at. Same gold wash the scope
   line uses for what the reader assembled, so the accent means one thing on
   this page: this is the point. */
.manifesto__em{
  font-weight:510; font-variation-settings:"wght" 510;
  box-shadow:inset 0 -.34em 0 var(--pick-wash);
}

/* one primary, and the secondary demotes to a text link. Two pills side by
   side is half of what C-0008 bans. */
.hero__alt{
  display:inline-flex; align-items:center; gap:7px;
  min-height:44px; color:var(--muted);
  text-decoration:underline; text-underline-offset:4px;
  text-decoration-color:var(--line-2);
}
.hero__alt:hover{ color:var(--ink); text-decoration-color:currentColor; }
.hero__alt svg{ width:12px; height:12px; }
/* the old centred hero left `justify-content:center` on this row, which put the
   CTA in the middle of a paragraph that is now flush left */
.hero__manifesto{ text-align:left; }
.hero__manifesto .hero__cta{
  align-items:center; justify-content:flex-start;
  gap:var(--s5); margin-top:var(--s6);
}
/* Below 520 the existing rule flips this row to `flex-direction:column`, and in
   a column the cross axis is HORIZONTAL, so the `align-items:center` above was
   what centred the button under a flush-left paragraph. Full-width stacked
   buttons are the right phone behaviour, so keep the stretch and pull the text
   link back to the left edge. */
@media (max-width:520px){
  .hero__manifesto .hero__cta{ align-items:stretch; gap:var(--s4); }
  .hero__manifesto .hero__alt{ justify-content:flex-start; }
}

@media (max-width:600px){
  .hero__manifesto{ max-width:100%; }
  .hero__cta{ gap:var(--s4); }
}

/* PRE-EXISTING BUG, fixed here rather than left alone because it is the phone
   number button on the first screen and Journey's customers are almost all on
   phones. `.btn--dark` sets `height:56px`, but the button is a flex item and a
   flex item is allowed to shrink below an explicit height: its automatic
   minimum size is its content, so inside the wrapped `.hero__cta` at phone
   widths it collapsed to a 26px line box. It measured 26px on the live site
   too, so this is not a regression from this pass.

   min-height cannot be overridden by shrinking, which is why it is the fix
   rather than another height. The nav pill is deliberately smaller and opts
   out. */
.btn{ flex-shrink:0; min-height:46px; }
.btn--dark{ min-height:56px; }
.nav .btn{ min-height:0; }

.stmt{ margin-bottom:var(--s2); }
.docnum{ margin-bottom:var(--s3); }
.plain{ margin-top:var(--s6); }
.plain__row{ padding:clamp(13px,1.5vw,19px) 0; }

/* the lede was set at up to 21.6px, which is a product-page size. An index
   page wants it closer to the body it sits above. */
.lede{ font-size:clamp(1.02rem,.98rem + .3vw,1.16rem); line-height:1.5; }
.lede--tight{ max-width:52ch; }

/* section headings sat a long way off the rule above them */
.band > .container > .h2,
.band > .container > .stmt{ margin-top:0; }

/* ==========================================================================
   3. THE FOOTER IS ALWAYS BLACK
   v6 made the footer transparent and painted a gradient ramp behind it whose
   colour was picked per page by `main:has(> .band:last-of-type.band--dark)`.
   Clever, and wrong: it meant the footer was only black on pages that happened
   to end on a dark band. Journey wants it black everywhere, so the selector
   games come out entirely rather than being extended with more cases.
   ========================================================================== */
.foot{
  background:var(--void);
  color:#FFFFFF;
  border-top:0;
  position:relative;
  z-index:1;
}
/* kill the ramp in every direction it was drawn */
.foot::before, .foot::after{ display:none !important; }
main + .foot::before, main + .foot::after{ display:none !important; }

/* the footer is now always dark, so its innards always take the dark tokens
   rather than only doing so under the :has() variant */
.foot{
  --ink:#FFFFFF; --ink-2:#C9C7C0; --muted:#9C9A93; --faint:#7E7C76;
  --line:rgba(255,255,255,.12); --line-2:rgba(255,255,255,.2);
}

/* ==========================================================================
   THE INDEX  ·  the page's spine, and the signature lives in it
   Six numbered rows on hairlines. Selecting rows composes one plain-English
   sentence describing the engagement, which is the whole agency argument
   ("we do all of this, not one thing") made by the reader rather than claimed
   in a headline.

   Deliberately NOT dressed as a document. No file numbers, no volume/issue,
   no fake metadata strip: the layout is the idea, the vocabulary stays plain.
   ========================================================================== */
.index{ margin-top:var(--s6); border-top:1px solid var(--line-2); }

/* ---- the three groups ----
   Six equally weighted rows is a flat list, and a flat list has no hierarchy:
   nothing is the star and the reader has no reason to believe the six things
   belong together. Pairing them under what they are FOR does three jobs at
   once. It gives the index a level above the row, it makes the argument the
   page has to make ("it is all the same job") structurally rather than in a
   sentence, and it gives assistive tech six related toggles in three named
   groups instead of six unrelated ones. */
.index__grplbl{
  font-family:var(--f-mono); font-size:10.5px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--faint);
  padding:var(--s5) 0 var(--s2);
  display:flex; align-items:center; gap:12px;
}
.index__grplbl::after{
  content:""; flex:1; height:1px; background:var(--line);
}
.index__grp:first-child .index__grplbl{ padding-top:var(--s3); }
.band--dark .index__grplbl::after{ background:rgba(255,255,255,.14); }

.index__row{
  display:grid;
  grid-template-columns:auto 1fr auto;
  align-items:start;
  gap:clamp(12px,2.2vw,30px);
  width:100%;
  padding:clamp(15px,1.7vw,22px) 0;
  border-bottom:1px solid var(--line);
  background:none;
  border-left:0; border-right:0; border-top:0;
  text-align:left;
  font:inherit; color:inherit;
  cursor:pointer;
  position:relative;
  transition:background 150ms cubic-bezier(.4,0,.2,1);
}
/* the whole row is the hit target, and the gold edge is the selected state.
   A left rule rather than a fill, so a selected row still reads as a line in
   an index rather than as a highlighted card. */
.index__row::before{
  content:"";
  position:absolute; left:calc(var(--pad-x) * -0.34); top:-1px; bottom:-1px;
  width:3px; background:var(--pick);
  transform:scaleY(0); transform-origin:50% 0;
  transition:transform 220ms cubic-bezier(.165,.84,.44,1);
}
.index__row[aria-pressed="true"]::before{ transform:scaleY(1); }
.index__row[aria-pressed="true"]{ background:var(--pick-wash); }
.index__row:hover{ background:rgba(17,17,18,.028); }
.index__row[aria-pressed="true"]:hover{ background:var(--pick-wash); }

.index__no{
  font-family:var(--f-mono); font-size:11px; letter-spacing:.06em;
  color:var(--faint); padding-top:.42em; font-variant-numeric:tabular-nums;
}
.index__row[aria-pressed="true"] .index__no{ color:var(--pick-ink); }

.index__body h3{
  font-size:clamp(1.02rem,.96rem + .42vw,1.32rem);
  font-weight:510; font-variation-settings:"wght" 510;
  letter-spacing:-.02em; line-height:1.2;
}
.index__body p{
  margin-top:5px; color:var(--muted);
  font-size:.945rem; line-height:1.5; max-width:58ch;
}

.index__tag{
  font-family:var(--f-mono); font-size:10.5px; letter-spacing:.07em;
  text-transform:uppercase; color:var(--faint);
  padding-top:.55em; white-space:nowrap;
}

/* the tick. Empty square until picked, so the row reads as selectable without
   an OS checkbox, which Journey has ruled out before. */
.index__tick{
  position:absolute; right:0; top:calc(clamp(15px,1.7vw,22px) + .2em);
  width:15px; height:15px; border:1px solid var(--line-2); border-radius:3px;
  display:grid; place-items:center;
  transition:background 150ms cubic-bezier(.4,0,.2,1), border-color 150ms cubic-bezier(.4,0,.2,1);
}
.index__tick svg{ width:10px; height:10px; opacity:0; transition:opacity 150ms; }
.index__row[aria-pressed="true"] .index__tick{ background:var(--pick); border-color:var(--pick); }
.index__row[aria-pressed="true"] .index__tick svg{ opacity:1; }
/* the tag would collide with the tick on wide rows */
.index__tag{ padding-right:26px; }

/* ---- the scope line: the sentence the index writes ----
   Sticky to the bottom so the sentence is visible while you are still picking,
   which is the entire point of it. Two things make that behave:

   1. It is wrapped with the rows, not with the whole section. A sticky element
      pins whenever its CONTAINING BLOCK is in view, so while it sat directly
      inside `.container` it pinned from the section heading onward and covered
      the lede and the first row before either had been read.
   2. It is one line tall at desktop width. A 200px bar pinned to the bottom of
      a 900px viewport hides a third of the thing it is describing. */
.index__wrap{ position:relative; }

.scope{
  position:sticky; bottom:0; z-index:2;
  border-top:1px solid var(--line-2);
  background:var(--canvas);
  padding:var(--s4) 0;
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--s5) var(--s6); flex-wrap:wrap;
}
.scope__txt{ min-width:min(100%, 30ch); flex:1 1 34ch; }
.scope__lbl{
  font-family:var(--f-mono); font-size:10.5px; letter-spacing:.09em;
  text-transform:uppercase; color:var(--faint); margin-bottom:5px;
}
.scope__line{
  font-size:clamp(1.04rem,.98rem + .48vw,1.3rem);
  font-weight:510; font-variation-settings:"wght" 510;
  letter-spacing:-.022em; line-height:1.34; text-wrap:pretty;
}
.scope__line b{ font-weight:510; box-shadow:inset 0 -.42em 0 var(--pick-wash); }
.scope__line.is-empty{ color:var(--muted); font-weight:400; font-variation-settings:"wght" 400; }
.scope__act{
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--s3);
  flex:0 0 auto;
}
/* before the primary, so the CTA is the thing that ends flush with the
   container edge rather than a secondary link touching it */
.scope__clear{
  order:-1;
  font-family:var(--f-mono); font-size:11px; letter-spacing:.05em;
  color:var(--muted); background:none; border:0; cursor:pointer;
  text-decoration:underline; text-underline-offset:3px; padding:6px 0;
}
.scope__clear:hover{ color:var(--ink); }
.scope__clear[hidden]{ display:none; }

@media (max-width:720px){
  .index__row{ grid-template-columns:auto 1fr; }
  .index__tag{ grid-column:2; padding-top:8px; white-space:normal; }
  .index__tick{ top:calc(clamp(15px,1.7vw,22px) + .1em); }
  .scope{ position:static; }
}

/* the row is a <button>, so the focus ring must not be the rounded 8px pill
   the global rule gives every control */
.index__row:focus-visible{ outline:2px solid var(--ink); outline-offset:-2px; border-radius:0; }

@media (prefers-reduced-motion:reduce){
  .index__row, .index__row::before, .index__tick, .index__tick svg{ transition:none; }
}

/* ==========================================================================
   DARK BAND CORRECTIONS
   The index and the scope line can both land in a dark band, and the tokens
   above are light-ground values.
   ========================================================================== */
.band--dark .index__row:hover{ background:rgba(255,255,255,.05); }
.band--dark .index__row[aria-pressed="true"]{ background:rgba(240,180,41,.12); }
.band--dark .index__row[aria-pressed="true"] .index__no{ color:var(--pick); }
.band--dark .scope{ background:var(--void); }
.band--dark .index__row:focus-visible{ outline-color:#FFFFFF; }
