/* ============================================================
   TOKENS: inherited from the Almost a Lab design system
   ============================================================ */
:root{
  color-scheme: dark;
  --bg:#0a0a0a;
  --surface:#101014;
  --raised:#17171c;
  --text:#f0f0f0;
  --muted:#9a9aa4;          /* 7.1:1 on --bg */
  --accent:#d1ff4c;         /* 17.1:1 on --bg */
  --accent-hover:#dcff70;
  --on-accent:#0a0a0a;      /* text on lime */
  --text-strong:#fff;
  --danger:#ff8a80;         /* 8.3:1 on --surface */
  --scrollbar:#2a2a30;
  --line:rgba(240,240,240,.10);
  --line-strong:rgba(240,240,240,.20);

  --display:"Bricolage Grotesque",system-ui,sans-serif;
  --sans:"Inter",system-ui,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,monospace;

  --r-sm:8px; --r-md:14px; --r-lg:20px;   /* concentric: inner = outer - padding */
  --ease:cubic-bezier(.16,1,.3,1);
  --pad:clamp(20px,5vw,40px);
  --card-pad:clamp(20px,3.2vw,26px);   /* one inset for every bordered card */
  /* Type ramp beyond the named roles (see DESIGN.md Typography). Anything smaller
     than --fs-label breaks the 12px floor. */
  --fs-label:.75rem;                          /* 12px: years, numbers, captions */
  --fs-sm:.875rem;                            /* 14px: card copy, captions, notes */
  --fs-md:.95rem;                             /* 15.2px: secondary prose, buttons */
  --fs-title-lg:clamp(1.2rem,3.2vw,1.5rem);   /* large card titles */
  --fs-statement:clamp(1.7rem,5.4vw,2.7rem);  /* footer line, menu pages */
  /* Tracking tightens as size grows, one step per role (see DESIGN.md). */
  --track-display:-.045em;     /* the name */
  --track-statement:-.03em;    /* footer line, menu pages */
  --track-title:-.02em;        /* section titles and every card or row title */
  --track-label:.01em;         /* small Inter labels */
  --track-mono:.08em;          /* JetBrains Mono labels and numbers */
}

*,*::before,*::after{box-sizing:border-box}
/* The UA's `[hidden]{display:none}` is not an author rule, so any author
   `display:` beats it. That silently unhid the brief dialog's success panel,
   which put an "Open the calendar" button on screen before the form was
   submitted. Make hidden mean hidden. */
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:var(--sans); font-size:16px; line-height:1.6;
  overflow-wrap:break-word; /* long URLs and the email break at 200% text instead of widening the page */
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}
img{max-width:100%; height:auto; display:block}
a{color:inherit; text-decoration:none}

/* Grain + lime bloom, purely decorative */
body{position:relative}
body::before{
  content:""; position:absolute; top:0; left:0; right:0; height:min(1100px,120vh);
  z-index:0; pointer-events:none;
  background:
    radial-gradient(70ch 50ch at 78% -8%, color-mix(in srgb,var(--accent) 10%,transparent), transparent 62%),
    radial-gradient(50ch 40ch at 4% 4%, color-mix(in srgb,var(--accent) 4.5%,transparent), transparent 60%);
}

/* flow-root keeps the header's top margin inside the wrapper. Without it the
   margin collapsed through body, moved the body (and its lime bloom) 10px down,
   and left a bare black strip across the top of the screen. */
.wrap{display:flow-root; position:relative; z-index:1; max-width:940px; margin:0 auto;
  padding:0 max(var(--pad), env(safe-area-inset-left)) 0 max(var(--pad), env(safe-area-inset-right))}

/* Focus: visible on every interactive element */
a:focus-visible,button:focus-visible{
  outline:2px solid var(--accent); outline-offset:3px; border-radius:var(--r-sm);
}

/* ============================================================
   SECTION HEADS
   ============================================================ */
.sec{padding:clamp(52px,9vw,88px) 0; border-top:1px solid var(--line)}
.sec-head{display:flex; align-items:baseline; gap:14px; margin-bottom:26px; flex-wrap:wrap}
.sec-head h2{
  font-family:var(--display); font-size:clamp(1.4rem,3.4vw,1.9rem);
  font-weight:600; letter-spacing:var(--track-title); margin:0;
}
.sec-num{
  font-family:var(--mono); font-size:var(--fs-label); color:var(--accent);
  letter-spacing:var(--track-mono); font-variant-numeric:tabular-nums;
}
.sec-note{font-family:var(--sans); font-size:var(--fs-label); color:var(--muted); letter-spacing:var(--track-label); margin-left:auto; font-weight:500}

/* ============================================================
   HERO
   ============================================================ */
.hero{padding:clamp(30px,7vw,58px) 0 clamp(44px,7vw,72px)}
.topbar{display:flex; align-items:center; justify-content:space-between; gap:16px;
  padding:12px 0; margin:10px 0 calc(clamp(34px,7vw,66px) - 12px)}
/* Header that comes back when you want it. At rest and while scrolling down it
   is an ordinary block that scrolls away with the page. Scroll up once it has
   left the screen and it slides in pinned (.pinned, set by site.js); scrolling
   down slides it out again, and at the very top it lets go and sits in its
   natural place. It is never pinned over the hero while you read down, which
   is what made the first version flash a bar across the portrait.
   The full-bleed backing is a spread box-shadow clipped to the bar's height:
   it reaches the screen edges without adding horizontal scroll. Opaque,
   because any translucency let body text ghost through in WebKit. */
.topbar{position:relative; z-index:50; transition:transform .32s var(--ease)}
.topbar.pinned{
  position:sticky; top:0;
  background-color:var(--bg); box-shadow:0 0 0 100vmax var(--bg), 0 1px 0 100vmax var(--line);
  clip-path:inset(0 -100vmax -1px);
  animation:bar-in .32s var(--ease)}
.topbar.pinned.hide{transform:translateY(calc(-100% - 12px))}
@keyframes bar-in{from{transform:translateY(calc(-100% - 12px))}}
@media(prefers-reduced-motion:reduce){ .topbar{transition:none} .topbar.pinned{animation:none} }
/* The monogram alone is the mark; the link is named by its aria-label. 44px
   square keeps the home target tappable now that it has no text beside it. */
.mark{display:flex; align-items:center; min-height:44px; min-width:44px}
.mark img{width:28px; height:auto; filter:invert(1)}

.status{display:inline-flex; align-items:center; gap:8px; font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); color:var(--muted); white-space:nowrap; font-weight:500}
/* Below this the status pill and the menu button fight for the same row and the
   text wraps into itself. It reappears inside the menu instead. */
@media(max-width:719px){ .topbar .status{display:none} }
.menu-status{display:none; align-items:center; gap:8px; margin-bottom:22px;
  font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); color:var(--muted); font-weight:500}
@media(max-width:719px){ .menu-status{display:inline-flex} }
.dot{width:6px; height:6px; border-radius:50%; background:var(--accent); box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 50%,transparent); animation:pulse 2.6s infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 45%,transparent)}70%{box-shadow:0 0 0 7px color-mix(in srgb,var(--accent) 0%,transparent)}100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--accent) 0%,transparent)}}

.hero-grid{display:grid; grid-template-columns:1fr; gap:clamp(28px,5vw,52px); align-items:center}
@media(min-width:820px){.hero-grid{grid-template-columns:1.12fr .88fr}}

