/* ============================================================
   JACK GREENTREE — MORTGAGE BROKER
   Visual system: a property campaign, not a bank.
   Warm uncoated paper, one grotesque at hard weight contrast, one eucalypt accent.
   Golden Marketing, Aug 2026. See DESIGN.md at repo root.
   ============================================================ */

:root{
  /* surface */
  --paper:oklch(0.968 0.006 85);
  --paper-2:oklch(0.940 0.009 80);

  /* ink */
  --ink:oklch(0.21 0.012 55);
  --ink-2:oklch(0.45 0.012 55);
  --ink-3:oklch(0.515 0.011 55);   /* detail lines; darkened from 0.60 — 0.545 failed AA on --paper-2 at 4.17 */

  /* the single accent */
  --accent:oklch(0.40 0.070 155);
  --accent-2:oklch(0.30 0.055 155);
  --accent-1:oklch(0.93 0.018 155);

  --rule:1px;
  --ease:cubic-bezier(0.22,1,0.36,1);
  --gut:clamp(20px,5vw,64px);
  --measure:66ch;
}

*{margin:0;padding:0;box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;}

body{
  font-family:'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
  font-size:17px;
  line-height:1.65;
  color:var(--ink);
  background:var(--paper);
  -webkit-font-smoothing:antialiased;
}

img{max-width:100%;display:block;}
a{color:inherit;text-decoration:none;}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;}

h1,h2,h3{
  font-family:'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
  font-weight:700;
  line-height:1.02;
  letter-spacing:-0.03em;
}

/* ---------- the detail line: the signature device ----------
   A listing carries "4 BED · 2 BATH · 1 CAR". This carries the facts that
   actually qualify him. It appears under the hero, under each case note and
   in the footer, and it is what makes the pages read as one thing. */
.detail{
  font-size:clamp(10.5px,1.05vw,11.5px);
  font-weight:600;
  letter-spacing:0.17em;
  text-transform:uppercase;
  color:var(--ink-3);
  display:flex;flex-wrap:wrap;align-items:center;
  gap:0.55em 0.9em;
  line-height:1.7;
}
.detail > span{display:inline-flex;align-items:center;gap:0.9em;}
.detail > span:not(:last-child)::after{
  content:'';width:3px;height:3px;border-radius:50%;
  background:var(--ink-3);opacity:.75;
}
.detail-accent{color:var(--accent);}
/* A wrapped detail line strands a separator dot at the end of a line, which looks like
   a typo. Below the width where these reliably fit on one line, stack them and drop the
   dots entirely rather than trying to suppress a trailing one, which CSS cannot do. */
@media(max-width:620px){
  .detail{flex-direction:column;align-items:flex-start;gap:5px;}
  .detail > span:not(:last-child)::after{display:none;}
}
/* Longer detail lines need to stack sooner than the short ones. Applied per instance
   rather than guessing a single breakpoint that suits every content length. */
@media(max-width:1100px){
  .detail-long{flex-direction:column;align-items:flex-start;gap:5px;}
  .detail-long > span:not(:last-child)::after{display:none;}
}

/* ---------- shell ---------- */
.wrap{
  max-width:1180px;
  margin:0 auto;
  padding:0 var(--gut);
}
.narrow{max-width:var(--measure);}