.eyebrow{font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); color:var(--accent); margin:0 0 16px; font-weight:500}
h1{
  font-family:var(--display); font-weight:700;
  font-size:clamp(3.1rem,11.5vw,6.4rem); line-height:.92; letter-spacing:var(--track-display);
  margin:0 0 20px;
}
/* A single unbreakable word ("Braeden") at 200% text size came out 379px wide
   on a 375px phone. Capping the floor by viewport keeps it inside the screen;
   at default text size min() still picks 3.1rem, so nothing changes there. */
h1{font-size:clamp(min(3.1rem,20vw),11.5vw,6.4rem)}
h1 .ln{display:block; overflow:hidden; padding-bottom:.04em}
h1 .ln > i{display:block; font-style:normal}
/* Masked line reveal: cancel the generic fade, slide each line up instead */
.js h1.rv{opacity:1; transform:none}
.js h1.rv .ln > i{transform:translateY(104%)}
.js h1.rv.in .ln > i{transform:none; transition:transform .85s var(--ease)}
.js h1.rv.in .ln:nth-child(2) > i{transition-delay:.09s}
.role{font-size:clamp(1.02rem,2.4vw,1.22rem); color:var(--text); margin:0 0 10px; font-weight:500}
.role b{color:var(--accent); font-weight:600}
.bio{color:var(--muted); max-width:46ch; margin:0 0 16px; font-size:1rem}

.chips{display:flex; flex-wrap:wrap; gap:10px}
.chip{
  display:inline-flex; align-items:center; gap:9px;
  min-height:46px; padding:0 17px; border-radius:999px;
  border:1px solid var(--line-strong); background:var(--surface);
  font-size:var(--fs-sm); font-weight:500; cursor:pointer;
  transition:background .22s var(--ease), border-color .22s var(--ease), color .22s var(--ease), transform .12s var(--ease);
}
.chip svg{width:16px; height:16px; flex:none}
@media (hover:hover){ .chip:hover{background:var(--raised); border-color:var(--line-strong); color:var(--text-strong)} }
.chip:active{transform:scale(.96)}
.chip.primary{background:var(--accent); color:var(--on-accent); border-color:var(--accent); font-weight:600}
@media (hover:hover){ .chip.primary:hover{background:var(--accent-hover); color:var(--on-accent)} }

.portrait{position:relative; border-radius:var(--r-lg); overflow:hidden; box-shadow:inset 0 0 0 1px var(--line)}
.portrait img{width:100%; aspect-ratio:4/5; object-fit:cover; object-position:50% 12%; filter:grayscale(1) contrast(1.06)}
/* Portrait swap, mirroring the Almost Impossible team page: two stacked frames
   cross-fading on opacity, both desaturated. A mouse swaps on hover; touch
   swaps on tap (.swap, set by site.js), and plays it once after load so the
   gesture is discoverable. The second frame is attached after window load, so
   it never competes with the LCP portrait. */
.p-alt{
  position:absolute; inset:0; opacity:0;
  background:50% 12%/cover no-repeat;
  filter:grayscale(1) contrast(1.06);
  transition:opacity .5s cubic-bezier(.4,0,.2,1);
}
.p-ready .p-alt{background-image:url("/assets/hero-portrait-hover-2d537447.jpg")}
.portrait.swap .p-alt{opacity:1}
@media (hover:hover) and (pointer:fine){
  /* Without JS a mouse can still hover it, so attach it straight away there */
  html:not(.js) .p-alt{background-image:url("/assets/hero-portrait-hover-2d537447.jpg")}
  .portrait:hover .p-alt{opacity:1}
}
@media (hover:none){ .portrait{cursor:pointer; -webkit-tap-highlight-color:transparent} }
@media(prefers-reduced-motion:reduce){ .p-alt{transition:none} }
.portrait::after{content:""; position:absolute; inset:0; background:linear-gradient(180deg,transparent 55%,color-mix(in srgb,var(--bg) 55%,transparent))}
@media(max-width:819px){
  /* Cap the width too, or the square grows with the column: at 819px it hit
     739x739 and pushed the link index 1.42 viewports down, which is the exact
     scroll cost the 1:1 crop below was chosen to avoid. Phones are unaffected
     (the portrait is 335px at 375px wide), so this only bites the tablet band. */
  .portrait{border-radius:var(--r-md); max-width:420px}
  /* Square, not 4:3. The source is a 4:5 portrait, so a landscape frame left
     dead black either side and shrank the face. Full 4:5 would be truest but
     adds ~400px of scroll between the CTAs and the link index, which is the one
     thing a link-in-bio cannot afford on its primary surface. */
  .portrait img{aspect-ratio:1/1}
}

/* ============================================================
   VENTURES
   ============================================================ */
.ventures{display:grid; grid-template-columns:1fr; gap:14px}
@media(min-width:760px){.ventures{grid-template-columns:1fr 1fr}}
.venture{
  position:relative; display:flex; flex-direction:column; gap:12px;
  padding:var(--card-pad); border:1px solid var(--line); border-radius:var(--r-lg);
  background:var(--surface); overflow:hidden; cursor:pointer;
  transition:border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}
@media (hover:hover){ .venture:hover{border-color:color-mix(in srgb,var(--accent) 42%,transparent); background:var(--raised); transform:translateY(-3px)} }
.venture:active{transform:translateY(-1px) scale(.995)}
.v-top{display:flex; align-items:center; justify-content:space-between; gap:12px}
.v-tag{font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); color:var(--accent); border:1px solid color-mix(in srgb,var(--accent) 30%,transparent); padding:4px 9px; border-radius:999px; font-weight:500}
.v-name{font-family:var(--display); font-size:var(--fs-title-lg); font-weight:600; letter-spacing:var(--track-title); margin:0}
.v-desc{color:var(--muted); font-size:var(--fs-md); margin:0; line-height:1.55}
.v-meta{font-family:var(--sans); font-size:var(--fs-label); color:var(--muted); letter-spacing:var(--track-label); margin-top:2px; font-weight:500}
.arrow{width:19px; height:19px; color:var(--muted); flex:none; transition:transform .3s var(--ease), color .3s var(--ease)}
@media (hover:hover){ .venture:hover .arrow{transform:translate(3px,-3px); color:var(--accent)} }

/* ============================================================
   LINK INDEX: the signature lime wipe
   ============================================================ */
.rows{border-top:1px solid var(--line)}
.row{
  position:relative; display:flex; align-items:center; gap:16px;
  min-height:64px; padding:16px 18px; border-bottom:1px solid var(--line);
  overflow:hidden; cursor:pointer; isolation:isolate;
}
.row::before{
  content:""; position:absolute; inset:0; background:var(--accent); z-index:-1;
  transform:scaleX(0); transform-origin:left;
  transition:transform .44s var(--ease);
}
.row:focus-visible::before{transform:scaleX(1)}
@media (hover:hover){ .row:hover::before{transform:scaleX(1)} }
.row:focus-visible{outline:2px solid var(--bg); outline-offset:-3px}
.r-num{
  font-family:var(--mono); font-size:var(--fs-label); color:var(--muted);
  font-variant-numeric:tabular-nums; flex:none; width:26px;
  transition:color .3s var(--ease);
}
.r-icon{width:19px; height:19px; flex:none; color:var(--muted); transition:color .3s var(--ease)}
.r-label{font-size:1.02rem; font-weight:500; transition:color .3s var(--ease)}
.r-val{
  margin-left:auto; font-family:var(--mono); font-size:var(--fs-label); color:var(--muted);
  transition:color .3s var(--ease); white-space:nowrap;
  overflow:hidden; text-overflow:ellipsis; max-width:42vw;
}
.r-go{width:16px; height:16px; flex:none; color:var(--muted); transition:transform .3s var(--ease), color .3s var(--ease)}
.row:focus-visible .r-num,.row:focus-visible .r-icon,.row:focus-visible .r-label,
.row:focus-visible .r-val,.row:focus-visible .r-go{color:var(--bg)}
@media (hover:hover){ .row:hover .r-num,.row:hover .r-icon,.row:hover .r-label,.row:hover .r-val,.row:hover .r-go{color:var(--bg)} }
.row:focus-visible .r-go{transform:translateX(3px)}
@media (hover:hover){ .row:hover .r-go{transform:translateX(3px)} }
.row{transition:transform .12s var(--ease)}
.row:active{transform:scale(.994)}
@media(max-width:560px){ .r-val{display:none} .r-label{flex:1} }

/* ============================================================
   PRESS
   ============================================================ */
.press{display:grid; gap:12px}
.item{
  display:flex; align-items:flex-start; gap:18px;
  padding:var(--card-pad); border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--surface); cursor:pointer;
  transition:border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}
@media (hover:hover){ .item:hover{border-color:color-mix(in srgb,var(--accent) 40%,transparent); background:var(--raised); transform:translateX(4px)} }
.item:active{transform:translateX(2px) scale(.995)}
.i-year{font-family:var(--mono); font-size:var(--fs-label); color:var(--accent); flex:none; padding-top:3px; font-variant-numeric:tabular-nums}
.i-body{flex:1; min-width:0}
.i-outlet{font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); color:var(--muted); display:block; margin-bottom:6px; font-weight:500}
.i-title{font-size:1rem; font-weight:500; margin:0 0 5px; line-height:1.42}
.i-sub{font-size:var(--fs-sm); color:var(--muted); margin:0; max-width:52ch}   /* ch undercounts Inter: 52ch is ~75 characters */
.item .arrow{align-self:center}

/* ============================================================
   CLIENT LOGO WALL
   ============================================================ */
.logos{padding:6px 0 0; display:flex; flex-direction:column; align-items:center; gap:clamp(18px,3.4vw,34px)}
/* Measured, not calculated. The artwork's own maximum alpha is about .44, so
   the filter never produces white: at opacity(.42) the brightest logo pixel
   rendered at 53 on a bg of 10, which is 1.6:1, under the 3:1 floor for
   meaningful non-text content. The .72 hover lift was the only thing that ever
   cleared it, and a phone has no hover. .85 measures 3.2:1, and the wall still
   sits far below the 17:1 body text. */
.logos img{
  height:auto;
  filter:brightness(0) invert(1) opacity(.85);
  transition:filter .45s var(--ease);
}
.logos .lr1{width:100%}
.logos .lr2{width:56%}
@media (hover:hover){ .logos:hover img{filter:brightness(0) invert(1) opacity(1)} }
@media(max-width:560px){ .logos{gap:16px} .logos .lr2{width:72%} }

/* ============================================================
   FOOTER
   ============================================================ */
footer{border-top:1px solid var(--line); padding:clamp(44px,7vw,64px) 0 46px}
.f-cta{font-family:var(--display); font-size:var(--fs-statement); font-weight:600; letter-spacing:var(--track-statement); line-height:1.1; margin:0 0 12px; max-width:15ch; text-wrap:balance}
/* 15ch is 270px on a phone, narrow enough that balance broke the line into four
   and stranded "almost" on its own. 17ch is still inside the column and holds
   it to three. */
@media(max-width:560px){ .f-cta{max-width:17ch} }
/* inline-block + padding gives a 44px tap target; the negative margin keeps
   the text where it was, and the underline is redrawn at the old baseline. */
.f-cta a{position:relative; display:inline-block; padding:8px 0; margin:-8px 0; transition:color .25s var(--ease)}
.f-cta a::after{content:""; position:absolute; left:0; right:0; bottom:8px; height:2px;
  background:color-mix(in srgb,var(--accent) 35%,transparent); transition:background .25s var(--ease)}
@media (hover:hover){ .f-cta a:hover{color:var(--accent)} }
@media (hover:hover){ .f-cta a:hover::after{background:var(--accent)} }
.f-sub{color:var(--muted); margin:0 0 32px; max-width:44ch}
.f-bot{display:flex; justify-content:space-between; align-items:center; gap:16px; flex-wrap:wrap;
  font-family:var(--mono); font-size:var(--fs-label); color:var(--muted); letter-spacing:var(--track-mono)}
.f-bot a{display:inline-flex; align-items:center; min-height:44px}
@media (hover:hover){ .f-bot a:hover{color:var(--accent)} }

/* ============================================================
   ENTRANCE: only applied when JS is present
   ============================================================ */
.js .rv{opacity:0; transform:translateY(16px)}
.js .rv.in{opacity:1; transform:none; transition:opacity .7s var(--ease), transform .7s var(--ease)}
.js .rv.in{transition-delay:var(--d,0ms)}

/* ============================================================
   CREDENTIALS GRID (speaking, teaching, advising)
   ============================================================ */
.creds{display:grid; grid-template-columns:1fr; gap:12px}
@media(min-width:600px){
  .creds{grid-template-columns:1fr 1fr}
  /* five cards in two columns leaves the last one beside a hole */
  .creds > :last-child:nth-child(odd){grid-column:1 / -1}
}
@media(min-width:900px){
  .creds{grid-template-columns:repeat(3,1fr)}
  .creds > :last-child:nth-child(odd){grid-column:auto}
  /* and in three columns the fifth card leaves the hole instead */
  .creds > :last-child:nth-child(3n+2){grid-column:span 2}
}

/* ============================================================
   PRINCIPLES: how I work
   ============================================================ */
.principles{display:grid; grid-template-columns:1fr; gap:0}
@media(min-width:760px){.principles{grid-template-columns:repeat(3,1fr); gap:0}}
.pr{padding:22px 0 22px 20px; border-top:1px solid var(--line); border-left:2px solid var(--accent)}
@media(min-width:760px){
  .pr{border-top:0; border-left:2px solid var(--accent); padding:4px 26px 4px 20px}
}
.pr h3{
  font-family:var(--display); font-size:var(--fs-title-lg); font-weight:600;
  letter-spacing:var(--track-title); margin:0 0 8px; text-wrap:balance;
}
.pr p{color:var(--muted); font-size:var(--fs-sm); margin:0; line-height:1.55}
.cred{
  padding:var(--card-pad); border:1px solid var(--line); border-radius:var(--r-md);
  background:var(--surface); transition:border-color .3s var(--ease), background .3s var(--ease);
}
/* No :hover here. Every card on this site that lights its border lime on hover
   (.feat, .venture, .bridge) is a link; these are plain divs with nowhere to go,
   so the same treatment promised a click that does nothing. */