/* ---------- masthead ---------- */
.mast{
  position:sticky;top:0;z-index:50;
  background:oklch(0.968 0.006 85 / .93);
  backdrop-filter:blur(10px);
  border-bottom:var(--rule) solid var(--accent-1);
}
.mast-in{
  max-width:1180px;margin:0 auto;padding:16px var(--gut);
  display:flex;align-items:center;gap:24px;
}
.wordmark{
  font-family:'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
  font-size:22px;font-weight:700;letter-spacing:-0.03em;line-height:1;white-space:nowrap;
}
.wordmark small{
  display:block;
  font-family:'Familjen Grotesk',sans-serif;
  font-size:9.5px;font-weight:600;letter-spacing:0.2em;text-transform:uppercase;
  color:var(--ink-3);margin-top:5px;
}
.mast-nav{display:none;gap:30px;margin-left:auto;align-items:center;}
.mast-nav a{
  font-size:14.5px;font-weight:500;color:var(--ink-2);
  padding-bottom:3px;border-bottom:1px solid transparent;
  transition:color .2s,border-color .2s;
}
@media(hover:hover){.mast-nav a:hover{color:var(--ink);border-bottom-color:var(--accent);}}
.mast-nav a[aria-current]{color:var(--ink);border-bottom-color:var(--accent);}
.mast-right{margin-left:auto;display:flex;align-items:center;gap:14px;}
@media(min-width:940px){
  .mast-nav{display:flex;}
  .mast-right{margin-left:0;}
}

/* ---------- buttons ---------- */
.plate{
  display:inline-flex;align-items:center;justify-content:center;
  font-family:'Familjen Grotesk',sans-serif;
  font-size:14.5px;font-weight:600;letter-spacing:0.04em;
  padding:14px 26px;min-height:48px;
  border:1px solid var(--ink);
  background:var(--ink);color:var(--paper);
  border-radius:2px;
  transition:background .2s var(--ease),color .2s var(--ease);
  white-space:nowrap;
}
@media(hover:hover){.plate:hover{background:var(--accent-2);border-color:var(--accent-2);}}
.plate-ghost{background:transparent;color:var(--ink);border-color:var(--ink);}
@media(hover:hover){.plate-ghost:hover{background:var(--ink);color:var(--paper);}}
.plate-sm{font-size:13.5px;padding:10px 18px;min-height:42px;}
.plate-light{background:var(--paper);color:var(--ink);border-color:var(--paper);}
@media(hover:hover){.plate-light:hover{background:var(--accent-1);border-color:var(--accent-1);color:var(--ink);}}

.burger{
  display:flex;flex-direction:column;gap:5px;background:none;
  border:1px solid var(--ink);padding:11px;cursor:pointer;
  min-height:44px;min-width:44px;align-items:center;justify-content:center;border-radius:2px;
}
.burger span{width:18px;height:1.5px;background:var(--ink);display:block;}
@media(min-width:940px){.burger{display:none;}}
.drawer{display:none;border-bottom:var(--rule) solid var(--accent-1);background:var(--paper);}
.drawer.open{display:block;}
.drawer a{
  display:block;padding:16px var(--gut);
  border-top:var(--rule) solid var(--accent-1);
  font-size:16px;font-weight:500;min-height:52px;
}
.drawer .drawer-cta{padding:18px var(--gut);border-top:var(--rule) solid var(--ink);}
.drawer .drawer-cta .plate{width:100%;}

/* ---------- inline links ---------- */
.prose a,.link{
  border-bottom:1px solid var(--accent);
  padding-bottom:1px;
  transition:background .2s;
}
@media(hover:hover){
  .prose a:hover,.link:hover{background:var(--accent-1);}
}

/* ---------- hero ---------- */
.hero{padding:clamp(48px,8vw,104px) 0 clamp(40px,6vw,80px);}
.hero-grid{
  display:grid;grid-template-columns:1fr;
  gap:clamp(32px,5vw,64px);align-items:center;
}
@media(min-width:900px){
  .hero-grid{grid-template-columns:1.08fr 0.92fr;gap:clamp(44px,5vw,76px);}
}
.hero h1{
  font-size:clamp(38px,6.4vw,72px);
  max-width:15ch;
}
.hero h1 em{font-style:italic;}
.hero-sub{
  font-size:clamp(17px,1.8vw,20px);
  color:var(--ink-2);
  max-width:44ch;
  margin-top:clamp(20px,2.4vw,28px);
}
.hero-acts{display:flex;flex-wrap:wrap;gap:14px;margin-top:clamp(26px,3vw,36px);}
.hero .detail{margin-top:clamp(26px,3vw,34px);padding-top:20px;border-top:var(--rule) solid var(--accent-1);}