.c-tag{font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); color:var(--accent); display:block; margin-bottom:10px; font-weight:500}
.c-title{font-family:var(--display); font-size:1.02rem; font-weight:600; letter-spacing:var(--track-title); margin:0 0 5px; text-wrap:balance}
/* No min-height. It reserved a second line to align titles across the row, but
   every title is one line, so all it produced was ~28px of dead air under each. */
.c-sub{font-size:var(--fs-sm); color:var(--muted); margin:0; line-height:1.5}

/* Location strip */
.places{display:flex; flex-wrap:wrap; align-items:center; gap:8px 14px; margin:0 0 18px;
  font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); font-weight:500; color:var(--muted)}
/* The separator leads the word it belongs to rather than being its own flex
   item, so a wrap can never strand a slash at the end of a line. It did on a
   375px screen: "BARCELONA /" then "SERVING EMEA". */
.places span + span::before{content:"/"; color:var(--accent); margin-right:14px}

/* ============================================================
   PRIVATE FLAG banner (injected server-side by functions/_middleware.js)
   ============================================================ */
.private-flag{
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  padding:13px 18px; border-bottom:1px solid var(--line);
  background:color-mix(in srgb,var(--accent) 5%,transparent);
  font-size:var(--fs-sm); color:var(--muted);
}
.pf-tag{
  font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); font-weight:500; color:var(--accent);
  border:1px solid color-mix(in srgb,var(--accent) 35%,transparent); padding:4px 9px; border-radius:999px; flex:none;
}

/* ============================================================
   FEATURED LINKS  (add a card by copying one <a class="feat">)
   ============================================================ */
.feats{display:grid; grid-template-columns:1fr; gap:12px}
@media(min-width:680px){
  .feats{grid-template-columns:1fr 1fr}
  /* an odd final card would otherwise sit alone beside dead space */
  .feats > :last-child:nth-child(odd){grid-column:1 / -1}
}
.feat{
  position:relative; display:flex; flex-direction:column; gap:9px; padding:var(--card-pad);
  border:1px solid var(--line); border-radius:var(--r-md); background:var(--surface);
  cursor:pointer; overflow:hidden;
  transition:border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}
@media (hover:hover){ .feat:hover{border-color:color-mix(in srgb,var(--accent) 42%,transparent); background:var(--raised); transform:translateY(-3px)} }
.feat:active{transform:translateY(-1px) scale(.995)}
.f-top{display:flex; align-items:center; justify-content:space-between; gap:12px}
.f-kind{font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); color:var(--accent); font-weight:500}
.f-title{font-family:var(--display); font-size:1.1rem; font-weight:600; letter-spacing:var(--track-title); margin:0; text-wrap:balance}
.f-desc{color:var(--muted); font-size:var(--fs-sm); margin:0; line-height:1.55}
/* margin-top:auto pins the source to the card floor. Without it a short
   description floated it up: in row one the two source lines sat 45px apart. */
.f-src{font-family:var(--mono); font-size:var(--fs-label); color:var(--muted); letter-spacing:var(--track-mono); margin-top:auto; padding-top:2px}

/* ============================================================
   ABOUT
   ============================================================ */
.about{max-width:64ch}
.about p{color:var(--muted); font-size:1.02rem; line-height:1.72; margin:0 0 18px}
.about p:last-child{margin-bottom:0}
.about strong{color:var(--text); font-weight:600}
.about a{color:var(--accent); border-bottom:1px solid color-mix(in srgb,var(--accent) 30%,transparent); transition:border-color .2s var(--ease)}
@media (hover:hover){ .about a:hover{border-color:var(--accent)} }

/* ============================================================
   AWARDS
   ============================================================ */
.awards{border-top:1px solid var(--line)}
.aw{display:flex; align-items:baseline; gap:18px; padding:17px 4px; border-bottom:1px solid var(--line); flex-wrap:wrap}
.aw-year{font-family:var(--mono); font-size:var(--fs-label); color:var(--accent); font-variant-numeric:tabular-nums; flex:none; width:44px}
.aw-body{flex:1; min-width:220px}
.aw-name{font-size:1rem; font-weight:500; margin:0 0 3px; color:var(--text)}
.aw-org{font-family:var(--sans); font-size:var(--fs-label); color:var(--muted); letter-spacing:var(--track-label); font-weight:500}
.aw-rank{
  font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); flex:none;
  padding:4px 10px; border-radius:999px; border:1px solid var(--line-strong); color:var(--muted);
; font-weight:500}
.aw-rank.gold{color:var(--accent); border-color:color-mix(in srgb,var(--accent) 40%,transparent)}
@media(max-width:560px){ .aw-year{width:100%} .aw-rank{margin-top:4px; max-width:100%} }

/* ============================================================
   FAQ  (native details, so answers stay in the HTML for crawlers)
   ============================================================ */
.faq{border-top:1px solid var(--line)}
.qa{border-bottom:1px solid var(--line)}
.qa summary{
  list-style:none; cursor:pointer; display:flex; align-items:center; gap:16px;
  padding:19px 4px; min-height:44px;
  font-size:1.01rem; font-weight:500; color:var(--text);
}
.qa summary::-webkit-details-marker{display:none}
@media (hover:hover){ .qa summary:hover{color:var(--accent)} }
.qa summary:focus-visible{outline:2px solid var(--accent); outline-offset:-2px; border-radius:var(--r-sm)}
.qa .plus,.fold .plus{
  margin-left:auto; flex:none; width:15px; height:15px; position:relative;
  transition:transform .32s var(--ease);
}
.qa .plus::before,.qa .plus::after,.fold .plus::before,.fold .plus::after{
  content:""; position:absolute; background:var(--accent); border-radius:2px;
}
.qa .plus::before,.fold .plus::before{left:0; right:0; top:6.5px; height:2px}
.qa .plus::after,.fold .plus::after{top:0; bottom:0; left:6.5px; width:2px; transition:opacity .32s var(--ease), transform .32s var(--ease)}
.qa[open] .plus::after,.fold[open] .plus::after{opacity:0; transform:rotate(90deg)}
.qa .ans{padding:0 4px 22px; color:var(--muted); font-size:var(--fs-md); line-height:1.68; max-width:66ch}
.qa .ans p{margin:0 0 12px}
.qa .ans p:last-child{margin:0}
.qa .ans a{color:var(--accent); border-bottom:1px solid color-mix(in srgb,var(--accent) 30%,transparent)}

/* ============================================================
   FOLD  (collapsed long lists; content stays in the DOM so crawlers
   and the Markdown route still see every row)
   ============================================================ */
.fold{border-top:1px solid var(--line)}
.fold>summary{
  list-style:none; cursor:pointer; display:flex; align-items:center; gap:18px;
  padding:20px 4px; min-height:44px;
  color:var(--muted); font-size:var(--fs-md); line-height:1.55;
  transition:color .2s var(--ease);
}
.fold>summary::-webkit-details-marker{display:none}
.fold .fold-txt{max-width:64ch}
@media (hover:hover){ .fold>summary:hover{color:var(--text)} }
.fold>summary:focus-visible{outline:2px solid var(--accent); outline-offset:-2px; border-radius:var(--r-sm)}
.fold[open]>summary{color:var(--text); border-bottom:1px solid var(--line)}
.fold .awards,.fold .press{padding-top:2px}
.fold .awards .aw:last-child{border-bottom:none}
@media(max-width:560px){ .fold>summary{font-size:var(--fs-sm); gap:12px} }

/* ============================================================
   COMPANY TOOLTIPS
   The two green company names in the hero are real links first. On a
   pointer device they also type out what the place is and what I do
   there. Touch devices get none of it: a hover cannot be dismissed with
   a finger, so the tap stays a plain navigation.

   The bubble text is injected from data-tip rather than living in the
   markup, so it never reaches the Markdown route and is never read
   twice by a screen reader.
   ============================================================ */
.role a.co{
  color:var(--accent); font-weight:600; text-decoration:none;
  border-bottom:1px solid color-mix(in srgb,var(--accent) 30%,transparent);
  transition:border-color .2s var(--ease);
}
@media (hover:hover){ .role a.co:hover{border-bottom-color:var(--accent)} }
.role a.co:focus-visible{outline:2px solid var(--accent); outline-offset:3px; border-radius:2px}

/* Skip link: off-screen until keyboard focus lands on it */
.skip{position:absolute; top:12px; left:12px; z-index:80; padding:10px 16px; min-height:44px;
  display:inline-flex; align-items:center; border-radius:999px;
  background:var(--accent); color:var(--bg); font-weight:600; font-size:var(--fs-sm);
  transform:translateY(-200%); transition:transform .2s var(--ease)}
.skip:focus-visible{transform:none}

.sr-only{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

/* Company bubbles. A mouse opens them on hover or keyboard focus; touch opens
   them on the first tap, and the second tap follows the link (site.js). */
/* The two company names sit on consecutive lines, so a bubble hung under the
   hovered word covers the other one. Anchor to the whole role block instead
   and slide it horizontally under the word it belongs to. left:0 is the
   default because an absolute box with no offset takes its static position,
   which pushed past the viewport before first hover. */
.role{position:relative}
.tip{
  display:block; position:absolute; left:0; top:calc(100% + 12px); z-index:45;   /* above the phone action bar */
  width:max-content; max-width:min(330px, 74vw);
  padding:13px 15px; border-radius:var(--r-md);
  background:var(--raised); border:1px solid var(--line-strong);
  box-shadow:0 18px 42px rgba(0,0,0,.55);
  font-family:var(--mono); font-size:var(--fs-label); line-height:1.65; color:var(--text);
  opacity:0; transform:translateY(-5px); pointer-events:none;
  transition:opacity .18s var(--ease), transform .18s var(--ease);
}
.tip::before{
  content:""; position:absolute; left:var(--tail,22px); margin-left:-4px; top:-5px; width:9px; height:9px;
  background:var(--raised);
  border-left:1px solid var(--line-strong); border-top:1px solid var(--line-strong);
  transform:rotate(45deg);
}
.tip.on{opacity:1; transform:translateY(0)}
/* Flipped above the link when there is no room below (site.js sets .up) */
.tip.up{top:auto; bottom:calc(100% + 12px); transform:translateY(5px)}
.tip.up.on{transform:translateY(0)}
.tip.up::before{top:auto; bottom:-5px; transform:rotate(225deg)}
/* the ghost reserves the final box so typing fills it instead of resizing it */
.tip-ghost{visibility:hidden; display:block}
.tip-live{position:absolute; left:15px; right:15px; top:13px}
.tip-caret{
  display:inline-block; width:7px; height:1.02em; margin-left:2px;
  background:var(--accent); vertical-align:-2px;
  animation:tipblink 1s steps(1) infinite;
}
@keyframes tipblink{0%,50%{opacity:1}51%,100%{opacity:0}}
@media (prefers-reduced-motion:reduce){
  .tip{transition:none}
  .tip-caret{animation:none}
}


/* Under-construction note */
.wip{
  display:flex; align-items:flex-start; gap:13px; flex-wrap:wrap;
  padding:15px 18px; margin-top:26px;
  border:1px dashed color-mix(in srgb,var(--accent) 30%,transparent); border-radius:var(--r-md);
  background:color-mix(in srgb,var(--accent) 3.5%,transparent); font-size:var(--fs-sm); color:var(--muted); max-width:60ch;
}
.wip b{font-family:var(--mono); font-size:var(--fs-label); letter-spacing:var(--track-mono); color:var(--accent);
  border:1px solid color-mix(in srgb,var(--accent) 35%,transparent); padding:4px 9px; border-radius:999px; flex:none}


/* ============================================================
   NAV + MENU
   ============================================================ */
.navwrap{display:flex; align-items:center; gap:14px}
.menu-btn{
  display:inline-flex; align-items:center; gap:10px; min-height:44px; padding:0 15px;
  background:var(--surface); border:1px solid var(--line-strong); border-radius:999px;
  color:var(--text); font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); font-weight:500;
  cursor:pointer; transition:background .22s var(--ease), border-color .22s var(--ease), transform .12s var(--ease);
}
@media (hover:hover){ .menu-btn:hover{background:var(--raised); border-color:color-mix(in srgb,var(--accent) 40%,transparent)} }
.menu-btn:active{transform:scale(.96)}
.bars{width:15px; height:11px; position:relative; flex:none}
.bars i{position:absolute; left:0; right:0; height:2px; background:var(--accent); border-radius:2px;
  transition:transform .3s var(--ease), opacity .2s var(--ease)}
.bars i:nth-child(1){top:0} .bars i:nth-child(2){top:4.5px} .bars i:nth-child(3){top:9px}
body.menu-open .bars i:nth-child(1){transform:translateY(4.5px) rotate(45deg)}
body.menu-open .bars i:nth-child(2){opacity:0}
body.menu-open .bars i:nth-child(3){transform:translateY(-4.5px) rotate(-45deg)}

.menu{
  position:fixed; inset:0; z-index:60; background:color-mix(in srgb,var(--bg) 97%,transparent);
  backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
  display:flex; flex-direction:column; justify-content:center;
  padding:var(--pad); opacity:0; visibility:hidden;
  transition:opacity .3s var(--ease), visibility 0s .3s;
}
/* Visibility flips instantly on open (the delay above only holds it for the
   fade-out), so site.js can move focus into the menu on the same tick. */
body.menu-open .menu{opacity:1; visibility:visible; transition:opacity .3s var(--ease), visibility 0s}
.menu-inner{max-width:940px; margin:0 auto; width:100%}

/* Explicit exit. The toggle button sits under the overlay (z-index 60 vs the
   page's 1), so its bars-to-X animation was never visible and there was no
   obvious way out. */