.portrait{position:relative;}
/* The hero portrait is the jacaranda shot: Jack kneeling on the lawn with Schooner,
   golden hour, fairy lights in the tree. Already trimmed at the bottom in ffmpeg so the
   slides are gone and the dog is whole, which leaves 1100x1532. The aspect-ratio matches
   the file, so nothing is cropped again in CSS and the photographer's framing survives. */
.portrait img{
  width:100%;height:auto;border-radius:2px;
  aspect-ratio:1100/1532;object-fit:cover;object-position:center center;
}
/* The contact page carries the office shot instead, for a professional register. It is a
   2:3 studio frame, so it gets its own ratio. */
.portrait-office img{aspect-ratio:900/1350;object-position:center 20%;}
.portrait figcaption{
  margin-top:14px;
  font-size:11px;font-weight:600;letter-spacing:0.17em;text-transform:uppercase;
  color:var(--ink-3);
}

/* ---------- section scaffolding ---------- */
.sec{padding:clamp(56px,8vw,110px) 0;}
.sec-sunk{background:var(--paper-2);}
.sec-head{max-width:var(--measure);margin-bottom:clamp(28px,4vw,48px);}
.sec-label{
  font-size:11px;font-weight:600;letter-spacing:0.2em;text-transform:uppercase;
  color:var(--accent);margin-bottom:16px;
}
.sec-head h2{font-size:clamp(28px,4.4vw,50px);}
.sec-head p{margin-top:18px;color:var(--ink-2);font-size:17.5px;}

/* ---------- prose ---------- */
.prose{max-width:var(--measure);}
.prose p{margin-bottom:1.35em;}
.prose p:last-child{margin-bottom:0;}
.prose h3{
  font-size:clamp(21px,2.6vw,28px);
  margin:2em 0 0.7em;
}
.prose strong{font-weight:600;}

/* The one oversize statement per page.
   Previously an italic serif behind a 2px border-left, which is the banned side-stripe
   pattern and also the editorial-typographic tell. It carries itself on size and weight
   now, with space instead of a container. */
.pull{
  font-size:clamp(27px,4vw,46px);
  font-weight:700;
  line-height:1.1;
  letter-spacing:-0.032em;
  max-width:18ch;
  color:var(--ink);
}

/* ---------- case notes: proof set as listing entries ---------- */
.notes{border-top:var(--rule) solid var(--ink);}
.note{
  padding:clamp(30px,4vw,46px) 0;
  border-bottom:var(--rule) solid var(--accent-1);
  display:grid;grid-template-columns:1fr;gap:14px 40px;
}
@media(min-width:820px){
  .note{grid-template-columns:88px 1fr;gap:0 48px;}
}
.note-no{
  font-family:'Familjen Grotesk',ui-sans-serif,system-ui,sans-serif;
  font-size:clamp(26px,3vw,36px);font-weight:700;letter-spacing:-0.03em;
  line-height:1;color:var(--accent);
}
.note-body{max-width:62ch;}
.note-body h3{font-size:clamp(21px,2.5vw,27px);margin-bottom:0.6em;}
.note-body p{margin-bottom:1.15em;color:var(--ink-2);}
.note-body p:last-of-type{margin-bottom:0;}
/* the compliance qualifier, styled as a detail line so it reads as design
   rather than as small print bolted on at the end */
.note-qual{
  margin-top:20px;padding-top:16px;
  border-top:var(--rule) solid var(--accent-1);
  font-size:12.5px;line-height:1.6;color:var(--ink-3);
  max-width:56ch;
}

/* ---------- who I work with: a list, not a card grid ---------- */
.who{border-top:var(--rule) solid var(--ink);max-width:var(--measure);}
.who div{
  padding:24px 0;border-bottom:var(--rule) solid var(--accent-1);
  display:grid;grid-template-columns:1fr;gap:6px;
}
@media(min-width:700px){.who div{grid-template-columns:0.8fr 1.2fr;gap:0 40px;align-items:baseline;}}
.who h3{font-size:clamp(19px,2.1vw,23px);}
.who p{color:var(--ink-2);font-size:16px;}