.menu-close{
  position:absolute; top:max(22px, env(safe-area-inset-top)); right:max(var(--pad), env(safe-area-inset-right));
  display:inline-flex; align-items:center; gap:10px;
  min-height:44px; padding:0 16px; border-radius:999px;
  background:var(--surface); border:1px solid var(--line-strong); color:var(--text);
  font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); font-weight:500; cursor:pointer;   /* same label face as Menu */
  transition:background .22s var(--ease), border-color .22s var(--ease), transform .12s var(--ease);
}
@media (hover:hover){ .menu-close:hover{background:var(--raised); border-color:color-mix(in srgb,var(--accent) 45%,transparent); color:var(--accent)} }
.menu-close:active{transform:scale(.96)}
.menu-close svg{width:13px; height:13px}
.menu a{
  display:flex; align-items:baseline; gap:18px; padding:14px 0;
  border-bottom:1px solid var(--line);
  font-family:var(--display); font-size:var(--fs-statement); font-weight:600;
  letter-spacing:var(--track-statement); color:var(--text);
  transform:translateY(14px); opacity:0;
  transition:color .22s var(--ease), transform .5s var(--ease), opacity .5s var(--ease);
}
body.menu-open .menu a{transform:none; opacity:1}
@media (hover:hover){ .menu a:hover{color:var(--accent)} }
.menu a[aria-current="page"]{color:var(--accent)}
.menu a[aria-current="page"] span{color:var(--accent)}
.menu a[aria-current="page"]::after{content:"CURRENT"; margin-left:auto; font-family:var(--mono); font-size:var(--fs-label); letter-spacing:var(--track-mono); color:var(--muted); align-self:center}
.menu a span{font-family:var(--mono); font-size:var(--fs-label); letter-spacing:var(--track-mono); color:var(--muted); flex:none; width:34px}
@media (hover:hover){ .menu a:hover span{color:var(--accent)} }
.menu-foot{margin-top:30px; font-family:var(--sans); font-size:var(--fs-label); color:var(--muted); letter-spacing:var(--track-label); font-weight:500}
.menu-foot a{display:inline; border:0; padding:0; font-family:var(--mono); font-size:var(--fs-label);
  font-weight:400; letter-spacing:var(--track-mono); transform:none; opacity:1; color:var(--accent)}

/* "Read more" bridge from the link hub to the about page */
.bridge{
  display:flex; align-items:center; gap:18px; flex-wrap:wrap;
  padding:var(--card-pad); border:1px solid var(--line); border-radius:var(--r-lg);
  background:var(--surface); cursor:pointer;
  transition:border-color .3s var(--ease), background .3s var(--ease), transform .3s var(--ease);
}
@media (hover:hover){ .bridge:hover{border-color:color-mix(in srgb,var(--accent) 42%,transparent); background:var(--raised); transform:translateY(-3px)} }
.bridge:active{transform:translateY(-1px) scale(.995)}
.br-body{flex:1; min-width:240px}
.br-title{font-family:var(--display); font-size:var(--fs-title-lg); font-weight:600;
  letter-spacing:var(--track-title); margin:0 0 6px}
.br-desc{color:var(--muted); font-size:var(--fs-md); margin:0; line-height:1.55}
.br-go{flex:none; width:22px; height:22px; color:var(--accent); transition:transform .3s var(--ease)}
@media (hover:hover){ .bridge:hover .br-go{transform:translateX(4px)} }

@media(prefers-reduced-motion:reduce){
  .menu a{transform:none !important; opacity:1 !important}
}

/* Micro-label floor. These mono labels rendered between 9.9px and 11.5px, under
   the 12px minimum for label text, and the previous rule only applied below
   560px so tablet and desktop never got it. 0.75rem = 12px at every width.
   New small labels join this list: the brief dialog, badges and menu captions
   all slipped under 12px by being added after it. */
.f-kind,.c-tag,.v-tag,.sec-num,.aw-rank,.pf-tag,
.f-src,.i-outlet,.aw-org,.v-meta,.status,.menu-status,.menu-foot,.menu-foot a,
.sec-note,.r-val,.r-num,.f-bot,.f-bot a,.i-year,.aw-year,.eyebrow,
.menu a[aria-current="page"]::after,
.menu a span,.wip b{
  font-size:var(--fs-label);
}
/* 4px of padding left this at 27px tall, under the 44px floor, on the one
   contact link inside the menu. Same trick as .f-cta a: pad to the target and
   pull the margin back so the line sits where it did. */
@media(max-width:560px){ .menu-foot a{display:inline-block; padding:13px 0; margin:-13px 0} }


/* ============================================================
   TRACK RECORD: the career spine. Roles and what was shipped in each,
   deliberately excluding awards and press so it does not restate them.
   ============================================================ */
.track{border-top:1px solid var(--line)}
.tr{display:flex; align-items:baseline; gap:20px; padding:18px 4px;
    border-bottom:1px solid var(--line); flex-wrap:wrap}
.tr-when{font-family:var(--mono); font-size:var(--fs-label); color:var(--accent);
    font-variant-numeric:tabular-nums; flex:none; width:96px; letter-spacing:var(--track-mono)}
.tr-body{flex:1; min-width:230px}
.tr-role{font-size:1.02rem; font-weight:500; margin:0 0 4px; color:var(--text)}
.tr-role b{color:var(--muted); font-weight:400}
.tr-did{font-size:var(--fs-sm); color:var(--muted); margin:0; line-height:1.55; max-width:62ch}
.tr-now{font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label); color:var(--accent);
    border:1px solid color-mix(in srgb,var(--accent) 35%,transparent); padding:3px 8px; border-radius:999px; flex:none; align-self:center; font-weight:500}
@media(max-width:560px){ .tr-when{width:100%} }

/* ============================================================
   BRIEF DIALOG
   The gate in front of the calendar. Native <dialog> so the modal
   semantics, focus trap, Esc-to-close and inert background come from the
   platform rather than from us.
   ============================================================ */
.brief{
  border:1px solid var(--line-strong); border-radius:var(--r-lg);
  background:var(--surface); color:var(--text);
  padding:0; width:min(520px, calc(100vw - 32px)); max-height:min(88svh, 780px);
  overflow:auto; overscroll-behavior:contain;
}
.brief::backdrop{background:color-mix(in srgb,var(--bg) 72%,transparent); backdrop-filter:blur(4px)}
.brief-in{padding:clamp(20px,4vw,30px); display:flex; flex-direction:column; gap:18px}
.brief-head{display:flex; align-items:flex-start; justify-content:space-between; gap:16px}
.brief-title{font-family:var(--display); font-size:1.35rem; line-height:1.2; margin:0}
.brief-sub{font-size:var(--fs-sm); color:var(--muted); margin:8px 0 0; line-height:1.5}
.brief-x{background:none; border:none; color:var(--muted); cursor:pointer;
  padding:6px; margin:-6px -6px 0 0; border-radius:var(--r-sm); flex:none; line-height:0}
.brief-x svg{width:20px; height:20px}
@media (hover:hover){ .brief-x:hover{color:var(--text)} }

.brief-field{display:flex; flex-direction:column; gap:7px}
.brief-field label{font-family:var(--sans); font-size:var(--fs-sm); letter-spacing:var(--track-label); color:var(--accent); font-weight:500}
.brief-field input,.brief-field select,.brief-field textarea{
  width:100%; min-height:46px; padding:11px 13px;
  background:var(--bg); color:var(--text);
  border:1px solid var(--line-strong); border-radius:var(--r-sm);
  font-family:var(--sans); font-size:16px; line-height:1.4;
}
.brief-field textarea{min-height:88px; resize:vertical}
.brief-field select{appearance:none; cursor:pointer; padding-right:38px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' stroke='%23d1ff4c' stroke-width='1.5' fill='none' stroke-linecap='round'/></svg>");
  background-repeat:no-repeat; background-position:right 13px center}
.brief-field input:focus-visible,.brief-field select:focus-visible,.brief-field textarea:focus-visible{
  outline:2px solid var(--accent); outline-offset:2px; border-color:transparent}