/* ---------- the dark plate: exactly one per page ---------- */
.cta{
  background:var(--accent-2);
  color:var(--paper);
  padding:clamp(52px,7vw,96px) 0;
}
.cta h2{font-size:clamp(28px,4.2vw,46px);max-width:17ch;}
.cta p{margin-top:20px;color:oklch(0.93 0.018 155);max-width:46ch;font-size:17.5px;}
.cta-acts{display:flex;flex-wrap:wrap;gap:14px;margin-top:32px;}
/* max-width:none is load-bearing: .detail is a <p>, so without it the 46ch measure
   above applies and the line wraps, stranding a separator dot. */
.cta .detail{margin-top:36px;padding-top:22px;max-width:none;border-top:1px solid oklch(0.40 0.070 155);color:oklch(0.80 0.030 155);}
.cta .detail > span:not(:last-child)::after{background:oklch(0.80 0.030 155);}

/* ---------- footer ---------- */
.foot{padding:clamp(40px,5vw,64px) 0 32px;border-top:var(--rule) solid var(--accent-1);}
.foot-grid{display:grid;grid-template-columns:1fr;gap:32px;}
@media(min-width:760px){.foot-grid{grid-template-columns:1.4fr 1fr 1fr;gap:40px;}}
.foot h4{
  font-size:11px;font-weight:600;letter-spacing:0.2em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:14px;
}
.foot a{display:block;padding:6px 0;font-size:15.5px;color:var(--ink-2);}
@media(hover:hover){.foot a:hover{color:var(--ink);}}
.foot-brand p{margin-top:14px;color:var(--ink-2);font-size:15.5px;max-width:38ch;}

/* The compliance strip is a legal requirement, so it is designed rather than hidden.
   CR and ACL numbers must appear in full on every page. */
.compliance{
  margin-top:clamp(36px,4.5vw,56px);
  padding-top:22px;
  border-top:var(--rule) solid var(--accent-1);
}
.compliance p{
  margin-top:14px;font-size:12.5px;line-height:1.7;color:var(--ink-3);max-width:78ch;
}

/* ---------- reveal ---------- */
.rise{opacity:0;transform:translateY(12px);}
.js .rise{transition:opacity .5s var(--ease),transform .5s var(--ease);}
.rise.in{opacity:1;transform:none;}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important;}
  .rise{opacity:1;transform:none;}
  html{scroll-behavior:auto;}
}

/* ============================================================
   CRAFT PASS — 9 Aug 2026
   The first build was correct but thin: section headings sat too close to body
   size, the who-I-work-with list read as a plain table, and the only motion was a
   single fade. Everything below raises presence without adding a second colour or
   a second family. Scale, weight and timing only.
   ============================================================ */

/* ---------- stronger section hierarchy ----------
   The h1 rule is load-bearing. Service pages put their h1 inside .sec-head, so when only
   .sec-head h2 was sized the page title rendered smaller than the section headings below
   it and the hierarchy read backwards. h1 stays a step above h2. */
.sec-head h1{
  font-size:clamp(36px,6.2vw,68px);
  letter-spacing:-0.038em;
  max-width:16ch;
}
.sec-head h2{
  font-size:clamp(32px,5.4vw,60px);
  letter-spacing:-0.035em;
  max-width:17ch;
}
.sec-head p{font-size:18px;max-width:52ch;}

/* The label now carries a rule that draws itself in, which is the campaign-board
   move: a line struck under the section number before the heading lands. */
.sec-label{
  display:flex;align-items:center;gap:14px;
  margin-bottom:20px;
}
.sec-label::after{
  content:'';flex:1;height:1px;background:var(--accent);
  transform:scaleX(0);transform-origin:left;
  transition:transform .8s var(--ease) .1s;
}
.rise.in .sec-label::after,.sec-head.in .sec-label::after{transform:scaleX(1);}

/* ---------- who I work with: a schedule, not a table ---------- */
.who div{
  padding:30px 0;
  align-items:start;
  transition:background .3s var(--ease);
  position:relative;
}
.who div::before{
  content:'';position:absolute;left:calc(var(--gut) * -0.5);top:30px;
  width:0;height:1px;background:var(--accent);
  transition:width .4s var(--ease);
}
.who h3{
  font-size:clamp(21px,2.6vw,27px);
  letter-spacing:-0.025em;
  transition:transform .3s var(--ease);
}
.who p{font-size:16.5px;max-width:48ch;}
@media(hover:hover){
  .who div:hover h3{transform:translateX(10px);}
  .who div:hover::before{width:calc(var(--gut) * 0.5 - 4px);}
}

/* ---------- case notes with more presence ---------- */
.note-no{
  font-size:clamp(30px,3.6vw,46px);
  letter-spacing:-0.04em;
}
.note-body h3{
  font-size:clamp(22px,2.8vw,30px);
  letter-spacing:-0.028em;
}
.note-body p{font-size:16.5px;}

/* ---------- hero entrance choreography ----------
   Runs on load rather than on scroll, because the hero is above the fold and an
   IntersectionObserver would either fire instantly or not at all. Children step in
   on a shared curve so the whole block reads as one movement. */
.js .hero-step{opacity:0;transform:translateY(14px);}
.js .hero-lit .hero-step{
  animation:step .75s var(--ease) forwards;
  animation-delay:calc(var(--s,0) * 90ms);
}
@keyframes step{to{opacity:1;transform:none;}}

/* The portrait is unveiled rather than faded: a campaign board going up.
   clip-path is composited, so this does not animate a layout property. */
/* The unveil is NOT gated on .hero-lit. It used to be, and it hid the portrait entirely on
   /about/ and /contact/: those pages use class="hero-sub", main.js only looked for ".hero",
   so hero-lit was never added, the clip-path stayed at inset(0 0 100% 0) and the image was
   invisible while still returning 200. A reveal that can leave content permanently hidden
   when one class goes missing is not worth the choreography. This one runs on its own. */
.js .portrait img{
  clip-path:inset(0 0 100% 0);
  animation:unveil 1s var(--ease) .18s forwards;
}
@keyframes unveil{to{clip-path:inset(0 0 0 0);}}

/* ---------- staggered reveal for grouped items ----------
   main.js sets --i per item within its own group, so a four-row list steps in
   rather than all four landing together. */
.js .rise{transition-delay:calc(var(--i,0) * 80ms);}

/* ---------- link and button polish ---------- */
/* Hover wipes the accent up from the bottom edge.
   Done with a background layer rather than an ::after: a pseudo-element needs
   z-index:-1 to sit under the label, which puts it behind the button's own
   background colour and makes it invisible. background-size is composited and is
   not a layout property, so this is safe to animate. */
.plate{
  background-image:linear-gradient(var(--accent-2),var(--accent-2));
  background-repeat:no-repeat;
  background-size:100% 0%;
  background-position:0 100%;
  transition:background-size .34s var(--ease),background-color .2s var(--ease),color .2s var(--ease);
}
.plate-ghost{background-image:linear-gradient(var(--ink),var(--ink));}
.plate-light{background-image:linear-gradient(var(--accent-1),var(--accent-1));}
@media(hover:hover){
  .plate:hover{background-size:100% 100%;}
  .plate-ghost:hover{color:var(--paper);}
}

.mast-nav a{position:relative;}
.mast-nav a::after{
  content:'';position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--accent);
  transform:scaleX(0);transform-origin:right;
  transition:transform .3s var(--ease);
}
@media(hover:hover){
  .mast-nav a:hover::after{transform:scaleX(1);transform-origin:left;}
  .mast-nav a:hover{border-bottom-color:transparent;}
}

/* ---------- the closing plate earns a little more ---------- */
.cta h2{font-size:clamp(32px,5vw,56px);letter-spacing:-0.035em;}
.cta p{font-size:18px;}