.brief-opt{color:var(--muted); text-transform:none; letter-spacing:0; font-size:var(--fs-label); font-weight:400}

.brief-send{
  display:flex; align-items:center; justify-content:center; gap:10px;
  width:100%; min-height:50px; border:none; border-radius:999px;
  background:var(--accent); color:var(--on-accent); cursor:pointer;
  font-family:var(--sans); font-size:var(--fs-md); font-weight:600;
  transition:background .22s var(--ease), transform .12s var(--ease);
}
@media (hover:hover){ .brief-send:hover:not(:disabled){background:var(--accent-hover)} }
.brief-send:active:not(:disabled){transform:scale(.98)}
.brief-send:disabled{opacity:.55; cursor:progress}
.brief-err{color:var(--danger); font-size:var(--fs-sm); margin:0; line-height:1.5}
.brief-note{font-family:var(--sans); font-size:var(--fs-label); letter-spacing:var(--track-label);
  color:var(--muted); margin:0; text-align:center; font-weight:500}

/* Success state: swapped in once the brief is saved. Relies on the global
   [hidden] rule above; this display:flex would otherwise override it. */
.brief-done{display:flex; flex-direction:column; gap:16px; text-align:center; align-items:center}
.brief-tick{width:52px; height:52px; border-radius:999px; display:grid; place-items:center;
  background:color-mix(in srgb,var(--accent) 14%,transparent); border:1px solid color-mix(in srgb,var(--accent) 40%,transparent); color:var(--accent)}
.brief-tick svg{width:26px; height:26px}

@media(max-width:480px){
  .brief{width:100vw; max-width:100vw; max-height:92svh; border-radius:var(--r-lg) var(--r-lg) 0 0;
    margin:auto auto 0; }
}

/* Polish */
::selection{background:var(--accent); color:var(--on-accent)}
h1,.f-cta,.v-name,.i-title{text-wrap:balance}
.qa summary,.aw-name,.tr-did{text-wrap:pretty}
#yr{font-variant-numeric:tabular-nums}
html{scroll-behavior:smooth; scrollbar-color:var(--scrollbar) var(--bg)}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important}
  .js .rv{opacity:1 !important; transform:none !important}
  .js h1.rv .ln > i{transform:none !important}
  .dot{animation:none}
  html{scroll-behavior:auto}
}


/* ============================================================
   POSTER HERO
   The face is how someone who just met Braeden recognises him, so on phones
   the portrait leads, full bleed, with the name set across its lower edge.
   Desktop keeps the two columns: name and copy left, portrait right.
   ============================================================ */
.hero-grid{grid-template-areas:"poster" "copy"}
.hero-grid > h1{grid-area:poster; align-self:end; position:relative; z-index:2; margin:0}
.hero-grid > .portrait{grid-area:poster}
.hero-copy{grid-area:copy}

@media(max-width:819px){
  /* Homepage only: the poster sits right under the top bar. The about page's
     text hero keeps its normal padding. */
  .home .topbar{margin-bottom:2px}   /* 12px padding + 2px = the poster's 14px */
  .home .hero{padding-top:0}
  .hero-grid{gap:22px}
  .hero-grid > .portrait{
    /* Out to the screen edge by exactly the .wrap padding. 50vw would count the
       scrollbar and overflow wherever one is visible. */
    margin-left:calc(-1 * max(var(--pad), env(safe-area-inset-left)));
    margin-right:calc(-1 * max(var(--pad), env(safe-area-inset-right)));
    max-width:none; border-radius:0; box-shadow:none;
    height:min(125vw, 60svh);   /* short phones: leave the role lines above the bar */
  }
  .hero-grid > .portrait img{height:100%; aspect-ratio:auto; object-position:50% 18%}
  .hero-grid > .portrait .p-alt{background-position:50% 18%}
  /* Fade the photo itself at the top, so the page's lime bloom shows through
     instead of a hard edge under the top bar. */
  .hero-grid > .portrait{-webkit-mask-image:linear-gradient(180deg,transparent 0,var(--bg) 20%);
    mask-image:linear-gradient(180deg,transparent 0,var(--bg) 20%)}
  /* Melt into the page so the name reads on the photo, not on a box */
  .hero-grid > .portrait::after{background:linear-gradient(180deg,transparent 42%,
    color-mix(in srgb,var(--bg) 72%,transparent) 76%,var(--bg) 100%)}
  .hero-grid > h1{font-size:clamp(min(3.1rem,20vw),21vw,6.4rem); margin-bottom:-.08em}
}
@media(min-width:820px){
  .hero-grid{grid-template-areas:"name poster" "copy poster"; grid-template-rows:auto 1fr; row-gap:24px}
  .hero-grid > h1{grid-area:name}
  .hero-copy{align-self:start}
}

/* The slogan: lime, but never mistakable for the lime links above it. It is
   italic, carries no underline, and the colour moves: a slow shine runs through
   the accent and a cooler turn of it, derived from --accent so the palette gains
   nothing new. Browsers without relative colour or text clipping get plain lime. */
.tagline{margin:2px 0 16px; font-family:var(--sans); font-style:italic; font-weight:500;
  font-size:clamp(1rem,2.2vw,1.12rem); letter-spacing:-.005em; color:var(--accent)}
@supports (color:oklch(from red l c h)) and ((-webkit-background-clip:text) or (background-clip:text)){
  .tagline{
    display:inline-block;   /* shrink the gradient to the words, not the column */
    background-image:linear-gradient(100deg,
      var(--accent) 0%,
      oklch(from var(--accent) l c calc(h + 42)) 22%,
      color-mix(in oklch,var(--accent) 55%,var(--text-strong)) 38%,
      var(--accent) 52%,
      oklch(from var(--accent) l c calc(h + 42)) 74%,
      var(--accent) 100%);
    background-size:220% 100%;
    -webkit-background-clip:text; background-clip:text;
    -webkit-text-fill-color:transparent; color:transparent;
    animation:tagline-shine 9s ease-in-out infinite alternate;
  }
  /* Drop shadow: a blurred copy of the same gradient on the same clock, set
     just below the words, so the shadow takes whichever colour is passing. A
     text-shadow cannot do this: it paints over clipped text in one colour. */
  .tagline{position:relative; isolation:isolate}
  .tagline::before{
    content:attr(data-text); position:absolute; inset:0; z-index:-1;
    background:inherit; background-size:220% 100%;
    -webkit-background-clip:text; background-clip:text;
    -webkit-text-fill-color:transparent; color:transparent;
    transform:translateY(2px); filter:blur(2.5px); opacity:.32; pointer-events:none;
    animation:inherit;
  }
}
@keyframes tagline-shine{from{background-position:0% 50%} to{background-position:100% 50%}}
/* Reduced motion: the global rule already stops it; hold a lime-forward frame */
@media(prefers-reduced-motion:reduce){ .tagline,.tagline::before{animation:none; background-position:0% 50%} }

/* Individual recognition, not agency awards: the claims are Braeden's own. */
.proof{display:flex; flex-direction:column; gap:3px; margin:0 0 16px; font-size:var(--fs-sm); color:var(--text); font-weight:500}   /* the evidence reads at the level of the roles */
.proof span{position:relative; padding-left:17px}
.proof span::before{content:""; position:absolute; left:0; top:.72em; width:9px; height:2px; background:var(--accent)}

.hero-logos{margin-top:clamp(44px,7vw,68px); padding-top:26px; border-top:1px solid var(--line)}
.hl-cap{margin:0 0 20px; text-align:center; font-size:var(--fs-label); color:var(--muted); font-weight:500}

/* Phone action bar. Replaces the hero chips below 560px so the three actions
   exist once on screen, and always within thumb reach. */
.actbar{display:none}
@media(max-width:560px){
  .hero .chips{display:none}
  .actbar{
    position:fixed; left:0; right:0; bottom:0; z-index:40; display:flex; gap:8px;
    padding:10px max(16px, env(safe-area-inset-right)) calc(10px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
    background:color-mix(in srgb,var(--bg) 88%,transparent);
    backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
    border-top:1px solid var(--line);
  }
  body{padding-bottom:calc(70px + env(safe-area-inset-bottom))}
  /* Content fades into the bar instead of being sliced through a line of text */
  .actbar::before{content:""; position:absolute; left:0; right:0; bottom:100%; height:28px; pointer-events:none;
    background:linear-gradient(to bottom, transparent, var(--bg))}
}
.ab-book{flex:1; display:inline-flex; align-items:center; justify-content:center; gap:9px; min-height:48px;
  border-radius:999px; background:var(--accent); color:var(--on-accent); font-weight:600; font-size:var(--fs-md);
  transition:background .22s var(--ease), transform .12s var(--ease)}
@media (hover:hover){ .ab-book:hover{background:var(--accent-hover)} }
.ab-book:active,.ab-icon:active{transform:scale(.96)}
.ab-icon{flex:none; width:48px; height:48px; display:grid; place-items:center; border-radius:999px;
  background:var(--surface); border:1px solid var(--line-strong); color:var(--text);
  transition:transform .12s var(--ease)}
.ab-book svg,.ab-icon svg{width:18px; height:18px; flex:none}

/* Optional brief fields, folded */
.brief-more summary{display:flex; align-items:center; gap:10px; min-height:44px; cursor:pointer; list-style:none;
  font-size:var(--fs-sm); font-weight:500; color:var(--text); border-radius:var(--r-sm)}
.brief-more summary::-webkit-details-marker{display:none}
.brief-more summary::before{content:""; width:7px; height:7px; flex:none; margin:0 2px 0 3px;
  border-right:1.5px solid var(--accent); border-bottom:1.5px solid var(--accent);
  transform:rotate(-45deg); transition:transform .2s var(--ease)}
.brief-more[open] summary::before{transform:rotate(45deg)}
.brief-more summary:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
.brief-more-in{display:flex; flex-direction:column; gap:16px; padding-top:10px}

/* Private hero card (injected by _middleware.js with the token). Hidden on
   phones, where the action bar carries the same actions. While it is present,
   Book a call steps down so one lime button leads: Save my contact. */
.pcard{padding:var(--card-pad); border-radius:var(--r-md);
  border:1px solid color-mix(in srgb,var(--accent) 30%,transparent);
  background:color-mix(in srgb,var(--accent) 5%,transparent)}
.pc-head{display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:0 0 14px; font-size:var(--fs-sm); color:var(--muted)}
.pcard ~ .chips{display:none}   /* the private card carries Save, WhatsApp and Book as one row */
.pc-head a{color:var(--text); border-bottom:1px solid var(--line-strong)}
@media(max-width:560px){
  /* Phones: the bar carries the actions; the card's head line stays as a label,
     moved up under the slogan so the first screen says this link is private. */
  .pcard{padding:0; border:0; background:none; border-radius:0}
  .pcard .chips{display:none}
  .pc-head{margin:0}
  .hero-copy{display:flex; flex-direction:column; align-items:flex-start}
  .hero-copy > *{order:3}
  .hero-copy > .role{order:0}
  .hero-copy > .tagline{order:1}
  .hero-copy > .pcard{order:2}
}
/* Phones: a Private link tag in the header, where the status pill sits on
   desktop, so the first screen always says it (injected with the token). */
.tb-private{display:none}
@media(max-width:560px){ .tb-private{display:inline-flex; align-items:center} }
/* Desktop card: one row of three. Secondary chips drop their icons and some padding. */
.pcard .chips{gap:8px}
.pcard .chip{padding:0 14px}
.pcard .chip:not(.primary) svg{display:none}

/* Touch press feedback. Hover styles only apply where hover exists, so a tap
   no longer leaves a row or card stuck lit; instead the fill shows while the
   finger is down. site.js registers a touchstart listener so iOS applies
   :active at all. */
@media (hover:none){
  .row:active::before{transform:scaleX(1); transition-duration:.14s}
  .row:active .r-num,.row:active .r-icon,.row:active .r-label,.row:active .r-val,.row:active .r-go{color:var(--bg)}
  .feat:active,.venture:active,.item:active,.bridge:active{
    border-color:color-mix(in srgb,var(--accent) 42%,transparent); background:var(--raised)}
  .chip:active{background:var(--raised)}
  .chip.primary:active,.ab-book:active{background:var(--accent-hover)}
  .ab-icon:active,.menu-btn:active{background:var(--raised)}
  .menu a:active,.menu a:active span,.f-cta a:active,.f-bot a:active{color:var(--accent)}
  .row,.feat,.venture,.item,.bridge,.chip,.ab-book,.ab-icon,.menu a{-webkit-tap-highlight-color:transparent}
}

/* Hero copy rhythm, judged by the space you see between the letters: about
   12px inside a pair (roles + slogan, bio + places) and 23px between groups
   (titles, proof, story, actions). The margins below are those targets minus
   the empty leading each item carries, measured from rendered pixels. */
.hero-copy{--g-role:6px; --g-tag:13px; --g-proof:15px; --g-bio:5px; --g-places:20px}
@media(max-width:560px){ .hero-copy{--g-role:8px; --g-tag:12px; --g-proof:12px} }   /* proof wraps to three lines here */
/* --g-tag is 3px under the group step on purpose: the slogan's glow and italic
   carry weight below the letters, so its gap measures 20 to look like 23. */
.hero-copy > .role{margin-bottom:var(--g-role); line-height:1.5}
.hero-copy > .tagline{margin:0 0 var(--g-tag); line-height:1.35}
.hero-copy > .proof{margin-bottom:var(--g-proof); line-height:1.5}
.hero-copy > .bio{margin-bottom:var(--g-bio); line-height:1.5}
.hero-copy > .places,.hero-copy > .pcard{margin-bottom:var(--g-places)}

/* Phones: size the poster to the screen so the first screen ends on the slogan,
   just above the action bar: face, name, roles, "Rewriting advertising", then
   the proof starts below the fold instead of a line being sliced by it.
   The 270px is everything under the poster (header, roles, slogan, bar and
   18px of air), measured on six phones at 268-271px; narrow phones wrap the
   second role line and need 293px. svh assumes the browser toolbar is showing,
   so the fold never lands behind it. */
@media(max-width:560px){
  .hero-grid > .portrait{height:max(260px, calc(100vh - 270px)); height:max(260px, calc(100svh - 270px))}
}
@media(max-width:359px){
  .hero-grid > .portrait{height:max(260px, calc(100vh - 293px)); height:max(260px, calc(100svh - 293px))}
}