@media(prefers-reduced-motion:reduce){
  .js .hero-step,.js .hero-lit .hero-step{opacity:1;transform:none;animation:none;}
  .js .portrait img,.js .hero-lit .portrait img{clip-path:none;animation:none;}
  .sec-label::after{transform:scaleX(1);transition:none;}
  .js .rise{transition-delay:0ms;}
}

/* ---------- page head: two columns, so the top band is not half empty ----------
   Service pages had a left column of type against a dead right half. The homepage and
   about page fill that side with the portrait; repeating the portrait on every service
   page would be heavy handed and it is the same two photographs. So the right column
   carries an at-a-glance panel instead: the four things a stranger wants settled before
   they ring, which is substance rather than something decorative to plug a hole. */
/* align-items:start, not end. Bottom-aligning the two columns made the top edges drift:
   the headline is four lines on home-loans and three on refinancing, so the at-a-glance
   panel floated ~70px above the section label on the shorter page and read as a mistake.
   The reader scans top edges first, and the labels are the anchor. Tops must line up. */
.head-grid{
  display:grid;grid-template-columns:1fr;
  gap:clamp(32px,4vw,56px);align-items:start;
}
@media(min-width:900px){
  .head-grid{grid-template-columns:1.12fr 0.88fr;gap:clamp(44px,5vw,80px);}
}
.head-grid .sec-head{margin-bottom:clamp(24px,3vw,34px);}
/* .sec-label carries margin-top:18px everywhere else, which is right when it follows other
   content. Here it is the first thing in the column, so that margin pushed the section label
   18px below "At a glance" in the next column and the two heads never lined up. Measured, not
   guessed: both column boxes start at the same y, only the label's own margin differed. */
.head-grid .sec-label{margin-top:0;}

.facts{border-top:1px solid var(--ink);}
.facts > div{
  display:grid;grid-template-columns:1fr;gap:2px;
  padding:15px 0;border-bottom:var(--rule) solid var(--accent-1);
}
@media(min-width:520px){
  .facts > div{grid-template-columns:9rem 1fr;gap:0 22px;align-items:baseline;}
}
.facts dt{
  font-size:11px;font-weight:600;letter-spacing:0.16em;text-transform:uppercase;
  color:var(--ink-3);
}
.facts dd{font-size:15.5px;line-height:1.6;color:var(--ink-2);}
.facts dd strong{color:var(--ink);font-weight:600;}

/* ---------- duo: heading left, body right ----------
   Prose sections used to stack a heading above a 66ch column, both hard left, which left
   the right half of every band empty down the whole page. Splitting them puts the heading
   and the body side by side: still left aligned, still a comfortable measure, but the
   band is used. Below 980px it stacks back, because a 66ch measure in half of a tablet
   width is not a measure any more. */
.duo{
  display:grid;grid-template-columns:1fr;
  gap:clamp(20px,3vw,36px);
}
@media(min-width:980px){
  .duo{grid-template-columns:0.85fr 1.15fr;gap:clamp(40px,5vw,88px);align-items:start;}
  .duo > .sec-head{margin-bottom:0;}
  .duo > .sec-head h2{max-width:14ch;}
}
.duo .prose{max-width:62ch;}
.duo .pull{margin-top:clamp(30px,3.5vw,44px);}

/* The schedule spans the full band rather than sitting in a 66ch column with nothing
   beside it. Its own two-column rows give it internal structure at this width. */
.who{max-width:none;}
@media(min-width:980px){
  .who div{grid-template-columns:0.62fr 1.38fr;gap:0 clamp(32px,4vw,64px);}
  .who p{max-width:62ch;}
}

/* The closing plate follows the same duo rule: heading left, the ask and the buttons
   right. It was the last band running hard left against an empty half. */
@media(min-width:980px){
  .cta-duo{align-items:end;}
  .cta-duo > h2{max-width:12ch;margin-bottom:0;}
}
.cta-duo p{margin-top:0;}
